Next.js Discord

Discord Forum

How to update metadata manually after page load

Answered
Afghan Hound posted this in #help-forum
Open in Discord
Afghan HoundOP
I have an app that is basically a canvas. I can navigate different routes from the canvas, but to do so I have to not reload the page so that the canvas doesn't reload.
That said, when I change route, I need to update the metadata manually. How can I do so?
Answered by "use php"
Mark this message as a solution then
View full answer

40 Replies

What exactly are you planning on changing? Things like <title> can be passed from any component or page and they will be hoisted to the <head> element iirc. It has been some time and i might be mixing some stuff but do try and test this approach.

Updating any other meta after page load is probably useless for obvious reasons.
Afghan HoundOP
My app consist of this routing:
[locale]/[vWebsiteID]/[vSpaceID]
The vWebsiteID never changes once you access a link.
The vSpaceID changes everytime the user navigates inside the canvas.

My title for a page looks like this to put things simply:
vSpaceTitle - vWebsiteTitle - appName

The metadata is set correctly on page load since it gets updated in the generateMetadata. But when I change page, I need a way to keep the existing vWebsiteTitle - appName and prepend the new vSpaceTitle.

Long story short, I'm currently routing using this
https://nextjs.org/docs/app/building-your-application/routing/linking-and-navigating#using-the-native-history-api

since I don't want the page to reload and have to reload my canvas everytime I navigate. So that's why I cannot rely only on generateMetadata.
Can you try the suggestion i gave? Unfortunately the only suggestion i can give.
Afghan HoundOP
You mean manually changing the title tag with <Head/> ? Don't think this is supported anymore with the AppRouter.

Or you meant I could manually set it through document.title ? but it feels so out of place lol
I meant literally passing a
<title>{`Website - ${name}`}</title>
Anywhere in the component
Afghan HoundOP
hmm. But then I'd need to get the current title and replace the first portion of it..I could try
Afghan HoundOP
I'm able to overwrite it using document.title. Feels sketchy though..it'd be nice if there was a more builtin way of doing this with nextjs, since I need to manually check the existing title and find and replace a part of it
@Clown I meant literally passing a html <title>{`Website - ${name}`}</title>
In client side, document.title would be the best one
or you can export different metadata for different routes
Afghan HoundOP
Oh for sure, but I need to not reload the page to keep my canvas mounted, since this is how users are navigating
is there another way than using the history api of keeping the canvas mounted, but not reloading the page everytime the user navigates to a new route?
hold on, let me try on my system
Afghan HoundOP
oh no, it's dynamic based on the vSpaceID people visit
I think document.title is the only way then. I haven't heard of any other
Afghan HoundOP
yeah ok. Also, is there another way than using the history api of keeping the canvas mounted, but not reloading the page everytime the user navigates to a new route?

I need to navigate from page to page, without the canvas rerendering.
So only the last part (vSpaceID) would change:
[locale]/[vWebsiteID]/[vSpaceID]
Any idea?
or let me look what can be done in my lcoal system
Afghan HoundOP
Yes I tried that. Worked perfectly, but things are a bit more complex..

Here are the available routes for my app:
Renders a canvas: [locale]/[vWebsiteID]/[vSpaceID]
Renders another canvas: [locale]/[vWebsiteID]/[vSpaceID]/kioskID
Mobile only. Renders a modal-like page, just content that can be viewed in the vSpace canvas: [locale]/[vWebsiteID]/[vSpaceID]/contentItemID

The issue was that I couldn't have a layout with a canvas defined here [vWebsiteId]/layout.tsx while also having another canvas defined here [locale]/[vWebsiteID]/[vSpaceID]/[kioskID]
Also, I had to basically return null for every pages, so that they can be accessed. Which felt wrong
Afghan HoundOP
Oh it's a complete other canvas for the kioskID route. I don't want the vSpace canvas to show up at all
Afghan HoundOP
^that doesn't seem to work with the native history API 🤔
It also rerenders the page 😦
So I guess you need to use document.title only otherwise
[locale]/[vWebsiteID]/(canvas1)/layout.tsx&page.tsx
[locale]/[vWebsiteID]/[vSpaceID]/[kioskID]/layout.tsx
Afghan HoundOP
Could you explain what this does? I looked at Route groups before, and couldn't figure out how that could work for my case
So for example
login/(another)/layout.tsx
will apply to all the routes like inside
login/(another)/page.tsx
or

login/(another)/someotherRoute/page.tsx

But won't effect
login/page.tsx
Afghan HoundOP
Oh interesting. That's pretty much my use case it seems. Will give it a shot
@"use php" `[locale]/[vWebsiteID]/(canvas1)/layout.tsx&page.tsx` `[locale]/[vWebsiteID]/[vSpaceID]/[kioskID]/layout.tsx`
Afghan HoundOP
So I tried your suggestion, and it seems that in order to be able to access this route:
[locale]/[vWebsiteID]/[vSpaceID]
I need to put the (canvas1)/layout.tsx&page.tsx here:
[locale]/[vWebsiteID]/[vSpaceID]/(canvas1)/layout.tsx&page.tsx

Thing is this way everytime I navigate to another vSpaceID, the page reloads
anything in the console/
Afghan HoundOP
only this:
No default component was found for a parallel route rendered on this page. Falling back to nearest NotFound boundary.
Oh, I think I got something. This shows my canvas
So put the page inside the vSpaceID folder, but the layout in the route group
Resolved?
Afghan HoundOP
It all seems to work so far. Just testing the whole thing to make sure all is good, but it's promising! Thanks so much
@"use php" So, you can create route groups
Mark this message as a solution then
Answer