Skip to content

Commit

Permalink
feat: Add localePrefix: 'never' option for middleware (#388 by @bor…
Browse files Browse the repository at this point in the history
…is-arkenaar)

fixes #366

---------

Co-authored-by: Jan Amann <[email protected]>
  • Loading branch information
boris-arkenaar and amannn authored Jul 18, 2023
1 parent 023d23a commit 92ec33a
Show file tree
Hide file tree
Showing 4 changed files with 260 additions and 41 deletions.
34 changes: 29 additions & 5 deletions docs/pages/docs/routing/middleware.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -138,14 +138,37 @@ import createMiddleware from 'next-intl/middleware';
export default createMiddleware({
// ... other config

localePrefix: 'always' // Defaults to 'as-needed'
localePrefix: 'always'
});
```

In this case, requests without a prefix will be redirected accordingly (e.g. `/about` to `/en/about`).

Note that this will affect both prefix-based as well as domain-based routing.

### Never use a locale prefix

For applications behind an authentication layer, where there is no need for SEO, it is possible to have the locale never show up in the URL.

```tsx filename="middleware.ts" {6}
import createMiddleware from 'next-intl/middleware';

export default createMiddleware({
// ... other config

localePrefix: 'never'
});
```

In this case all requests for all locales will be rewritten to have the locale
prefixed internally. You still need to place all your pages inside a
`[locale]` folder for the routes to be able to receive the `locale` param.

<Callout>
Note that [alternate links](#disable-alternate-links) are disabled in this
mode since there are no distinct URLs per language.
</Callout>

### Disable automatic locale detection

If you want to rely entirely on the URL to resolve the locale, you can disable locale detection based on the `accept-language` header and a potentially existing cookie value from a previous visit.
Expand All @@ -156,11 +179,11 @@ import createMiddleware from 'next-intl/middleware';
export default createMiddleware({
// ... other config

localeDetection: false // Defaults to `true`
localeDetection: false
});
```

Note that in this case other detection mechanisms will remain in place regardless (e.g. based on a locale prefix in the pathname or a matched domain).
In this case, only the locale prefix and a potentially [matching domain](#domain-based-routing) are used to determine the locale.

### Disable alternate links

Expand Down Expand Up @@ -322,8 +345,9 @@ export default function RootPage() {

<Callout type="warning">
Note that this is currently limited to the usage of `next-intl` in [Client
Components](/docs/getting-started/app-router-client-components) (no [Server
Components](/docs/getting-started/app-router-server-components)).
Components](/docs/getting-started/app-router-client-components) ([Server
Components](/docs/getting-started/app-router-server-components) are not
supported).
</Callout>

You can explore a working demo by building [the Next.js 13 example](/examples/app-router) after enabling the static export:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
type LocalePrefix = 'as-needed' | 'always';
type LocalePrefix = 'as-needed' | 'always' | 'never';

type RoutingBaseConfig = {
/** A list of all locales that are supported. */
Expand Down
17 changes: 11 additions & 6 deletions packages/next-intl/src/middleware/middleware.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,9 @@ export default function createMiddleware(config: MiddlewareConfig) {
}

if (
hasMatchedDefaultLocale &&
configWithDefaults.localePrefix === 'as-needed'
configWithDefaults.localePrefix === 'never' ||
(hasMatchedDefaultLocale &&
configWithDefaults.localePrefix === 'as-needed')
) {
response = rewrite(pathWithSearch);
} else {
Expand All @@ -140,7 +141,9 @@ export default function createMiddleware(config: MiddlewareConfig) {
if (hasLocalePrefix) {
const basePath = pathWithSearch.replace(`/${pathLocale}`, '') || '/';

if (pathLocale === locale) {
if (configWithDefaults.localePrefix === 'never') {
response = redirect(basePath);
} else if (pathLocale === locale) {
if (
hasMatchedDefaultLocale &&
configWithDefaults.localePrefix === 'as-needed'
Expand Down Expand Up @@ -168,9 +171,10 @@ export default function createMiddleware(config: MiddlewareConfig) {
}
} else {
if (
hasMatchedDefaultLocale &&
(configWithDefaults.localePrefix === 'as-needed' ||
configWithDefaults.domains)
configWithDefaults.localePrefix === 'never' ||
(hasMatchedDefaultLocale &&
(configWithDefaults.localePrefix === 'as-needed' ||
configWithDefaults.domains))
) {
response = rewrite(`/${locale}${pathWithSearch}`);
} else {
Expand All @@ -186,6 +190,7 @@ export default function createMiddleware(config: MiddlewareConfig) {
}

if (
configWithDefaults.localePrefix !== 'never' &&
configWithDefaults.alternateLinks &&
configWithDefaults.locales.length > 1
) {
Expand Down
Loading

3 comments on commit 92ec33a

@vercel
Copy link

@vercel vercel bot commented on 92ec33a Jul 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

next-intl-example-next-13 – ./examples/example-next-13

next-intl-example-next-13-git-main-next-intl.vercel.app
next-intl-example-next-13.vercel.app
next-intl-example-next-13-next-intl.vercel.app

@vercel
Copy link

@vercel vercel bot commented on 92ec33a Jul 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

example-next-13-next-auth – ./examples/example-next-13-next-auth

example-next-13-next-auth-next-intl.vercel.app
example-next-13-next-auth-git-main-next-intl.vercel.app
example-next-13-next-auth.vercel.app

@vercel
Copy link

@vercel vercel bot commented on 92ec33a Jul 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

next-intl-docs – ./docs

next-intl-docs-next-intl.vercel.app
next-intl-docs.vercel.app
next-intl-docs-git-main-next-intl.vercel.app

Please sign in to comment.