next.js
next.js copied to clipboard
Next.js 13: Client side navigation does not update head
Verify canary release
- [X] I verified that the issue exists in the latest Next.js canary release
Provide environment information
Operating System:
Platform: darwin
Arch: x64
Version: Darwin Kernel Version 21.6.0: Mon Aug 22 20:17:10 PDT 2022; root:xnu-8020.140.49~2/RELEASE_X86_64
Binaries:
Node: 16.18.0
npm: 8.19.2
Yarn: 1.22.19
pnpm: 7.13.5
Relevant packages:
next: 13.0.2-canary.2
eslint-config-next: 13.0.0
react: 18.2.0
react-dom: 18.2.0
What browser are you using? (if relevant)
Bug present in all browsers
How are you deploying your application? (if relevant)
Local and Vercel
Describe the Bug
On client side navigation, head.tsx
is not updating the DOM. Works fine when you force a refresh.
Using the current file structure:
├── posts
│ └── [id]
│ ├── head.tsx
│ └── page.tsx
├── head.tsx
├── layout.tsx
└── page.tsx
See repo at: https://github.com/shadcn/next-debug-head
Expected Behavior
Expected the <title />
tag to be updated on client side navigation.
Link to reproduction
https://next-debug-head.vercel.app
To Reproduce
- Click on Post one. Check the title.
- Refresh the page. Check the title again.
OK looks like a known issue. I just found the following in the docs:
Warning: Currently, the Head export does not re-render on client-side transitions, only on > initial render. To work around this for
, you can use a client component with > useEffect that updates document.title. This will be fixed soon in a future release.
https://beta.nextjs.org/docs/api-reference/file-conventions/head
can you impl the workaround?
So far this is what I've been using. Hope it helps.
// ./components/TitleUpdater.tsx
"use client";
import { useEffect } from "react";
const TitleUpdater = ({ title }: { title: string }) => {
useEffect(() => {
document.title = title;
});
return null;
};
export default TitleUpdater;
And you just place it on any of your pages passing in the title like so
// ./app/[userId]/page.tsx
import TitleUpdater from '../../components/TitleUpdater.tsx';
const getUser = async (userId: string) => {...}; // call to api to get user data
const UserPage = async ({ params }: UserPageProps) => {
const { userId } = params;
const { name }: UserType = await getUser(userId);
const title = `${name} • Your website`;
return (
<>
<TitleUpdater title={title} />
<main>
// your page content
</main>
</>
);
}
export default UserPage;
You should still use the new head
file if you want the title to be picked up on first render by the server since the update is triggered only on client side.
meta is also not update. is a way to update it ?
13.0.4 solve the problem
Confirmed. Fixed by https://github.com/vercel/next.js/pull/42904. Closing this. Thanks everyone.
This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.