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

feat!: Next.js 13 RSC integration #149

Merged
merged 378 commits into from
Nov 14, 2023
Merged

feat!: Next.js 13 RSC integration #149

merged 378 commits into from
Nov 14, 2023

Conversation

amannn
Copy link
Owner

@amannn amannn commented Dec 8, 2022

→ Please refer to the announcement


Fixes #488
Fixes #402
Fixes #578

@vercel
Copy link

vercel bot commented Dec 8, 2022

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

Name Status Preview Comments Updated (UTC)
example-next-13-next-auth ✅ Ready (Inspect) Visit Preview 💬 Add feedback Nov 14, 2023 2:37pm
next-intl ✅ Ready (Inspect) Visit Preview 💬 Add feedback Nov 14, 2023 2:37pm
next-intl-docs ✅ Ready (Inspect) Visit Preview 10 resolved Nov 14, 2023 2:37pm
next-intl-example-next-13 ✅ Ready (Inspect) Visit Preview 💬 Add feedback Nov 14, 2023 2:37pm
next-intl-examples-next-13 ✅ Ready (Inspect) Visit Preview 💬 Add feedback Nov 14, 2023 2:37pm

@amannn amannn mentioned this pull request Dec 8, 2022
11 tasks
@amannn amannn changed the title feat: Next.js 13 RSC integration feat!: Next.js 13 RSC integration Dec 8, 2022
@amannn amannn changed the title feat!: Next.js 13 RSC integration feat: Next.js 13 RSC integration Dec 8, 2022
Base automatically changed from feat/next-13-minimum to main December 9, 2022 19:43
@amannn amannn changed the title feat: Next.js 13 RSC integration feat!: Next.js 13 RSC integration Nov 14, 2023
@Morishiri
Copy link

@Morishiri Your call site of Link doesn't seem right.

This should work:

import {Link} from '../navigation';

<Link href={{
  pathname: '/gallery/[photoId]',
  params: {photoId: photo.id}
}}>
  Gallery
</Link>

See the navigation docs about Link.

I tried that and it causes the same error. Looks like next is no longer accepting this syntax. If you go trough the docs their propose (https://nextjs.org/docs/messages/app-dir-dynamic-href ) they recommend exactly the opposite.

@amannn
Copy link
Owner Author

amannn commented Nov 14, 2023

@Morishiri Can you share a reproduction? In this branch, we have both an app example with this syntax as well as an extensive unit test suite for the navigation APIs. Both use [email protected].

My guess would be that either the wrong Link is used or photoId was not provided.

@Morishiri
Copy link

@amannn Found the issue!

I had the LocaleLink rendered on every page dynamically with the same path as current, but different locale.

When I landed on /en/gallery/[photoId] that was the pathname which I was providing to link:

export const LocaleLink = ({ switchToLocale, title }: LocaleLinkProps) => {
  const pathname = usePathname();
  const locale = useLocale();

  return (
    <Link
      href={pathname}
      locale={switchToLocale}
      title={title}
    >
      {switchToLocale}
    </Link>
  );
};

I changed it to


export const LocaleLink = ({ switchToLocale, title }: LocaleLinkProps) => {
  const pathname = usePathname();
  const params = useParams();
  const locale = useLocale();

  return (
    <Link
      // @ts-expect-error
      href={{ pathname, params }}
      locale={switchToLocale}
      title={title}
    >
      {switchToLocale}
    </Link>
  );
};

and it works now. Thanks for the pointer!

@Tomekmularczyk
Copy link

Tomekmularczyk commented Nov 14, 2023

Hey, I'm using Next 14.0.1, I updated next-intl from rc-6 to rc-10 and now I'm getting this error:

./src/app/[locale]/event/[slug]/page.tsx
 ✓ Compiled /[locale]/[...rest]/page in 13.6s (11099 modules)
 ⨯ node_modules/next-intl/dist/esm/server/RequestLocale.js (1:609) @ eval
 ⨯ Error: Unable to find `next-intl` locale because the middleware didn't run on this request. See https://next-intl-docs.vercel.app/docs/routing/middleware#unable-to-find-locale
    at RootLayout (./src/app/[locale]/layout.tsx:48:74)
    at AsyncLocalStorage.run (node:async_hooks:338:14)
    at Object.apply (./src/app/[locale]/layout.tsx:139:10)
    at async Promise.all (index 0)
null
 ⚠ Fast Refresh had to perform a full reload due to a runtime error.
 ⨯ node_modules/next-intl/dist/esm/server/RequestLocale.js (1:609) @ eval
 ⨯ Error: Unable to find `next-intl` locale because the middleware didn't run on this request. See https://next-intl-docs.vercel.app/docs/routing/middleware#unable-to-find-locale
    at RootLayout (./src/app/[locale]/layout.tsx:48:74)
    at AsyncLocalStorage.run (node:async_hooks:338:14)
    at Object.apply (./src/app/[locale]/layout.tsx:139:10)
    at async Promise.all (index 0)
digest: "1556311853"

the other time:

✓ Compiled /not-found in 5s (11107 modules)
 ✓ Compiled (11093 modules)
 ⚠ Fast Refresh had to perform a full reload. Read more: https://nextjs.org/docs/messages/fast-refresh-reload
 ⨯ node_modules/next-intl/dist/esm/server/RequestLocale.js (1:609) @ eval
 ⨯ Error: Unable to find `next-intl` locale because the middleware didn't run on this request. See https://next-intl-docs.vercel.app/docs/routing/middleware#unable-to-find-locale
    at RootLayout (./src/app/[locale]/layout.tsx:48:74)
    at AsyncLocalStorage.run (node:async_hooks:338:14)
    at Object.apply (./src/app/[locale]/layout.tsx:139:10)
    at async Promise.all (index 0)
null
 ⨯ node_modules/next-intl/dist/esm/server/RequestLocale.js (1:609) @ eval
 ⨯ Error: Unable to find `next-intl` locale because the middleware didn't run on this request. See https://next-intl-docs.vercel.app/docs/routing/middleware#unable-to-find-locale
    at RootLayout (./src/app/[locale]/layout.tsx:48:74)
    at AsyncLocalStorage.run (node:async_hooks:338:14)
    at Object.apply (./src/app/[locale]/layout.tsx:139:10)
    at async Promise.all (index 0)
digest: "1556311853"
null

It doesn't happen immediately, it seems that it happens when there's a compilation error, and then you fix it. Do you have any idea how to fix this error?

EDIT, it's been happening on rc-6 as well

@amannn
Copy link
Owner Author

amannn commented Nov 14, 2023

@Tomekmularczyk Can you share a reproduction? (template)

Please also check the relevant troubleshooting section in the docs.

@sFritsch09
Copy link

@Tomekmularczyk Can you also check the following:

  1. Structure should be like this in your next app:
  • app
    - [locale]
    - layout.js
    - page.js
    - ...
    • layout.js
    • not-found.js
    • ...
  • middleware.js
  • navigation.js
  • messages
  1. try to delete .next folder after stopping server and rerun
  2. check your config inside middleware.js|ts:
    export const config = { // Skip all paths that should not be internationalized. This example skips the // folders "api", "_next" and all files with an extension (e.g. favicon.ico) matcher: ['/((?!api|_next|.*\\..*).*)'], matcher: ['/', '/(de|en)/:path*'], };

@Tomekmularczyk
Copy link

Tomekmularczyk commented Nov 14, 2023

@Tomekmularczyk Can you also check the following:

  1. Structure should be like this in your next app:
  • app

    • [locale]
    • layout.js
    • page.js
    • ...
    • layout.js
    • not-found.js
    • ...
  • middleware.js

  • navigation.js

  • messages

  1. try to delete .next folder after stopping server and rerun
  2. check your config inside middleware.js|ts:
    export const config = { // Skip all paths that should not be internationalized. This example skips the // folders "api", "_next" and all files with an extension (e.g. favicon.ico) matcher: ['/((?!api|_next|.*\\..*).*)'], matcher: ['/', '/(de|en)/:path*'], };

Hi, the directory structure is pretty much the same:
image

I tried deleting node_modules, .next and installing everything again.

export const config = {
  // Skip all paths that aren't pages that you'd like to internationalize
  matcher: ["/((?!api|_next|_vercel|.*\\..*).*)"],
};

It kind of seems that when /[locale]/[...rest]/page is compiled then it happens. Could be unrelated.

I cannot reproduce it on fresh repo.

@Tomekmularczyk
Copy link

Hey, I'm using Next 14.0.1, I updated next-intl from rc-6 to rc-10 and now I'm getting this error:

./src/app/[locale]/event/[slug]/page.tsx
 ✓ Compiled /[locale]/[...rest]/page in 13.6s (11099 modules)
 ⨯ node_modules/next-intl/dist/esm/server/RequestLocale.js (1:609) @ eval
 ⨯ Error: Unable to find `next-intl` locale because the middleware didn't run on this request. See https://next-intl-docs.vercel.app/docs/routing/middleware#unable-to-find-locale
    at RootLayout (./src/app/[locale]/layout.tsx:48:74)
    at AsyncLocalStorage.run (node:async_hooks:338:14)
    at Object.apply (./src/app/[locale]/layout.tsx:139:10)
    at async Promise.all (index 0)
null
 ⚠ Fast Refresh had to perform a full reload due to a runtime error.
 ⨯ node_modules/next-intl/dist/esm/server/RequestLocale.js (1:609) @ eval
 ⨯ Error: Unable to find `next-intl` locale because the middleware didn't run on this request. See https://next-intl-docs.vercel.app/docs/routing/middleware#unable-to-find-locale
    at RootLayout (./src/app/[locale]/layout.tsx:48:74)
    at AsyncLocalStorage.run (node:async_hooks:338:14)
    at Object.apply (./src/app/[locale]/layout.tsx:139:10)
    at async Promise.all (index 0)
digest: "1556311853"

the other time:

✓ Compiled /not-found in 5s (11107 modules)
 ✓ Compiled (11093 modules)
 ⚠ Fast Refresh had to perform a full reload. Read more: https://nextjs.org/docs/messages/fast-refresh-reload
 ⨯ node_modules/next-intl/dist/esm/server/RequestLocale.js (1:609) @ eval
 ⨯ Error: Unable to find `next-intl` locale because the middleware didn't run on this request. See https://next-intl-docs.vercel.app/docs/routing/middleware#unable-to-find-locale
    at RootLayout (./src/app/[locale]/layout.tsx:48:74)
    at AsyncLocalStorage.run (node:async_hooks:338:14)
    at Object.apply (./src/app/[locale]/layout.tsx:139:10)
    at async Promise.all (index 0)
null
 ⨯ node_modules/next-intl/dist/esm/server/RequestLocale.js (1:609) @ eval
 ⨯ Error: Unable to find `next-intl` locale because the middleware didn't run on this request. See https://next-intl-docs.vercel.app/docs/routing/middleware#unable-to-find-locale
    at RootLayout (./src/app/[locale]/layout.tsx:48:74)
    at AsyncLocalStorage.run (node:async_hooks:338:14)
    at Object.apply (./src/app/[locale]/layout.tsx:139:10)
    at async Promise.all (index 0)
digest: "1556311853"
null

It doesn't happen immediately, it seems that it happens when there's a compilation error, and then you fix it. Do you have any idea how to fix this error?

Actually, it's been happening on rc-6 for me, I just did not notice it...

**Changes:**
- [Set hreflang on
Link](dc91509)
- [Throw for missing params in localized
pathnames](00f0998)
- [Remove
deprecations](967f903)
@amannn
Copy link
Owner Author

amannn commented Nov 14, 2023

@Tomekmularczyk

export const config = {
  // Skip all paths that aren't pages that you'd like to internationalize
  matcher: ["/((?!api|_next|_vercel|.*\\..*).*)"],
};

It kind of seems that when /[locale]/[...rest]/page is compiled then it happens. Could be unrelated.

Maybe this section from the docs is relevant for you: Pathnames without a locale prefix.

If you find that the issue is caused by next-intl, please open a new issue—because … 🥁🥁🥁 … this PR is about to get merged!

@amannn amannn merged commit 50cf6bb into main Nov 14, 2023
5 checks passed
@amannn amannn deleted the feat/next-13-rsc branch November 14, 2023 14:50
@amannn
Copy link
Owner Author

amannn commented Nov 14, 2023

meme

Thank you SO MUCH to everyone who has participated in this crazy pull request. Felt almost surreal to finally push that big, green merge button after a year of exploration and iteration on this topic.

All the feedback, code contributions, and testing from everyone who collaborated on this pull request made all the difference on what ended up as the RSC integration of next-intl. I think the result is pretty cool.

If you find something that hasn't been covered so far, please open a new discussion or issue!

See also:

Announcement on Twitter
Announcement blog post

@Tomekmularczyk

This comment was marked as resolved.

@amannn

This comment was marked as resolved.

Repository owner locked as resolved and limited conversation to collaborators Nov 14, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet