Is it still possible to declare Head elements client side when using the App Directory ? #49704
Replies: 4 comments 2 replies
-
You can! If you need dynamic head data, you can re-use a fetch call since they’re de-duped to populate page-specific meta https://nextjs.org/docs/app/building-your-application/optimizing/metadata#seo |
Beta Was this translation helpful? Give feedback.
-
I responded too quickly. You can use it in a page or layout and a page can be a client component. Just curious what need it’s filling to use it in client components specifically? |
Beta Was this translation helpful? Give feedback.
-
Not the cleanest solution, but I was able to get the tags working on 'use client'. This only works if you don't need to persist Context state as you navigate your app. You pretty much have to manually recreate the entire tree every page. The drawback is that you can't persist state in your Context Providers. // app/layout.tsx
export default function RootLayout({
children,
}: {
children: React.ReactNode
}): React.ReactNode {
return children
} // app/page.tsx
'use client'
export default function Page(): JSX.Element {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta content="width=device-width" name="viewport" />
<meta content="Root page" name="title" />
</head>
<body>
// your content
</body>
</html>
} // app/another-page/page.tsx
'use client'
export default function Page(): JSX.Element {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta content="width=device-width" name="viewport" />
<meta content="Subpage" name="title" />
</head>
<body>
// your content
</body>
</html>
} |
Beta Was this translation helpful? Give feedback.
-
I do think I found a better fitting solution for my own project, and I wanted to share in case anyone else would benefit from it. Problem Thoughts
Solution "use client";
import { useTheme } from "@/styles/themes/ThemeProvider";
import { useEffect } from "react";
const ViewportMeta = () => {
const { theme } = useTheme();
useEffect(() => {
const metaViewport = document.querySelector('meta[name="theme-color"]');
if (metaViewport) {
metaViewport.setAttribute("content", theme.palette.primary.main);
} else {
const newMetaViewport = document.createElement("meta");
newMetaViewport.name = "theme-color";
newMetaViewport.content = theme.palette.primary.main;
document.head.appendChild(newMetaViewport);
}
}, [theme]);
return null;
};
export default ViewportMeta; Which could be set in the export default async function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<head></head>
<body>
<CustomThemeProvider>
+ <ViewportMeta />
{children}
</CustomThemeProvider>
</body>
</html>
);
}
After some testing, this seem to yield the correct theme color, while also responding to theme toggling. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi all,
Now that
next/head
isn't supported in the App Directory and themetadata
object is only supported in Server Components does it mean we cannot declareHead
elements in client components anymore ?Also the
head.js
file that was introduced isn't in the docs anymore https://nextjs.org/docs/appBeta Was this translation helpful? Give feedback.
All reactions