Skip to content

Commit

Permalink
Nextjs example & docs
Browse files Browse the repository at this point in the history
  • Loading branch information
fromthemills committed Apr 7, 2024
1 parent 9360179 commit eda630a
Show file tree
Hide file tree
Showing 31 changed files with 6,369 additions and 1 deletion.
3 changes: 3 additions & 0 deletions examples/nextjs-rsc/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}
45 changes: 45 additions & 0 deletions examples/nextjs-rsc/.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
6 changes: 6 additions & 0 deletions examples/nextjs-rsc/.prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
semi: false,
singleQuote: true,
trailingComma: 'none'
// endOfLine: "lf"
}
69 changes: 69 additions & 0 deletions examples/nextjs-rsc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
## Example project using Next 13 SWC Compiler with LinguiJS Plugin

This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).

## SWC Compatibility
SWC Plugin support is still experimental. Semver backwards compatibility between different `next-swc` versions is not guaranteed.

Therefore, you need to select an appropriate version of the Lingui plugin to match compatible `NextJs` version.
You also need to add the `@lingui/swc-plugin` dependency with strict version without a range specifier.

```json
{
"devDependencies": {
"@lingui/swc-plugin": "4.0.5"
}
}
```

For more information on compatibility, please refer to the [Compatibility section](https://github.com/lingui/swc-plugin#compatibility).

## Getting Started

First, run the development server:

```bash
npm run dev
# or
yarn dev
# or
pnpm dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

## LinguiJS Integration
LinguiJs integrated with standard nextjs i18n support. Nextjs do routing for every language,
LinguiJs activated with `router.locale`.

Open [http://localhost:3000/cs](http://localhost:3000/cs) with your browser to prerender page in different language.

## LinguiJS Related Commands

Extract messages from sourcecode:
```bash
npm run lingui:extract
# or
yarn lingui:extract
# or
pnpm lingui:extract
```

## Important Notes
- You **should not have** a babel config in the project, otherwise Next will turn off SWC compiler in favor of babel.
- The actual code is compiled with SWC + Lingui SWC plugin.

## Learn More

To learn more about Next.js, take a look at the following resources:

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!

## Deploy on Vercel

The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.

Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
3 changes: 3 additions & 0 deletions examples/nextjs-rsc/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-rsc/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/']
}
]
}
5 changes: 5 additions & 0 deletions examples/nextjs-rsc/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
20 changes: 20 additions & 0 deletions examples/nextjs-rsc/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/** @type {import('next').NextConfig} */
module.exports = {
webpack: (config, options) => {
config.module.rules.push({
test: /\.po/,
use: [
options.defaultLoaders.babel,
{
loader: '@lingui/loader',
},
],
})
return config
},
experimental: {
swcPlugins: [
['@lingui/swc-plugin', {}],
],
},
}
31 changes: 31 additions & 0 deletions examples/nextjs-rsc/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "nextjs-swc-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"
}
}
Binary file added examples/nextjs-rsc/public/favicon.ico
Binary file not shown.
4 changes: 4 additions & 0 deletions examples/nextjs-rsc/public/vercel.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
47 changes: 47 additions & 0 deletions examples/nextjs-rsc/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-rsc/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>
)
}

16 changes: 16 additions & 0 deletions examples/nextjs-rsc/src/components/AboutText.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Trans } from '@lingui/macro'

export function AboutText() {
return (
<p>
<Trans id="next-explanation">
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.
</Trans>
</p>
)
}
27 changes: 27 additions & 0 deletions examples/nextjs-rsc/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-rsc/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}
/>
);
}

0 comments on commit eda630a

Please sign in to comment.