-
-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 319c21e
Showing
49 changed files
with
7,915 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"extends": "next/core-web-vitals", | ||
"rules": { | ||
"@next/next/no-img-element": 0 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
.next | ||
node_modules | ||
.vscode | ||
.next | ||
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/** | ||
* If you want to enable locale keys typechecking and enhance IDE experience. | ||
* | ||
* Requires `resolveJsonModule:true` in your tsconfig.json. | ||
* | ||
* @link https://www.i18next.com/overview/typescript | ||
*/ | ||
import 'i18next' | ||
|
||
import type translation from '../app/i18n/locales/en/translation.json' | ||
import type secondPage from '../app/i18n/locales/en/second-page.json' | ||
import type footer from '../app/i18n/locales/en/footer.json' | ||
import type clientPage from '../app/i18n/locales/en/client-page.json' | ||
import type secondClientPage from '../app/i18n/locales/en/second-client-page.json' | ||
|
||
interface I18nNamespaces { | ||
translation: typeof translation | ||
'second-page': typeof secondPage | ||
footer: typeof footer | ||
'client-page': typeof clientPage | ||
'second-client-page': typeof secondClientPage | ||
} | ||
|
||
declare module 'i18next' { | ||
interface CustomTypeOptions { | ||
// returnNull: false | ||
// defaultNS: 'translation' | ||
resources: I18nNamespaces | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# Next.js 13 app directory feature in combination with i18next | ||
|
||
This example shows a basic way to use [i18next](https://www.i18next.com) (and [react-i18next](https://react.i18next.com)) in a [Next.js 13](https://beta.nextjs.org/) app with the new app directory features. | ||
[next-i18next](https://next.i18next.com) is not needed anymore for this setup. | ||
|
||
It shows i18next integration on some server side pages and some client side pages. | ||
|
||
There is also an example middleware with language detection and persistence via cookie. | ||
|
||
*This example has been created out of [this discussion](https://github.com/i18next/next-i18next/discussions/1993).* | ||
|
||
## There's also a [blog post](https://locize.com/blog/next-13-app-dir-i18n) describing this with more detail information. | ||
|
||
[](https://locize.com/blog/next-13-app-dir-i18n) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { useTranslation } from '../../i18n' | ||
|
||
export default async function Head({ params: { lng } }) { | ||
const { t } = await useTranslation(lng, 'client-page') | ||
|
||
return ( | ||
<> | ||
<title>{t('title')}</title> | ||
<meta | ||
name="description" | ||
content="A playground to explore new Next.js 13 app directory features such as nested layouts, instant loading states, streaming, and component level data fetching." | ||
/> | ||
</> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
'use client' | ||
|
||
import Link from 'next/link' | ||
import { useTranslation } from '../../i18n/client' | ||
import { Header } from '../components/Header' | ||
import { Footer } from '../components/Footer/client' | ||
import { useState } from 'react' | ||
|
||
export default function Page({ params: { lng } }: { | ||
params: { | ||
lng: string; | ||
}; | ||
}) { | ||
const { t } = useTranslation(lng, 'client-page') | ||
const [counter, setCounter] = useState(0) | ||
return ( | ||
<> | ||
<main> | ||
<Header heading={t('h1')} /> | ||
<p>{t('counter', { count: counter })}</p> | ||
<div> | ||
<button onClick={() => setCounter(Math.max(0, counter - 1))}>-</button> | ||
<button onClick={() => setCounter(Math.min(10, counter + 1))}>+</button> | ||
</div> | ||
<Link href={`/${lng}/second-client-page`}> | ||
{t('to-second-client-page')} | ||
</Link> | ||
<Link href={`/${lng}`}> | ||
<button type="button"> | ||
{t('back-to-home')} | ||
</button> | ||
</Link> | ||
</main> | ||
<Footer lng={lng} path="/client-page" /> | ||
</> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { i18n } from 'i18next' | ||
import Link from 'next/link' | ||
import { Trans } from 'react-i18next/TransWithoutContext' | ||
import { languages } from '../../../i18n/settings' | ||
|
||
export const FooterBase = ({ i18n, lng, path = '' }: { i18n: i18n, lng: string, path: string }) => { | ||
const t = i18n.getFixedT(lng, 'footer') | ||
return ( | ||
<footer> | ||
<Trans i18nKey="languageSwitcher" t={t}> | ||
{/* @ts-expect-error Trans interpolation */} | ||
Switch from <strong>{{lng}}</strong> to:{' '} | ||
</Trans> | ||
{languages.filter((l) => lng !== l).map((l, index) => { | ||
return ( | ||
<span key={l}> | ||
{index > 0 && (' or ')} | ||
<Link href={`/${l}${path}`}> | ||
{l} | ||
</Link> | ||
</span> | ||
) | ||
})} | ||
<p>{t('description')}</p> | ||
<p | ||
style={{ | ||
fontSize: 'smaller', | ||
fontStyle: 'italic', | ||
marginTop: 20, | ||
}} | ||
> | ||
<Trans i18nKey="helpLocize" t={t}> | ||
With using | ||
<a href="https://locize.com" target="_new"> | ||
locize | ||
</a> | ||
you directly support the future of | ||
<a href="https://www.i18next.com" target="_new"> | ||
i18next | ||
</a> | ||
. | ||
</Trans> | ||
</p> | ||
</footer> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
'use client' | ||
|
||
import { FooterBase } from './FooterBase' | ||
import { useTranslation } from '../../../i18n/client' | ||
|
||
export const Footer = ({ lng, path }) => { | ||
const { i18n } = useTranslation(lng, 'footer') | ||
return <FooterBase i18n={i18n} lng={lng} path={path} /> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { useTranslation } from '../../../i18n' | ||
import { FooterBase } from './FooterBase' | ||
|
||
export const Footer = async ({ lng, path }: { | ||
lng: string; | ||
path?: string; | ||
}) => { | ||
const { t, i18n } = await useTranslation(lng, 'footer') | ||
return <FooterBase i18n={i18n} lng={lng} path={path} /> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
export const Header = ({ heading }) => ( | ||
<> | ||
<h2> | ||
Next.js 13 <small>(app directory)</small> - i18next | ||
<hr /> | ||
</h2> | ||
<h1>{heading}</h1> | ||
<a className="github" href="//github.com/i18next/i18next"> | ||
<i className="typcn typcn-social-github-circular" /> | ||
</a> | ||
</> | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
body { | ||
font-family: 'Open Sans', sans-serif; | ||
text-align: center; | ||
background-image: linear-gradient( | ||
to left top, | ||
#ffffff, | ||
#f5f5f5, | ||
#eaeaea, | ||
#e0e0e0, | ||
#d6d6d6 | ||
); | ||
display: flex; | ||
flex-direction: column; | ||
margin: 0; | ||
min-height: 100vh; | ||
min-width: 100vw; | ||
} | ||
|
||
h1, | ||
h2 { | ||
font-family: 'Oswald', sans-serif; | ||
} | ||
|
||
h1 { | ||
font-size: 3rem; | ||
/* margin: 5rem 0; */ | ||
} | ||
h2 { | ||
min-width: 18rem; | ||
font-size: 2rem; | ||
opacity: 0.3; | ||
} | ||
h3 { | ||
font-size: 1.5rem; | ||
opacity: 0.5; | ||
} | ||
|
||
p { | ||
line-height: 1.65em; | ||
} | ||
p:nth-child(2) { | ||
font-style: italic; | ||
opacity: 0.65; | ||
margin-top: 1rem; | ||
} | ||
|
||
a.github { | ||
position: fixed; | ||
top: 0.5rem; | ||
right: 0.75rem; | ||
font-size: 4rem; | ||
color: #888; | ||
opacity: 0.8; | ||
} | ||
a.github:hover { | ||
opacity: 1; | ||
} | ||
|
||
button { | ||
display: inline-block; | ||
vertical-align: bottom; | ||
outline: 0; | ||
text-decoration: none; | ||
cursor: pointer; | ||
background-color: rgba(255, 255, 255, 0.5); | ||
box-sizing: border-box; | ||
font-size: 1em; | ||
font-family: inherit; | ||
border-radius: 3px; | ||
transition: box-shadow 0.2s ease; | ||
user-select: none; | ||
line-height: 2.5em; | ||
min-height: 40px; | ||
padding: 0 0.8em; | ||
border: 0; | ||
color: inherit; | ||
position: relative; | ||
transform: translateZ(0); | ||
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26); | ||
margin: 0.8rem; | ||
} | ||
|
||
button:hover, | ||
button:focus { | ||
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.4); | ||
} | ||
|
||
main { | ||
display: flex; | ||
flex-direction: column; | ||
flex: 1; | ||
justify-content: center; | ||
align-items: center; | ||
} | ||
footer { | ||
background-color: rgba(255, 255, 255, 0.5); | ||
width: 100vw; | ||
padding: 3rem 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { languages, fallbackLng } from '../i18n/settings' | ||
import { useTranslation } from '../i18n' | ||
|
||
export default async function Head({ params: { lng } }) { | ||
if (languages.indexOf(lng) < 0) lng = fallbackLng | ||
const { t } = await useTranslation(lng) | ||
|
||
return ( | ||
<> | ||
<title>{t('title')}</title> | ||
<meta | ||
name="description" | ||
content="A playground to explore new Next.js 13 app directory features such as nested layouts, instant loading states, streaming, and component level data fetching." | ||
/> | ||
</> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import './global.css' | ||
|
||
import { dir } from 'i18next' | ||
import { languages } from '../i18n/settings' | ||
|
||
export async function generateStaticParams() { | ||
return languages.map((lng) => ({ lng })) | ||
} | ||
|
||
export default function RootLayout({ | ||
children, | ||
params: { | ||
lng | ||
} | ||
}) { | ||
return ( | ||
<html lang={lng} dir={dir(lng)}> | ||
<head /> | ||
<body> | ||
{children} | ||
</body> | ||
</html> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import Link from 'next/link' | ||
import { Trans } from 'react-i18next/TransWithoutContext' | ||
import { languages, fallbackLng } from '../i18n/settings' | ||
import { useTranslation } from '../i18n' | ||
import { Header } from './components/Header' | ||
import { Footer } from './components/Footer' | ||
|
||
export default async function Page({ params: { lng } }: { | ||
params: { | ||
lng: string; | ||
}; | ||
}) { | ||
if (languages.indexOf(lng) < 0) lng = fallbackLng | ||
const { t } = await useTranslation(lng) | ||
|
||
return ( | ||
<> | ||
<main> | ||
<Header heading={t('h1')} /> | ||
<h2> | ||
<Trans t={t} i18nKey="welcome"> | ||
Welcome to Next.js v13 <small>appDir</small> and i18next | ||
</Trans> | ||
</h2> | ||
<div style={{ width: '100%' }}> | ||
<p> | ||
<Trans t={t} i18nKey="blog.text"> | ||
Check out the corresponding <a href={t('blog.link')}>blog post</a> describing this example. | ||
</Trans> | ||
</p> | ||
<a href={t('blog.link')}> | ||
<img | ||
style={{ width: '50%' }} | ||
alt="next 13 blog post" | ||
src="https://locize.com/blog/next-13-app-dir-i18n/next-13-app-dir-i18n.jpg" | ||
/> | ||
</a> | ||
</div> | ||
<hr style={{ marginTop: 20, width: '90%' }} /> | ||
<div> | ||
<Link href={`/${lng}/second-page`}> | ||
<button type="button">{t('to-second-page')}</button> | ||
</Link> | ||
<Link href={`/${lng}/client-page`}> | ||
<button type="button">{t('to-client-page')}</button> | ||
</Link> | ||
</div> | ||
</main> | ||
{/* @ts-expect-error Server Component */} | ||
<Footer lng={lng}/> | ||
</> | ||
) | ||
} |
Oops, something went wrong.