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

fix: add missing 'use client' directive for usePathname #189

Merged
merged 1 commit into from
Feb 14, 2023
Merged

fix: add missing 'use client' directive for usePathname #189

merged 1 commit into from
Feb 14, 2023

Conversation

wxh06
Copy link
Contributor

@wxh06 wxh06 commented Feb 14, 2023

error - ./node_modules/.pnpm/next-intl@2.11.0-beta.8_next@13.1.6+react@18.2.0/node_modules/next-intl/dist/src/client/usePathname.js
ReactServerComponentsError:

You're importing a component that needs useState. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.

   ,-[./node_modules/.pnpm/next-intl@2.11.0-beta.8_next@13.1.6+react@18.2.0/node_modules/next-intl/dist/src/client/usePathname.js:1:1]
 1 | import { usePathname as useNextPathname } from 'next/navigation';
 2 | import { useEffect, useState } from 'react';
   :                     ^^^^^^^^
 3 | import getCookieLocale from './getCookieLocale';
 4 | import hasPathnamePrefixed from './hasPathnamePrefixed';
 5 | export function unlocalizePathname(pathname) {
   `----

Maybe one of these should be marked as a client entry with "use client":
  node_modules/.pnpm/next-intl@2.11.0-beta.8_next@13.1.6+react@18.2.0/node_modules/next-intl/dist/src/client/usePathname.js
  node_modules/.pnpm/next-intl@2.11.0-beta.8_next@13.1.6+react@18.2.0/node_modules/next-intl/dist/src/client/index.js
  app/[locale]/layout.tsx

Reference: https://beta.nextjs.org/docs/rendering/server-and-client-components#convention

Introduced in 68ce7db#diff-b67520fde3f77290ca84cfb11466b0d730d23909f7c67ee7150ee2888e9307b1R2

import {useEffect, useState} from 'react';

@vercel
Copy link

vercel bot commented Feb 14, 2023

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

Name Status Preview Comments Updated
next-intl ✅ Ready (Inspect) Visit Preview 💬 Add your feedback Feb 14, 2023 at 7:22AM (UTC)

@wxh06 wxh06 changed the title Add missing 'use client' directive for usePathname fix: add missing 'use client' directive for usePathname Feb 14, 2023
@amannn
Copy link
Owner

amannn commented Feb 14, 2023

Hey @wxh06,

thanks for the PR. Does this improve the error in some way?

The way I see it is that the component (or a parent) that uses usePathname needs to be marked with 'use client'; nonetheless, so this doesn't really change the result.

If the error message is better with this fix, we could add it though (or generally to next-intl/client).

@wxh06
Copy link
Contributor Author

wxh06 commented Feb 14, 2023

In fact, I had never used usePathname in my code.

The error appears when trying to import anything from next-intl/client in a server component. It works now after changing the import statement as I noticed that importing NextIntlClientProvider from next-intl/client has been deprecated:

-import { NextIntlClientProvider } from "next-intl/client";
+import { NextIntlClientProvider } from "next-intl";

I guess the import statements in index.tsx cause the problem:

import NextIntlClientProvider_ from '../shared/NextIntlClientProvider';
import usePathname from './usePathname';

@amannn
Copy link
Owner

amannn commented Feb 14, 2023

Yep, the import for NextIntlClientProvider was changed for this very reason that the /client path is only available to the client side.

I guess the import statements in index.tsx cause the problem

It's not a problem, but by design that you can't import client-only functionality on the server side.

@wxh06
Copy link
Contributor Author

wxh06 commented Feb 14, 2023

It's not a problem, but by design that you can't import client-only functionality on the server side.

I mean using NextIntlClientProvider that is imported from next-intl/client is impossible in 2.11.0-beta.8 (marked as deprecated but UNUSABLE) but still exists in the docs of current version

The code below does not work at all in 2.11.0-beta.8 as I mentioned in the description of this pr

// app/[locale]/layout.tsx

import {NextIntlClientProvider} from 'next-intl/client';
import {notFound} from 'next/navigation';

export function generateStaticParams() {
  return [{locale: 'en'}, {locale: 'de'}];
}

export default async function LocaleLayout({children, params: {locale}}) {
  let messages;
  try {
    messages = (await import(`../../messages/${locale}.json`)).default;
  } catch (error) {
    notFound();
  }

  return (
    <html lang={locale}>
      <body>
        <NextIntlClientProvider locale={locale} messages={messages}>
          {children}
        </NextIntlClientProvider>
      </body>
    </html>
  );
}

@amannn
Copy link
Owner

amannn commented Feb 14, 2023

That's a fair point! Unfortunately, I wasn't aware of a way to deprecate the old import for NextIntlClientProvider in a backward-compatible way.

I'll mark the latest beta version as a new major version and will include a note about upgrading in the documentation.

Thanks!

@wxh06
Copy link
Contributor Author

wxh06 commented Feb 14, 2023

In fact, the current approach to reserving deprecated export of NextIntlClientProvider is ineffective.
However, the error can be resolved by adding 'use client'; to the beginning of usePathname.tsx as a temporary solution.

@amannn
Copy link
Owner

amannn commented Feb 14, 2023

Oh, that's interesting, you're right! Sorry, now I finally see your point, I thought this would still print an error message! 🙂

Sounds good!

@amannn amannn merged commit a78b375 into amannn:feat/next-13-rsc Feb 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants