Skip to content

Commit

Permalink
Merge branch 'canary' into render-callback-context
Browse files Browse the repository at this point in the history
  • Loading branch information
devknoll committed Apr 19, 2021
2 parents ccfb0c4 + e0da6a6 commit a24145b
Show file tree
Hide file tree
Showing 31 changed files with 2,772 additions and 331 deletions.
2 changes: 1 addition & 1 deletion docs/advanced-features/i18n-routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ description: Next.js has built-in support for internationalized routing and lang

Next.js has built-in support for internationalized ([i18n](https://en.wikipedia.org/wiki/Internationalization_and_localization#Naming)) routing since `v10.0.0`. You can provide a list of locales, the default locale, and domain-specific locales and Next.js will automatically handle the routing.

The i18n routing support is currently meant to complement existing i18n library solutions like `react-intl`, `react-i18next`, `lingui`, `rosetta`, and others by streamlining the routes and locale parsing.
The i18n routing support is currently meant to complement existing i18n library solutions like [`react-intl`](https://formatjs.io/docs/getting-started/installation), [`react-i18next`](https://react.i18next.com/), [`lingui`](https://lingui.js.org/), [`rosetta`](https://github.com/lukeed/rosetta), [`next-intl`](https://github.com/amannn/next-intl) and others by streamlining the routes and locale parsing.

## Getting started

Expand Down
31 changes: 26 additions & 5 deletions docs/api-reference/next/router.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,11 @@ import { useRouter } from 'next/router'
export default function Page() {
const router = useRouter()

return <span onClick={() => router.push('/about')}>Click me</span>
return (
<button type="button" onClick={() => router.push('/about')}>
Click me
</button>
)
}
```

Expand All @@ -99,7 +103,11 @@ import { useRouter } from 'next/router'
export default function Page() {
const router = useRouter()

return <button onClick={() => router.push('/post/abc')}>Click me</button>
return (
<button type="button" onClick={() => router.push('/post/abc')}>
Click me
</button>
)
}
```

Expand Down Expand Up @@ -138,6 +146,7 @@ export default function ReadMore({ post }) {

return (
<button
type="button"
onClick={() => {
router.push({
pathname: '/post/[pid]',
Expand Down Expand Up @@ -171,7 +180,11 @@ import { useRouter } from 'next/router'
export default function Page() {
const router = useRouter()

return <button onClick={() => router.replace('/home')}>Click me</button>
return (
<button type="button" onClick={() => router.replace('/home')}>
Click me
</button>
)
}
```

Expand Down Expand Up @@ -282,7 +295,11 @@ import { useRouter } from 'next/router'
export default function Page() {
const router = useRouter()

return <button onClick={() => router.back()}>Click here to go back</button>
return (
<button type="button" onClick={() => router.back()}>
Click here to go back
</button>
)
}
```

Expand All @@ -298,7 +315,11 @@ import { useRouter } from 'next/router'
export default function Page() {
const router = useRouter()

return <button onClick={() => router.reload()}>Click here to reload</button>
return (
<button type="button" onClick={() => router.reload()}>
Click here to reload
</button>
)
}
```

Expand Down
2 changes: 1 addition & 1 deletion examples/with-docker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ yarn create next-app --example with-docker nextjs-docker
## Using Docker

1. [Install Docker](https://docs.docker.com/get-docker/) on your machine.
1. Build your container: `docker build . -t nextjs-docker`.
1. Build your container: `docker build -t nextjs-docker .`.
1. Run your container: `docker run -p 3000:3000 nextjs-docker`.

You can view your images created with `docker images`.
Expand Down
34 changes: 34 additions & 0 deletions examples/with-i18n-next-intl/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local

# vercel
.vercel
29 changes: 29 additions & 0 deletions examples/with-i18n-next-intl/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# next-intl example

This example uses [next-intl](https://github.com/amannn/next-intl), a minimal, but complete solution for managing internationalization in Next.js apps.

## Features

- 🌟 I18n is an essential part of the user experience, therefore this library doesn't compromise on flexibility and never leaves you behind when you need to fine tune a translation. Messages use the proven [ICU syntax](https://formatjs.io/docs/core-concepts/icu-syntax) which covers interpolation, numbers, dates, times, plurals, ordinal pluralization, label selection based on enums and rich text.
- ⚔️ Based on battle-tested building blocks from [Format.JS](https://formatjs.io/) (used by `react-intl`), this library is a thin wrapper around high-quality, lower-level APIs for i18n.
- 💯 Built-in number and date formatting that is integrated with translations, e.g. allowing for the usage of global formats for a consistent look & feel of your app.
- 💡 A hooks-only API ensures that you can use the same API for `children` as well as for attributes which expect strings.
- 🚀 Integrates with both static as well as server side rendering.

## Deploy your own

Deploy the example using [Vercel](https://vercel.com):

[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/import/project?template=https://github.com/vercel/next.js/tree/canary/examples/with-i18n-next-intl)

## How to use

Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:

```bash
npx create-next-app --example with-i18n-next-intl
# or
yarn create next-app --example with-i18n-next-intl
```

Deploy it to the cloud with [Vercel](https://vercel.com/import?filter=next.js&utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
7 changes: 7 additions & 0 deletions examples/with-i18n-next-intl/components/Code.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default function Code({ children }) {
return (
<code style={{ background: '#eee', padding: 4, borderRadius: 4 }}>
{children}
</code>
)
}
26 changes: 26 additions & 0 deletions examples/with-i18n-next-intl/components/Navigation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { useTranslations } from 'next-intl'
import { useRouter } from 'next/dist/client/router'
import Link from 'next/link'

export default function Navigation() {
const t = useTranslations('Navigation')

const { locale, locales, route } = useRouter()
const otherLocale = locales?.find((cur) => cur !== locale)

return (
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<div style={{ display: 'flex', gap: 10 }}>
<Link href="/">
<a>{t('index')}</a>
</Link>
<Link href="/about">
<a>{t('about')}</a>
</Link>
</div>
<Link href={route} locale={otherLocale}>
<a>{t('switchLocale', { locale: otherLocale })}</a>
</Link>
</div>
)
}
19 changes: 19 additions & 0 deletions examples/with-i18n-next-intl/components/PageLayout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import Navigation from './Navigation'

export default function PageLayout({ children, title }) {
return (
<div
style={{
padding: 24,
fontFamily: 'system-ui, sans-serif',
lineHeight: 1.5,
}}
>
<Navigation />
<div style={{ maxWidth: 510 }}>
<h1>{title}</h1>
{children}
</div>
</div>
)
}
7 changes: 7 additions & 0 deletions examples/with-i18n-next-intl/messages/about/de.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"About": {
"title": "About",
"description": "Diese Seite verwendet Übersetzungen aus <code>./messages/about/{locale}.json</code> und <code>./messages/shared/{locale}.json</code>. Übersetzungen von der Startseite und anderen Sprachen werden nicht geladen.",
"lastUpdated": "Dieses Beispiel wurde {lastUpdatedRelative} aktualisiert ({lastUpdated, date, short})."
}
}
7 changes: 7 additions & 0 deletions examples/with-i18n-next-intl/messages/about/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"About": {
"title": "About",
"description": "This page uses messages from <code>./messages/about/{locale}.json</code> and <code>./messages/shared/{locale}.json</code>. Messages from the start page and other locales are not loaded.",
"lastUpdated": "This example was updated {lastUpdatedRelative} ({lastUpdated, date, short})."
}
}
6 changes: 6 additions & 0 deletions examples/with-i18n-next-intl/messages/index/de.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"Index": {
"title": "Start",
"description": "Diese Seite verwendet Übersetzungen aus <code>./messages/index/{locale}.json</code> und <code>./messages/shared/{locale}.json</code>. Übersetzungen von der Über-Seite und anderen Sprachen werden nicht geladen."
}
}
6 changes: 6 additions & 0 deletions examples/with-i18n-next-intl/messages/index/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"Index": {
"title": "Home",
"description": "This page uses messages from <code>./messages/index/{locale}.json</code> and <code>./messages/shared/{locale}.json</code>. Messages from the about page and other locales are not loaded."
}
}
7 changes: 7 additions & 0 deletions examples/with-i18n-next-intl/messages/shared/de.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"Navigation": {
"index": "Start",
"about": "Über",
"switchLocale": "Zu {locale, select, de {Deutsch} en {Englisch}} wechseln"
}
}
7 changes: 7 additions & 0 deletions examples/with-i18n-next-intl/messages/shared/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"Navigation": {
"index": "Home",
"about": "About",
"switchLocale": "Switch to {locale, select, de {German} en {English}}"
}
}
6 changes: 6 additions & 0 deletions examples/with-i18n-next-intl/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
i18n: {
locales: ['en', 'de'],
defaultLocale: 'en',
},
}
16 changes: 16 additions & 0 deletions examples/with-i18n-next-intl/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "with-i18n-next-intl",
"version": "1.0.0",
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
},
"dependencies": {
"next": "latest",
"next-intl": "^1.0.1",
"react": "^17.0.1",
"react-dom": "^17.0.1"
},
"license": "MIT"
}
29 changes: 29 additions & 0 deletions examples/with-i18n-next-intl/pages/_app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { NextIntlProvider } from 'next-intl'

export default function App({ Component, messages, pageProps }) {
return (
<NextIntlProvider
// To achieve consistent date, time and number formatting
// across the app, you can define a set of global formats.
formats={{
dateTime: {
short: {
day: 'numeric',
month: 'short',
year: 'numeric',
},
},
}}
messages={pageProps.messages}
// Providing an explicit value for `now` ensures consistent formatting of
// relative values regardless of the server or client environment.
now={new Date(pageProps.now)}
// Also an explicit time zone is helpful to ensure dates render the
// same way on the client as on the server, which might be located
// in a different time zone.
timeZone="Austria/Vienna"
>
<Component {...pageProps} />
</NextIntlProvider>
)
}
40 changes: 40 additions & 0 deletions examples/with-i18n-next-intl/pages/about.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { useIntl, useTranslations } from 'next-intl'
import { useRouter } from 'next/router'
import Code from '../components/Code'
import PageLayout from '../components/PageLayout'

export default function About() {
const t = useTranslations('About')
const { locale } = useRouter()
const intl = useIntl()
const lastUpdated = new Date(2021, 0, 26, 17, 4, 45)

return (
<PageLayout title={t('title')}>
<p>
{t('description', {
locale,
code: (children) => <Code>{children}</Code>,
})}
</p>
<p>
{t('lastUpdated', {
lastUpdated,
lastUpdatedRelative: intl.formatRelativeTime(lastUpdated),
})}
</p>
</PageLayout>
)
}

export function getStaticProps({ locale }) {
return {
props: {
messages: {
...require(`../messages/shared/${locale}.json`),
...require(`../messages/about/${locale}.json`),
},
now: new Date().getTime(),
},
}
}
31 changes: 31 additions & 0 deletions examples/with-i18n-next-intl/pages/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { useTranslations } from 'next-intl'
import { useRouter } from 'next/router'
import Code from '../components/Code'
import PageLayout from '../components/PageLayout'

export default function Index() {
const t = useTranslations('Index')
const { locale } = useRouter()

return (
<PageLayout title={t('title')}>
<p>
{t('description', {
locale,
code: (children) => <Code>{children}</Code>,
})}
</p>
</PageLayout>
)
}

export function getStaticProps({ locale }) {
return {
props: {
messages: {
...require(`../messages/shared/${locale}.json`),
...require(`../messages/index/${locale}.json`),
},
},
}
}
Loading

0 comments on commit a24145b

Please sign in to comment.