Skip to content

Commit

Permalink
chore: update with-react-intl example (vercel#40999)
Browse files Browse the repository at this point in the history
## Changes

see commits

## Additional Info

Since this example is quite complex I tried to remove additional noise
(unused type inference).

## Documentation / Examples

- [x] Make sure the linting passes by running `pnpm lint`
- [x] The "examples guidelines" are followed from [our contributing
doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)

## Related

Closes: vercel#40975
  • Loading branch information
HaNdTriX authored and BowlingX committed Oct 5, 2022
1 parent 1a549cc commit 7debda2
Show file tree
Hide file tree
Showing 11 changed files with 65 additions and 72 deletions.
3 changes: 3 additions & 0 deletions examples/with-react-intl/.gitignore
Expand Up @@ -35,3 +35,6 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts

# i18n
compiled-lang
1 change: 1 addition & 0 deletions examples/with-react-intl/.npmrc
@@ -0,0 +1 @@
enable-pre-post-scripts=true
3 changes: 0 additions & 3 deletions examples/with-react-intl/.vscode/settings.json

This file was deleted.

30 changes: 15 additions & 15 deletions examples/with-react-intl/components/Layout.tsx
@@ -1,32 +1,32 @@
import { ReactChild } from 'react'
import { ReactNode } from 'react'
import { useIntl } from 'react-intl'
import Head from 'next/head'
import Nav from './Nav'

interface LayoutProps {
title?: string
description?: string
children: ReactChild | ReactChild[]
children: ReactNode
}

export default function Layout({ title, description, children }: LayoutProps) {
const intl = useIntl()

title ||= intl.formatMessage({
defaultMessage: 'React Intl Next.js Example',
description: 'Default document title',
})

description ||= intl.formatMessage({
defaultMessage: 'This page is powered by Next.js',
description: 'Default document description',
})

return (
<>
<Head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>
{title ||
intl.formatMessage({
defaultMessage: 'React Intl Next.js Example',
description: 'Default document title',
})}
{description ||
intl.formatMessage({
defaultMessage: 'This page is powered by Next.js',
description: 'Default document description',
})}
</title>
<title>{title}</title>
<meta name="description" content={description} />
</Head>
<header>
<Nav />
Expand Down
2 changes: 1 addition & 1 deletion examples/with-react-intl/components/Nav.tsx
Expand Up @@ -30,7 +30,7 @@ export default function Nav() {

<li className={styles.divider}></li>

{locales.map((availableLocale) => (
{locales?.map((availableLocale) => (
<li key={availableLocale} className={styles.li}>
<Link
href={asPath}
Expand Down
38 changes: 12 additions & 26 deletions examples/with-react-intl/helper/loadIntlMessages.ts
@@ -1,35 +1,21 @@
import fs from 'fs/promises'
import path from 'path'
export type MessageConfig = Record<string, string>

type LoadI18nMessagesProps = {
locale: string
defaultLocale: string
}

type MessageConfig = { [key: string]: string }

export default async function loadI18nMessages({
locale,
defaultLocale,
}: LoadI18nMessagesProps): Promise<MessageConfig> {
export default async function loadI18nMessages(
locale: string,
defaultLocale = 'en'
) {
// If the default locale is being used we can skip it
if (locale === defaultLocale) {
return {}
}

if (locale !== defaultLocale) {
const languagePath = path.join(
process.cwd(),
`compiled-lang/${locale}.json`
try {
return import(`../compiled-lang/${locale}.json`).then(
(module) => module.default
)
} catch (error) {
throw new Error(
'Could not load compiled language files. Please run "npm run i18n:compile" first"'
)
try {
const contents = await fs.readFile(languagePath, 'utf-8')
return JSON.parse(contents)
} catch (error) {
console.info(
'Could not load compiled language files. Please run "npm run i18n:compile" first"'
)
console.error(error)
}
}
}
20 changes: 10 additions & 10 deletions examples/with-react-intl/package.json
Expand Up @@ -11,17 +11,17 @@
"i18n:compile": "formatjs compile-folder lang compiled-lang"
},
"dependencies": {
"next": "11.1.0",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-intl": "5.20.9"
"next": "latest",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-intl": "6.1.1"
},
"devDependencies": {
"@formatjs/cli": "4.2.31",
"@types/node": "16.6.2",
"@types/react": "17.0.19",
"babel-plugin-formatjs": "10.3.5",
"eslint-plugin-formatjs": "2.17.4",
"typescript": "4.3.5"
"@formatjs/cli": "5.1.0",
"@types/node": "18.7.23",
"@types/react": "18.0.21",
"babel-plugin-formatjs": "10.3.28",
"eslint-plugin-formatjs": "4.3.1",
"typescript": "4.8.4"
}
}
8 changes: 6 additions & 2 deletions examples/with-react-intl/pages/_app.tsx
@@ -1,12 +1,16 @@
import type { AppProps } from 'next/app'
import type { MessageConfig } from '../helper/loadIntlMessages'
import { IntlProvider } from 'react-intl'
import { useRouter } from 'next/router'

export default function MyApp({ Component, pageProps }: AppProps) {
export default function MyApp({
Component,
pageProps,
}: AppProps<{ intlMessages: MessageConfig }>) {
const { locale, defaultLocale } = useRouter()
return (
<IntlProvider
locale={locale}
locale={locale as string}
defaultLocale={defaultLocale}
messages={pageProps.intlMessages}
>
Expand Down
15 changes: 8 additions & 7 deletions examples/with-react-intl/pages/about.tsx
@@ -1,19 +1,20 @@
import type { GetServerSidePropsContext } from 'next'
import { FormattedRelativeTime, useIntl } from 'react-intl'
import Layout from '../components/Layout'
import loadIntlMessages from '../helper/loadIntlMessages'
import { InferGetStaticPropsType } from 'next'
import Layout from '../components/Layout'

export async function getStaticProps(ctx) {
export async function getStaticProps({
locale,
defaultLocale,
}: GetServerSidePropsContext) {
return {
props: {
intlMessages: await loadIntlMessages(ctx),
intlMessages: await loadIntlMessages(locale as string, defaultLocale),
},
}
}

type AboutPageProps = InferGetStaticPropsType<typeof getStaticProps>

export default function AboutPage(props: AboutPageProps) {
export default function AboutPage() {
const intl = useIntl()
return (
<Layout
Expand Down
15 changes: 8 additions & 7 deletions examples/with-react-intl/pages/index.tsx
@@ -1,19 +1,20 @@
import type { GetStaticPropsContext } from 'next'
import { FormattedMessage, FormattedNumber, useIntl } from 'react-intl'
import Layout from '../components/Layout'
import loadIntlMessages from '../helper/loadIntlMessages'
import { InferGetStaticPropsType } from 'next'
import Layout from '../components/Layout'

export async function getStaticProps(ctx) {
export async function getStaticProps({
defaultLocale,
locale,
}: GetStaticPropsContext) {
return {
props: {
intlMessages: await loadIntlMessages(ctx),
intlMessages: await loadIntlMessages(locale as string, defaultLocale),
},
}
}

type HomePageProps = InferGetStaticPropsType<typeof getStaticProps>

export default function HomePage(props: HomePageProps) {
export default function IndexPage() {
const intl = useIntl()
return (
<Layout
Expand Down
2 changes: 1 addition & 1 deletion examples/with-react-intl/tsconfig.json
Expand Up @@ -5,7 +5,7 @@
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
Expand Down

0 comments on commit 7debda2

Please sign in to comment.