Skip to content

Feature Request: Allow defining shared translated pathnames for regional locales (DRY) #1842

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

Open
archneon opened this issue Apr 15, 2025 · 2 comments
Labels
enhancement New feature or request unconfirmed Needs triage.

Comments

@archneon
Copy link

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

Description:

Currently, when using next-intl with regional locales (e.g., de-DE, de-AT, de-CH) that share the same base language (de) and consequently should often share the same translated pathnames, the pathnames configuration requires explicitly defining the identical translated path for each regional locale.

For example, with locales: ['en', 'de-DE', 'de-AT', 'fr'], the configuration might look like this:

import { defineRouting } from 'next-intl/routing';

export const routing = defineRouting({
  locales: ['en', 'de-DE', 'de-AT', 'fr'],
  defaultLocale: 'en',
  // Domains setup here...
  localePrefix: {
    mode: 'as-needed',
  },
  pathnames: {
    '/': '/',
    '/products': {
      'de-DE': '/produkte', // Repetition for German locales
      'de-AT': '/produkte', // Repetition for German locales
      'fr': '/produits',
      // 'en' uses the internal '/products' due to default locale & 'as-needed'
    },
    '/products/[productId]': {
      'de-DE': '/produkte/[productId]', // Repetition
      'de-AT': '/produkte/[productId]', // Repetition
      'fr': '/produits/[productId]',
    },
    '/contact': {
      'de-DE': '/kontakt', // Repetition
      'de-AT': '/kontakt', // Repetition
      'fr': '/contactez-nous',
    }
  }
});

This leads to repetition, especially when dealing with multiple regional variations (e.g., German in Germany, Austria, Switzerland) or other languages with similar regional needs. It violates the DRY (Don't Repeat Yourself) principle and makes the configuration harder to maintain.

This contrasts with the elegant solution for sharing message files (e.g., using de.json for both de-DE and de-AT) by leveraging new Intl.Locale(locale).language within getRequestConfig.

Describe the solution you'd like

Proposed Solution:

It would be highly beneficial to have a mechanism within the pathnames configuration to define a shared translated path for a group of regional locales or based on the base language. Possible syntax ideas could include:

  • Using an array of locales:
    '/products': {
      ['de-DE', 'de-AT']: '/produkte', // Define once for multiple German locales
      'fr': '/produits',
    }
  • Using the base language code (potentially ambiguous if base code is also in locales):
    '/products': {
      'de': '/produkte', // Apply to all 'de-*' locales unless explicitly overridden
      'fr': '/produits',
    }
  • A dedicated syntax/property:
    '/products': {
      // Apply '/produkte' to all 'de-*' locales
      basePaths: { 'de': '/produkte' },
      // Specific overrides if needed
      // 'de-CH': '/produkte-ch',
      'fr': '/produits',
    }

The goal is to allow developers to define the common translated pathname (/produkte, /kontakt) only once for all relevant German-speaking locales, while still allowing specific overrides if necessary for a particular region.

Benefits:

  • Improved Maintainability: Reduces redundancy and makes the pathnames configuration cleaner and easier to manage.
  • DRY Principle: Adheres better to the DRY principle.
  • Consistency: Aligns the developer experience for pathnames closer to the flexibility offered for message handling.

Use Case:

Websites targeting multiple countries that share a common language (e.g., Germany/Austria/Switzerland, France/Belgium, US/UK/Canada/Australia) would significantly benefit from this feature by avoiding repetitive pathname definitions.

Describe alternatives you've considered

I have considered duplicating all pathnames for de-AT and de-DE and other countries that speak German language.

@archneon archneon added enhancement New feature or request unconfirmed Needs triage. labels Apr 15, 2025
@amannn
Copy link
Owner

amannn commented Apr 15, 2025

Hey, thanks for the detailed feature request! I agree there might be a need for this, I'm currently not sure if it should be implemented within next-intl though.

You can realize this in userland with a function like this:

import {defineRouting} from 'next-intl/routing';

const locales = ['en', 'de', 'de-DE', 'de-AT'] as const;

function inheritPathnames(pathnames: Record<string, string>) {
  const result: Record<string, string> = {...pathnames};
  for (const locale of locales) {
    const baseLocale = locale.split('-')[0];
    if (baseLocale !== locale && pathnames[baseLocale]) {
      result[locale] = pathnames[baseLocale];
    }
  }
  return result;
}

export const routing = defineRouting({
  locales,
  defaultLocale: 'en',
  pathnames: {
    '/': '/',
    '/products': inheritPathnames({
      de: '/produkte'
    })
  }
});

@archneon
Copy link
Author

Alright, thank you amann, i think i have successfully implemented it with your instructions. It might be cool if this was built-in, but at least we have this option :-)

kind regards,
Arch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request unconfirmed Needs triage.
Projects
None yet
Development

No branches or pull requests

2 participants