QuiiBz / next-international

Type-safe internationalization (i18n) for Next.js
https://next-international.vercel.app
MIT License
1.19k stars 52 forks source link

feat: next-international V2 #361

Open QuiiBz opened 4 months ago

QuiiBz commented 4 months ago

Development branch for https://github.com/QuiiBz/next-international/issues/359

Breaking changes

Single createI18n function

Instead of having two separate createI18nClient / createI18nServer methods that needs to live in separate files and each expose distinct but similar methods (useI18n / getI18n), a single createI18n function is introduced to replace all of them.

You can import from the same file the getI18n / getScopedI18n methods, without worrying about client vs server - it's taken care of by next-international automatically. These functions both return a Promise, which you can either await inside a Server Component or use() inside a Client Component.

Before/after #### Before ```tsx // locales/client.ts export const { useI18n, useScopedI18n, ... } = createI18nClient(...) // locales/server.ts export const { getI18n, getScopedI18n, ... } = createI18nServer(...) // Client Component import { useI18n } from '@/locales/client' export function ClientComponent() { const t = useI18n() ... } // Server Component import { getI18n } from '@/locales/server' export async function ServerComponent() { const t = await getI18n() ... } ``` #### After ```tsx // locales/index.ts export const { getI18n, getScopedI18n, ... } = createI18n(...) // Client Component import { getI18n } from '@/locales' import { use } from 'react' export function Component() { const t = use(getI18n()) ... } // Server Component import { getI18n } from '@/locales/server' export async function ServerComponent() { const t = await getI18n() ... } ```

Improved middleware

Previously, it was complex to use next-international's middleware with custom code or external middlewares (e.g. next-auth). The improved createI18nMiddleware function now accepts a full middleware-like signature ((request: NextRequest) => NextResponse) as the first argument, meaning you can very easily add custom logic:

Before/after #### Before ```ts const I18nMiddleware = createI18nMiddleware({ locales: ['en', 'fr'], defaultLocale: 'en' }) export function middleware(request: NextRequest) { return I18nMiddleware(request) } ``` #### After ```ts export const middleware = createI18nMiddleware(request => { // Any custom logic using a raw `NextRequest` and returning a raw `NextResponse` return NextResponse.next() }, { locales: ['en', 'fr'], defaultLocale: 'en' }); ```

Removal of I18nProviderClient

With the new approach in next-international v2, the I18nProviderClient component is no longer needed - you can simply remove it completely!

Rename getStaticParams to generateI18nStaticParams

The utility function used for static rendering in combinaison with Next.js' generateStaticParams function has been renamed from getStaticParams to generateI18nStaticParams, in order to match the other function names:

Before/after #### Before ```ts // locales/server.ts export const { getStaticParams, ... } = createI18n(...) // app/[locale]/layout.tsx import { getStaticParams } from '@/locales' export function generateStaticParams() { return getStaticParams() } ``` #### After ```ts // locales/index.ts export const { generateI18nStaticParams, ... } = createI18n(...) // app/[locale]/layout.tsx import { generateI18nStaticParams } from '@/locales' export const dynamicParams = false export function generateStaticParams() { return generateI18nStaticParams() } ```
### Rename locale helpers The locale helper functions have been renamed to be more simple: - `useCurrentLocale()` -> `getLocale()` - `getCurrentLocale()` -> `getLocale()` - No update: `useChangeLocale()` (this one keeps the `use*` naming because it can only be used inside Client Components)
vercel[bot] commented 4 months ago

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
next-international ✅ Ready (Inspect) Visit Preview Mar 4, 2024 11:50am
stunaz commented 3 months ago

@QuiiBz sorry to bother, any update on this?

QuiiBz commented 3 months ago

@QuiiBz sorry to bother, any update on this?

It's still in progress.

dariolongo-dufercodev commented 1 month ago

Any update on v2? without new middleware can't be used with auth.js (v5) Thanks!

noxify commented 1 month ago

Hi @dariolongo-dufercodev,

Have you tried to chain the middleware?

Wasn't able to find the original source, but here an example how you could do it (with authjs instead of lucia):

https://github.com/noxify/t3-turbo-lucia/tree/main/apps/nextjs/src

Maybe a workaround but should work until the new middleware is available.

dariolongo-dufercodev commented 1 month ago

Hi @noxify, this is exactly the solution i found after some research, the code is very similar, thanks! I haven't tried that yet, but I'll write results asap. Thanks

dariolongo-dufercodev commented 1 month ago

Maybe it could be easier than expected:

export default auth((req) => {
  // here is possible access to req.auth
  const isLoggedIn = !!req.auth;

  if (... apply logic here ...) {
      return NextResponse.redirect(new URL(DEFAULT_REDIRECT_HOME_URL, url));
  }
  return I18nMiddleware(req);
}