Next.js with localization - deployment on subpath with ingress config

Viewed 492

What I'd like to achieve

I want my next.js app to be deployed and hosted on my domain like this - https://example.com/myapp

I also want it to support localization, so that when the user enters the page with detected locale, the app will do a redirect such as this - https://example.com/myapp/en-US

What's the problem

The current behavior is that when the user enters the page with default locale, the app loads correctly. However, if the user has a different locale set as his preferred one, instead of being redirected to https://example.com/myapp/en-US, the app does a redirect to https://example.com/en-US. I should also mention that when I enter https://example.com/myapp/en-US manually, the correct locale is loaded and everything works as intended.

What's my current configuration

Here's my next.config.js file:

const isProd = process.env.NODE_ENV === 'production';

module.exports = {
  // Use the CDN in production and localhost for development.
  assetPrefix: isProd ? '/myapp/' : '',
  async rewrites() {
    if (!isProd) {
      return [];
    }

    return [{ source: '/myapp/_next/:path*', destination: '/_next/:path*' }];
  },
  images: {
    path: isProd ? '/myapp/_next/image' : '/_next/image',
  },
  i18n: {
    locales: ['pl', 'en-US'],
    defaultLocale: 'pl',
  },
  webpack: (config) => {
    config.module.rules.push({
      test: /\.(graphql|gql)$/,
      exclude: /node_modules/,
      loader: 'graphql-tag/loader',
    });
    return config;
  },
  webpackDevMiddleware: (config) => {
    return config;
  },
};

And here's the relevant part of my ingress configuration:

kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  name: example-ingress
  namespace: default
  annotations:
    ingress.kubernetes.io/ssl-redirect: 'false'
    kubernetes.io/ingress.class: nginx
    kubernetes.io/ingress.global-static-ip-name: web-static-ip
    kubernetes.io/tls-acme: 'true'
    nginx.ingress.kubernetes.io/configuration-snippet: |
      add_header X-Frame-Options "SAMEORIGIN";
      add_header Content-Security-Policy "frame-ancestors 'none'";
    nginx.ingress.kubernetes.io/limit-connections: ‘10’
    nginx.ingress.kubernetes.io/limit-rpm: ‘60’
    nginx.ingress.kubernetes.io/proxy-body-size: 100m
    nginx.ingress.kubernetes.io/rewrite-target: /$1

spec:
  tls:
    - hosts:
        - example.com
      secretName: my-example-secret
  rules:
    - host: example.com
      http:
        paths:
          - path: /myapp
            pathType: ImplementationSpecific
            backend:
              serviceName: my-app-svc
              servicePort: 3000
          - path: /myapp/(.*)
            pathType: ImplementationSpecific
            backend:
              serviceName: my-app-svc
              servicePort: 3000
          - path: /otherapp/(.*)
            pathType: ImplementationSpecific
            backend:
              serviceName: my-other-app-svc
              servicePort: 8080
          - path: /(.*)
            pathType: ImplementationSpecific
            backend:
              serviceName: yet-another-app-svc
              servicePort: 80

Explanation

The reason I'm using the assetPrefix, rewrites() and images config, instead of using the available basePath configuration nextjs provides, is because when I tried to set it to /myapp, my application was available under https://example.com/myapp/myapp

Many thanks in advance for any suggestions

0 Answers
Related