Skip to content
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

docs: React server components example and docs #1903

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
45 changes: 45 additions & 0 deletions examples/nextjs-app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# 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

# lingui js
/src/locales/**/*.js

.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
File renamed without changes.
File renamed without changes.
3 changes: 3 additions & 0 deletions examples/nextjs-app/globals.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
declare module "*.po" {
export const messages: any
}
17 changes: 17 additions & 0 deletions examples/nextjs-app/lingui.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const nextConfig = require('./next.config')

/** @type {import('@lingui/conf').LinguiConfig} */
module.exports = {
locales: ['en', 'sr', 'es', 'pseudo'],
pseudoLocale: 'pseudo',
sourceLocale: 'en',
fallbackLocales: {
default: 'en'
},
catalogs: [
{
path: 'src/locales/{locale}',
include: ['src/']
}
]
}
File renamed without changes.
19 changes: 19 additions & 0 deletions examples/nextjs-app/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/** @type {import('next').NextConfig} */
module.exports = {
webpack: (config, options) => {
config.module.rules.push({
test: /\.po/,
use: [
{
loader: '@lingui/loader',
},
],
})
return config
},
experimental: {
swcPlugins: [
['@lingui/swc-plugin', {}],
],
},
}
31 changes: 31 additions & 0 deletions examples/nextjs-app/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "nextjs-app-example",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"debug": "NODE_OPTIONS='--inspect' next dev",
"build": "yarn lingui:extract && next build",
"start": "next start",
"lingui:extract": "lingui extract --clean",
"test": "yarn build"
},
"dependencies": {
"@lingui/cli": "^4.8.0",
"@lingui/core": "^4.8.0",
"@lingui/react": "^4.8.0",
"next": "14.1.4",
"react": "^18",
"react-dom": "^18"
},
"devDependencies": {
"@lingui/cli": "^4.8.0",
"@lingui/loader": "^4.8.0",
"@lingui/macro": "^4.8.0",
"@lingui/swc-plugin": "4.0.6",
"@types/react": "^18",
"eslint": "8.35.0",
"eslint-config-next": "12.3.4",
"typescript": "^4.7.4"
}
}
47 changes: 47 additions & 0 deletions examples/nextjs-app/src/app/[locale]/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { t } from '@lingui/macro'
import { Inter } from "next/font/google"
import "../../styles/globals.css"
import { I18nProvider } from '../../components/I18nProvider'
import { loadCatalog, setI18n } from '../../utils'

type Params = {
locale: string
}

type Props = {
params: Params
children: React.ReactNode
}

const inter = Inter({ subsets: ["latin"] })

export function generateMetadata({ params }: { params: Params }) {
const { locale } = params
const i18n = setI18n(locale)
return {
title: t(i18n)`Translation Demo`,
}
}

export function generateStaticParams() {
return [
{ locale: 'en' },
{ locale: 'sr' },
{ locale: 'es' },
{ locale: 'pseudo'}
]
}

export default function RootLayout({ params, children }: Props) {
const { locale } = params
const messages = loadCatalog(locale)
return (
<html lang={locale}>
<body className={inter.className}>
<I18nProvider locale={locale} messages={messages}>
{children}
</I18nProvider>
</body>
</html>
);
}
35 changes: 35 additions & 0 deletions examples/nextjs-app/src/app/[locale]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { t, Trans } from '@lingui/macro'
import { AboutText } from '../../components/AboutText'
import { setI18n } from '../../utils'
import Developers from '../../components/Developers'
import { Switcher } from '../../components/Switcher'
import styles from '../../styles/Index.module.css'

type Params = {
locale: string
}

type Props = {
params: Params
children: React.ReactNode
}

export default function Page({ params }: Props) {
return (
<div className={styles.container}>
<main className={styles.main}>
<Switcher />
<h1 className={styles.title}>
<Trans>
Welcome to <a href="https://nextjs.org">Next.js!</a>
</Trans>
</h1>
<div className={styles.description}>
<AboutText />
</div>
<Developers />
</main>
</div>
)
}

27 changes: 27 additions & 0 deletions examples/nextjs-app/src/components/Developers.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
'use client'

import { useState } from 'react'
import { Trans, Plural } from '@lingui/macro'

export default function Developers() {
const [selected, setSelected] = useState('1')
return (
<div>
<p>
<Trans>Plural Test: How many developers?</Trans>
</p>
<div style={{ display: 'flex', justifyContent: 'space-evenly' }}>
<select
value={selected}
onChange={(evt) => setSelected(evt.target.value)}
>
<option value={'1'}>1</option>
<option value={'2'}>2</option>
</select>
<p>
<Plural value={selected} one={'Developer'} other={`Developers`} />
</p>
</div>
</div>
)
}
22 changes: 22 additions & 0 deletions examples/nextjs-app/src/components/I18nProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'use client'

import { setupI18n } from '@lingui/core'
import { I18nProvider as LinguiProvider } from '@lingui/react'

type Props = {
locale: string
messages?: any
children: React.ReactNode
}

export function I18nProvider({ locale, messages, ...props }: Props) {
return (
<LinguiProvider
i18n={setupI18n({
locale,
messages: { [locale]: messages },
})}
{...props}
/>
);
}
43 changes: 43 additions & 0 deletions examples/nextjs-app/src/components/Switcher.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
'use client'

import { useRouter, useParams } from 'next/navigation'
import { t, msg } from '@lingui/macro'
import { MessageDescriptor } from '@lingui/core/src'
import { useLingui } from '@lingui/react'

type LOCALES = 'en' | 'sr' | 'es' | 'pseudo'

const languages: { [key: string]: MessageDescriptor } = {
en: msg`English`,
sr: msg`Serbian`,
es: msg`Spanish`
}

export function Switcher() {
const router = useRouter()
const { locale } = useParams<{ locale: string }>()
const { i18n } = useLingui()
const currentLocale = locale!.split('-')[0]

// disabled for DEMO - so we can demonstrate the 'pseudo' locale functionality
// if (process.env.NEXT_PUBLIC_NODE_ENV !== 'production') {
// languages['pseudo'] = t`Pseudo`
// }

function handleChange(event: React.ChangeEvent<HTMLSelectElement>) {
const locale = event.target.value as LOCALES
router.push(`/${locale}`)
}

return (
<select value={currentLocale} onChange={handleChange}>
{Object.keys(languages).map((locale) => {
return (
<option value={locale} key={locale}>
{i18n._(languages[locale as unknown as LOCALES])}
</option>
)
})}
</select>
)
}
47 changes: 47 additions & 0 deletions examples/nextjs-app/src/locales/en.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2020-12-04 23:19+0100\n"
"Mime-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: en\n"
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: \n"
"Plural-Forms: \n"

#: src/components/Developers.tsx:22
msgid "{selected, plural, one {Developer} other {Developers}}"
msgstr "{selected, plural, one {Developer} other {Developers}}"

#: src/components/Switcher.tsx:11
msgid "English"
msgstr "English"

#. js-lingui-explicit-id
#: src/components/AboutText.tsx:6
msgid "next-explanation"
msgstr "Next.js is an open-source React front-end development web framework that enables functionality such as server-side rendering and generating static websites for React based web applications. It is a production-ready framework that allows developers to quickly create static and dynamic JAMstack websites and is used widely by many large companies."

#: src/components/Developers.tsx:11
msgid "Plural Test: How many developers?"
msgstr "Plural Test: How many developers?"

#: src/components/Switcher.tsx:12
msgid "Serbian"
msgstr "Serbian"

#: src/components/Switcher.tsx:13
msgid "Spanish"
msgstr "Spanish"

#: src/app/[locale]/layout.tsx:22
msgid "Translation Demo"
msgstr "Translation Demo"

#: src/app/[locale]/page.tsx:23
msgid "Welcome to <0>Next.js!</0>"
msgstr "Welcome to <0>Next.js!</0>"
47 changes: 47 additions & 0 deletions examples/nextjs-app/src/locales/es.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2020-12-05 21:42+0100\n"
"Mime-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: es\n"
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: \n"
"Plural-Forms: \n"

#: src/components/Developers.tsx:22
msgid "{selected, plural, one {Developer} other {Developers}}"
msgstr "{selected, plural, one {Programador} other {Programadores}}"

#: src/components/Switcher.tsx:11
msgid "English"
msgstr "Inglés"

#. js-lingui-explicit-id
#: src/components/AboutText.tsx:6
msgid "next-explanation"
msgstr "Next.js es un marco de trabajo web de desarrollo front-end de React de código abierto que permite funciones como la representación del lado del servidor y la generación de sitios web estáticos para aplicaciones web basadas en React. Es un marco listo para producción que permite a los desarrolladores crear rápidamente sitios web JAMstack estáticos y dinámicos y es ampliamente utilizado por muchas grandes empresas."

#: src/components/Developers.tsx:11
msgid "Plural Test: How many developers?"
msgstr "Prueba Plural: Cuantos programadores?"

#: src/components/Switcher.tsx:12
msgid "Serbian"
msgstr "Serbio"

#: src/components/Switcher.tsx:13
msgid "Spanish"
msgstr "Español"

#: src/app/[locale]/layout.tsx:22
msgid "Translation Demo"
msgstr "Demostración de Traducción"

#: src/app/[locale]/page.tsx:23
msgid "Welcome to <0>Next.js!</0>"
msgstr "Bienvenido a <0>Next.js!</0>"
Loading
Loading