Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewriting the prefixes #549

Closed
dellacagna opened this issue Oct 4, 2023 · 6 comments
Closed

Rewriting the prefixes #549

dellacagna opened this issue Oct 4, 2023 · 6 comments
Labels
enhancement New feature or request has-workaround

Comments

@dellacagna
Copy link

dellacagna commented Oct 4, 2023

Is your feature request related to a problem? Please describe.

I would like to modify the URL structure of the prefix from a format like /en-GB to /en/UK or /eng.

Describe the solution you'd like

In the middleware I would like to specify my alternate prefixes and map them to the locale, similar like how its done with the domain mapping e.g.

prefixes: [
    {
      prefix: 'en/uk',
      locale: 'en-GB'
    },
    {
      prefix: 'eng',
      locale: 'en-GB'
    }
  ]

Describe alternatives you've considered

I tried modifying the next.config.js like this:

const withNextIntl = require('next-intl/plugin')('./src/i18n.ts');

/** @type {import('next').NextConfig} */
const nextConfig = {
    async rewrites() {
        return {
            beforeFiles: [
                {
                    source: "/en/uk/:path*",
                    destination: "/en-GB/:path*",
                },
                {
                    source: "/eng/:path*",
                    destination: "/de-GB/:path*",
                },
            ]
        }
    },
}

module.exports = withNextIntl(nextConfig);

I also tried by adding the domain middleware:

import createMiddleware from 'next-intl/middleware';

export default createMiddleware({
    locales: ['de-DE', 'en-GB'],
    defaultLocale: '',
    domains: [
        {
            domain: 'example.com/en/uk',
            defaultLocale: 'en-GB',
        },
    ]

});

export const config = {
    // Skip all paths that should not be internationalized. This skips
    // certain folders and all pathnames with a dot (e.g. favicon.ico)
    matcher: ['/((?!api|_next|_vercel|.*\\..*).*)']
};
@dellacagna dellacagna added enhancement New feature or request unconfirmed Needs triage. labels Oct 4, 2023
@dellacagna
Copy link
Author

dellacagna commented Oct 6, 2023

I found a a work around, by changing from server components to client components and adding the following in my middleware to make the rewrite config work:

export function middleware(request: NextRequest) {
    return NextResponse.next();
}

So final solution for anyone who is interested:
src/middleware.ts:

import createMiddleware from 'next-intl/middleware';
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
    return NextResponse.next();
}

export default createMiddleware({
    locales: ['de-DE', 'en-GB'],
    defaultLocale: ''
});

export const config = {
    // Skip all paths that should not be internationalized.
    matcher: ['/((?!api|_next|_vercel|.*\\..*).*)']
};

next.config.js:

/** @type {import('next').NextConfig} */
const nextConfig = {
    async rewrites() {
        return  [
                {
                    source: '/de/de/:path*',
                    destination: '/de-DE/:path*',
                },
               
                {
                    source: '/en/uk/:path*',
                    destination: '/en-GB/:path*',
                },
             
            ]

    },
}

module.exports = nextConfig

Cant seem to get it to work with server components.

@dellacagna dellacagna reopened this Oct 6, 2023
@dellacagna
Copy link
Author

To make it work with server components I removed the rewrites from the next.config.js file and created them in the middleware like so:

import createIntlMiddleware from 'next-intl/middleware';
import { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
    const localeMapping = {
        'en/uk': 'en-GB',
        'de/de': 'de-DE',
    };
    let modifiedRequest = request;

    // URL Rewrites
    for (const [srcPath, targetPath] of Object.entries(localeMapping)) {
        if (request.nextUrl.pathname.startsWith(`/${srcPath}`)) {
            const remainingPath = request.nextUrl.pathname.replace(`/${srcPath}`, '');
            const newUrl = new URL(`/${targetPath}${remainingPath}`, request.url);
            modifiedRequest = new NextRequest(newUrl, request);
            break;
        }
    }

    const locales = Object.values(localeMapping);

    // Translations middleware logic
    const defaultLocale = modifiedRequest.headers.get('x-default-locale') || 'en-GB';
    const handleI18nRouting = createIntlMiddleware({
        locales,
        defaultLocale
    });

    const response = handleI18nRouting(modifiedRequest);
    response.headers.set('x-default-locale', defaultLocale);

    return response;
}

export const config = {
    // Skip all paths that should not be internationalized.
    matcher: ['/((?!api|_next|_vercel|.*\\..*).*)']
};

@amannn
Copy link
Owner

amannn commented Oct 9, 2023

Thank you for sharing your workaround! I made a note in #243 about this, the two issues seem to be related and I'm wondering if there could be a shared solution. basePath is really a simpler, static solution for what you're doing here. However, the navigation APIs will likely create incorrect links, you'd have to wrap them accordingly to work with your custom routing.

@amannn
Copy link
Owner

amannn commented Nov 22, 2023

I agree there's a piece missing here currently. I've opened #653 to collect this issue together with similar ones, also to share solutions that can be used today.

@amannn amannn added has-workaround and removed unconfirmed Needs triage. labels Nov 23, 2023
@amannn
Copy link
Owner

amannn commented Jan 23, 2024

@dellacagna I've updated #653 with a proposal that I think could support your use case. Let me know in the linked issue in case you have feedback or a better idea in mind!

@amannn
Copy link
Owner

amannn commented Mar 28, 2024

I'll close this now in favor of #653. This issue is mentioned there and will be taken care of.

@amannn amannn closed this as completed Mar 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request has-workaround
Projects
None yet
Development

No branches or pull requests

2 participants