Next Meta Datas
Unanswered
Himalayan posted this in #help-forum
HimalayanOP
I am using nextjs app router
so I want to do this
I am going to make what is shown on the browser metadata to be meaningful.
It should show like Team , People and stuff based on the route it is on.
And when it is a specific team, it should show me something like
So I want to get the team Id from params. param.teamId gives me the id
and I have a hook that calls the api and gets me the team detail. so I want to use that and the TeamName from there.
Here is what I tried
But I am getting the following error:
so I want to do this
I am going to make what is shown on the browser metadata to be meaningful.
It should show like Team , People and stuff based on the route it is on.
And when it is a specific team, it should show me something like
Team | TeamName on the top of the browser.So I want to get the team Id from params. param.teamId gives me the id
and I have a hook that calls the api and gets me the team detail. so I want to use that and the TeamName from there.
Here is what I tried
import useTeam from 'hooks/useTeam'
import { Metadata } from 'next'
export async function generateMetadata({ params }): Promise<Metadata> {
const teamId = params.teamId
const { teamDetails } = useTeam(teamId)
return {
title: teamDetails?.name,
}
}
export default function TeamsLayout({ children }) {
return <>{children}</>
}But I am getting the following error:
You're importing a component that needs useReducer. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.
Learn more: https://nextjs.org/docs/getting-started/react-essentials18 Replies
You can't use hooks inside generateMetadata function, since it's not a client component
You may want to extract the data fetching logic from the useTeam hook into a separate function, and call that function from generateMetadata. That way you may fetch the data without using hooks
You may want to extract the data fetching logic from the useTeam hook into a separate function, and call that function from generateMetadata. That way you may fetch the data without using hooks
yeah what denexapp said, you cant use the hooks in generateMetadata as its for server, but you can use the <title> in your client function and then use the hook: https://nextjs-faq.com/metadata-client-components#how-do-i-set-dynamic-metadata-that-depends-on-client-side-states
German yellowjacket
maybe use Head?
no, head is not a thing for app dir
German yellowjacket
oh
HimalayanOP
@riský @denexapp The problem with this is it doesn't use the parent's title template.
I have this
teams ->
So that whatever is inside teams folders, I want it to use the title template
It should be
If I use <Title></Title> tag it will override everything and it just becomes
Do you have a solution for this ?
I have this
teams ->
export const metadata: Metadata = {
title: {
template: 'Teams | %s',
default: 'Teams',
},
description: ``,
}
export default function TeamsLayout({ children }) {
return <>{children}</>
}So that whatever is inside teams folders, I want it to use the title template
It should be
Teams | TeamNameIf I use <Title></Title> tag it will override everything and it just becomes
TeamNameDo you have a solution for this ?
@Himalayan the generateMetadata function accepts
parent field, which contains metadata object from a parent segment, which contains title. So you can use concat parent segment title and current segment title and return the resultActually wait, there's a better way, i just checked the docs: https://nextjs.org/docs/app/api-reference/functions/generate-metadata#title
@denexapp <@992751193774362625> the generateMetadata function accepts `parent` field, which contains metadata object from a parent segment, which contains `title`. So you can use concat parent segment title and current segment title and return the result
thats not helpfull.. the issue is they already tried something like that, but generatemetadta isnt what they want as they want client hook and generate metadata is server
@Himalayan <@657067112434499595> <@304173216828489729> The problem with this is it doesn't use the parent's title template.
I have this
teams ->
export const metadata: Metadata = {
title: {
template: 'Teams | %s',
default: 'Teams',
},
description: ``,
}
export default function TeamsLayout({ children }) {
return <>{children}</>
}
So that whatever is inside teams folders, I want it to use the title template
It should be Teams | TeamName
If I use <Title></Title> tag it will override everything and it just becomes TeamName
Do you have a solution for this ?
i think you will need to make a const somewhere and use it in both places or just duplicate
but if you have dynamic name, youd prob have to pass that from server component page to the client or smth less fancy ðŸ˜
HimalayanOP
@denexapp It will concat them by default. But only if the title is exported from the metadata object.
example
so if there are any other child layouts inside this folder, and they export a title (for example
But this won't work if I define the title of the child inside the title tag
example
export const metadata: Metadata = {
title: {
template: 'Parent | %s',
default: 'Parent | Home',
},
description: ``,
}so if there are any other child layouts inside this folder, and they export a title (for example
child) from a metadata object it will concat them by default, and return in this format: Parent | ChildBut this won't work if I define the title of the child inside the title tag
But this won't work if I define the title of the child inside the title tagyeah, thats why you have to somehow get the template to client side to use (i do wish the api was better, and i have also run into this pain)
HimalayanOP
looks like I'm in trouble
What is the best way to get the template on the client side ?
@riský
copy the code for how you work it out on layout, and put it on client
if server fetching, make server page.tsx and then do the fetch and import a client page with that prop