Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into feat/next-13-rsc
Browse files Browse the repository at this point in the history
# Conflicts:
#	examples/example-next-13/next.config.js
#	examples/example-next-13/src/app/[locale]/layout.tsx
#	packages/next-intl/package.json
#	pnpm-lock.yaml
  • Loading branch information
amannn committed Jun 20, 2023
2 parents 335afcf + fab8e17 commit b219e13
Show file tree
Hide file tree
Showing 38 changed files with 853 additions and 244 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
- uses: actions/checkout@v3
- uses: pnpm/action-setup@v2
with:
version: 8.4.0
version: 8.6.0
- uses: actions/setup-node@v3
with:
node-version: 18.x
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
- uses: actions/checkout@v3
- uses: pnpm/action-setup@v2
with:
version: 8.4.0
version: 8.6.0
- uses: actions/setup-node@v3
with:
registry-url: 'https://registry.npmjs.org'
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

# 2.15.0 (2023-06-20)


### Features

* Add `format.list(…)` for formatting conjunctions and disjunctions ([#327](https://github.com/amannn/next-intl/issues/327) by [@stefanprobst](https://github.com/stefanprobst)) ([32cda32](https://github.com/amannn/next-intl/commit/32cda32f47112915bb2032f3f9cc02bf3a4e833b))





## 2.14.6 (2023-05-22)

**Note:** Version bump only for package root
Expand Down
4 changes: 4 additions & 0 deletions docs/components/CodeSnippets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,10 @@ function standards() {
.RelativeTimeFormat
</span>
</span>
<span className="line">
<span style={{color: 'var(--shiki-token-constant)'}}>Intl</span>
<span style={{color: 'var(--shiki-color-text)'}}>.ListFormat</span>
</span>
<span className="line"> </span>
<span className="line">
<span style={{color: 'var(--shiki-color-text)'}}>
Expand Down
3 changes: 0 additions & 3 deletions docs/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ const withNextra = require('nextra')({
});

module.exports = withNextra({
experimental: {
appDir: true
},
redirects: () => [
// Index pages
{
Expand Down
3 changes: 1 addition & 2 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@
},
"dependencies": {
"@heroicons/react": "^2.0.17",
"@next/font": "^13.1.6",
"@tailwindcss/typography": "^0.5.9",
"clsx": "^1.2.1",
"http-status-codes": "^2.2.0",
"next": "^13.4.0",
"next": "^13.4.6",
"nextra": "^2.4.2",
"nextra-theme-docs": "^2.4.2",
"react": "^18.2.0",
Expand Down
2 changes: 1 addition & 1 deletion docs/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Inter} from '@next/font/google';
import Analytics from 'components/Analytics';
import {AppProps} from 'next/app';
import {Inter} from 'next/font/google';
import {ReactNode} from 'react';
import 'nextra-theme-docs/style.css';
import '../styles.css';
Expand Down
39 changes: 36 additions & 3 deletions docs/pages/docs/next-13/middleware.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ export const config = {

There are two strategies for detecting the locale:

1. [Prefix-based routing (default)](#prefix-based-routing-default)
1. [Prefix-based routing (default)](#prefix-based-routing)
2. [Domain-based routing](#domain-based-routing)

Once a locale is detected, it will be saved in a cookie.

### Prefix-based routing (default)
### Prefix-based routing (default) [#prefix-based-routing]

Since your pages are nested within a `[locale]` folder, all routes are prefixed with one of your supported locales (e.g. `/de/about`). To keep the URL short, requests for the default locale are rewritten internally to work without a locale prefix.

Expand Down Expand Up @@ -112,7 +112,7 @@ The locale is detected based on these priorities:

<Callout>

Since unknown domains will be handled with [prefix-based routing](#prefix-based-routing-default), this strategy can be used for local development where the host is `localhost`.
Since unknown domains will be handled with [prefix-based routing](#prefix-based-routing), this strategy can be used for local development where the host is `localhost`.

</Callout>

Expand Down Expand Up @@ -302,3 +302,36 @@ There's a working [example that combines `next-intl` with Auth.js](https://githu
</Callout>

Many thanks to [narakhan](https://github.com/narakhan) for [sharing his middleware implementation](https://github.com/amannn/next-intl/pull/149#issuecomment-1509990635)!

## Usage without middleware (static export)

If you're using the [static export feature from Next.js](https://nextjs.org/docs/app/building-your-application/deploying/static-exports) (`output: 'export'`), the middleware will not run. You can use [prefix-based routing](#prefix-based-routing) nontheless to internationalize your app, but a few tradeoffs apply.

**Static export limitations:**

1. There's no default locale that can be used without a prefix (same as [`localePrefix: 'always'`](#always-use-a-locale-prefix))
2. The locale can't be negotiated at runtime (same as [`localeDetection: false`](#disable-automatic-locale-detection))
3. You need to add a redirect for the root of the app

```tsx filename="app/page.tsx"
import {redirect} from 'next/navigation';

// Redirect the user to the default locale when the app root is requested
export default function RootPage() {
redirect('/en');
}
```

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

You can explore a working demo by building [the Next.js 13 example](/examples/next-13) after enabling the static export:

```tsx filename="next.config.js"
module.exports = {
output: 'export'
};
```
1 change: 1 addition & 0 deletions docs/pages/docs/usage/_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"messages": "Messages",
"numbers": "Numbers",
"dates-times": "Dates and times",
"lists": "Lists",
"configuration": "Configuration",
"error-handling": "Error handling",
"typescript": "TypeScript",
Expand Down
11 changes: 9 additions & 2 deletions docs/pages/docs/usage/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ For consistent results in end-to-end tests, it can be helpful to mock this value

## Global formats

To achieve consistent date, time and number formatting across your app, you can define a set of global formats and pass them to the provider.
To achieve consistent date, time, number and list formatting across your app, you can define a set of global formats and pass them to the provider.

```js
<NextIntlProvider
Expand All @@ -61,6 +61,12 @@ To achieve consistent date, time and number formatting across your app, you can
precise: {
maximumFractionDigits: 5
}
},
list: {
enumeration: {
style: 'long',
type: 'conjunction'
}
}
}}
>
Expand All @@ -76,10 +82,11 @@ function Component() {

format.dateTime(new Date('2020-11-20T10:36:01.516Z'), 'short');
format.number(47.414329182, 'precise');
format.list(['HTML', 'CSS', 'JavaScript'], 'enumeration');
}
```

Global formats can be referenced in messages too.
Global formats for numbers, dates and times can be referenced in messages too.

```js filename="en.json"
{
Expand Down
5 changes: 4 additions & 1 deletion docs/pages/docs/usage/dates-times.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ function Component() {
const format = useFormatter();
const dateTime = new Date('2020-11-20T10:36:01.516Z');

// Renders "Nov 20, 2020"
format.dateTime(dateTime, {
year: 'numeric',
month: 'numeric',
month: 'short',
day: 'numeric'
});

// Renders "11:36 AM"
format.dateTime(dateTime, {hour: 'numeric', minute: 'numeric'});
}
```
Expand Down Expand Up @@ -91,6 +93,7 @@ function Component() {
const format = useFormatter();
const dateTime = new Date('2020-11-20T10:36:01.516Z');

// Renders e.g. "2 hours ago" and updates continuously
format.relativeTime(dateTime, now);
}
```
Expand Down
43 changes: 43 additions & 0 deletions docs/pages/docs/usage/lists.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import Callout from 'components/Callout';

# List formatting

When working with lists of items, you might want to format them as conjunctions or disjunctions.

Formatting aspects, like the used separators, differ per locale:

- "HTML, CSS, and JavaScript" in `en-US`
- "HTML, CSS und JavaScript" in `de-DE`

List formatting can be applied with the `useFormatter` hook:

```js
import {useFormatter} from 'next-intl';

function Component() {
const format = useFormatter();
const items = ['HTML', 'CSS', 'JavaScript'];

// Renders "HTML, CSS, and JavaScript"
format.list(items, {type: 'conjunction'});

// Renders "HTML, CSS, or JavaScript"
format.list(items, {type: 'disjunction'});
}
```

See [the MDN docs about `ListFormat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/ListFormat) to learn more about the options that you can provide to `list` ([interactive explorer](https://www.intl-explorer.com/ListFormat)).

Note that lists can can currently only be formatted via `useFormatter`, there's no equivalent inline syntax for messages at this point.

<Callout>
To reuse list formats for multiple components, you can configure [global
formats](/docs/usage/configuration#global-formats).
</Callout>

<details>
<summary>How can I render an array of messages?</summary>

See the [arrays of messages guide](/docs/usage/messages#arrays-of-messages).

</details>
1 change: 1 addition & 0 deletions docs/pages/docs/usage/numbers.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {useFormatter} from 'next-intl';
function Component() {
const format = useFormatter();

// Renders "$499.90"
format.number(499.9, {style: 'currency', currency: 'USD'});
}
```
Expand Down
5 changes: 4 additions & 1 deletion docs/pages/docs/usage/runtime-requirements-polyfills.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Based on the features you're using, you have to make sure your browser supports
- Number formatting: `Intl.NumberFormat` ([compatibility](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#browser_compatibility))
- Pluralization: `Intl.PluralRules` ([compatibility](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/PluralRules/PluralRules#browser_compatibility))
- Relative time formatting: `Intl.RelativeTimeFormat` ([compatibility](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat/RelativeTimeFormat#browser_compatibility))
- List formatting: `Intl.ListFormat` ([compatibility](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/ListFormat#browser_compatibility))

If you target a browser that doesn't support all the required APIs, consider using polyfills. [Polyfill.io](https://polyfill.io/v3/) is a valuable solution for this that helps you to load only the polyfills you need for a given locale.

Expand All @@ -36,7 +37,9 @@ function IntlPolyfills() {
'Intl.PluralRules',
`Intl.PluralRules.~locale.${locale}`,
'Intl.RelativeTimeFormat',
`Intl.RelativeTimeFormat.~locale.${locale}`
`Intl.RelativeTimeFormat.~locale.${locale}`,
'Intl.ListFormat',
`Intl.ListFormat.~locale.${locale}`
];

return (
Expand Down
3 changes: 1 addition & 2 deletions docs/theme.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,7 @@ export default {
project: {
link: 'https://github.com/amannn/next-intl'
},
docsRepositoryBase:
'https://github.com/amannn/next-intl/blob/main/packages/website',
docsRepositoryBase: 'https://github.com/amannn/next-intl/blob/main/docs',
useNextSeoProps() {
return {
titleTemplate: '%s – Internationalization (i18n) for Next.js'
Expand Down
4 changes: 2 additions & 2 deletions examples/example-advanced/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"dependencies": {
"accept-language-parser": "^1.5.0",
"lodash": "^4.17.21",
"next": "^13.4.0",
"next": "^13.4.6",
"next-intl": "^2.14.3",
"react": "^18.2.0",
"react-dom": "^18.2.0"
Expand All @@ -28,6 +28,6 @@
"eslint-config-molindo": "^6.0.0",
"eslint-config-next": "^13.4.0",
"jest": "^27.4.5",
"typescript": "^4.6.3"
"typescript": "^4.9.5"
}
}
1 change: 0 additions & 1 deletion examples/example-next-13-advanced/next.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
const withNextIntl = require('next-intl/plugin')();

module.exports = withNextIntl({
experimental: {appDir: true},
rewrites() {
return [
{
Expand Down
2 changes: 0 additions & 2 deletions examples/example-next-13-named-routes/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ const withNextIntl = require('next-intl/plugin')();
const routesByLocale = require('./routesByLocale.json');

module.exports = withNextIntl({
experimental: {appDir: true},

rewrites() {
// Routes are set up for the default locale ("en") in the app. This
// rewrites all non-English routes to their internal equivalent.
Expand Down
3 changes: 0 additions & 3 deletions examples/example-next-13-next-auth/next.config.js

This file was deleted.

4 changes: 2 additions & 2 deletions examples/example-next-13-next-auth/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"start": "next start"
},
"dependencies": {
"next": "^13.4.0",
"next": "^13.4.6",
"next-auth": "^4.22.1",
"next-intl": "^2.14.3",
"react": "^18.2.0",
Expand All @@ -24,6 +24,6 @@
"eslint": "^8.39.0",
"eslint-config-molindo": "^6.0.0",
"eslint-config-next": "^13.4.0",
"typescript": "^4.6.3"
"typescript": "^4.9.5"
}
}
4 changes: 1 addition & 3 deletions examples/example-next-13-with-pages/next.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
const withNextIntl = require('next-intl/plugin')();

module.exports = withNextIntl({
experimental: {appDir: true}
});
module.exports = withNextIntl();
1 change: 1 addition & 0 deletions examples/example-next-13/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ tsconfig.tsbuildinfo
/test-results/
/playwright-report/
/playwright/.cache/
out
4 changes: 1 addition & 3 deletions examples/example-next-13/next.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
const withNextIntl = require('next-intl/plugin')();

module.exports = withNextIntl({
experimental: {appDir: true}
});
module.exports = withNextIntl();
5 changes: 2 additions & 3 deletions examples/example-next-13/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@
"start": "next start"
},
"dependencies": {
"@next/font": "^13.1.6",
"clsx": "^1.2.1",
"next": "^13.4.0",
"next": "^13.4.6",
"next-intl": "^2.14.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand All @@ -29,6 +28,6 @@
"eslint-config-next": "^13.4.0",
"postcss": "^8.4.23",
"prettier-plugin-tailwindcss": "^0.2.3",
"typescript": "^4.6.3"
"typescript": "^4.9.5"
}
}
2 changes: 1 addition & 1 deletion examples/example-next-13/src/app/[locale]/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Inter} from '@next/font/google';
import clsx from 'clsx';
import {Inter} from 'next/font/google';
import {notFound} from 'next/navigation';
import {useLocale} from 'next-intl';
import {getTranslations} from 'next-intl/server';
Expand Down
6 changes: 6 additions & 0 deletions examples/example-next-13/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import {redirect} from 'next/navigation';

// This page only renders when the app is built statically (output: 'export')
export default function RootPage() {
redirect('/en');
}
Loading

0 comments on commit b219e13

Please sign in to comment.