How to set a different meta tag in the head depending on the page
I would like to create some sort of dynamic open graph tags.
I will briefly explain the use case to make it obvious: I've got a webapp to generate action figures. I want people to share their action figures in URLs like this (https://tufiguradeaccion.com/guest-figure/8258a638-0416-4b62-a720-1e116d004d5a) and for them to see the Open Graph tags with the action figure as the image.
I've been researching and I've found that there is no support for SSG. I understand ... I was wondering if there is any workaround or something I can do. I hear the approach is to use "react-helmet-async" but I don't know how to start ... is there any sample repo where I can get inspiration from?
Thanks in advance.
Further details:
- Wasp version: 0.16.3
- Platform: MacOS
Tu figura de acción
🦾 Crea tu figura de acción personalizada en segundos
15 Replies
Hi @kessius85. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
You're right that Wasp doesn't currently have built-in support for SSG or dynamic meta tags in the
head
section of your app. However, there is a workaround using React Helmet that's recommended by the Wasp team.
Current State of SEO in Wasp
Wasp allows you to set static meta tags in the head
section of your main.wasp
file, but these are global and not dynamic per page GitHub Issue #1910. For your use case of having different Open Graph tags for each action figure page, you'll need a client-side solution.
Recommended Workaround
As you mentioned, the recommended approach is to use react-helmet-async
. Here's how you can implement it:
1. Install react-helmet-async
in your project
2. Use Wasp's rootComponent
to set up the Helmet provider
3. Create dynamic meta tags in your specific pages/components
The Wasp team specifically recommends this approach for your exact use case:
"In the meantime, solution might be https://github.com/nfl/react-helmet -> it allows you to set head directly from React. I see it is not currently maintained but allegedly this fork is https://github.com/staylor/react-helmet-async. And to set it in just one place, you can use Wasp's rootComponent
https://wasp-lang.dev/docs/project/client-config#defining-a-common-layout." Discord Support Thread
Example Implementation
For inspiration, you can look at CoverLetterGPT, an open-source Wasp app that has good SEO despite not using SSR. The developer mentions:
"Wasp allows you to add OG tags in theYou can check out their implementation here: CoverLetterGPT GitHub Future Plans The Wasp team is aware of this limitation and has open issues to address both SSR/SSG and dynamic meta tags: - Issue #911 for SSR/SSG - Issue #1786 for environment-specific values in meta tags Additional SEO Notes It's worth noting that even without SSR, you can still achieve good SEO results with Wasp:head
property of themain.wasp
file" Discord Support Thread
"A lot of hype around needing SSR for good SEO is exaggerated... Google is very good at scraping websites, and even does so with JS activated." Discord Support ThreadThe CoverLetterGPT app mentioned above ranks well in Google searches despite not using SSR or a separate landing page. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @kessius85, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
I've been looking at how to implement "react-helmet-async" and didn't manage ... I will tell you what I did and you tell me what's missing.
I did:
* install react-helmet-async
* (Layout.jsx) import { HelmetProvider } from "react-helmet-async"; // and added the <HelmetProvider> tag
* (DynamicPage.jsx) import { Helmet } from 'react-helmet-async'; // and added the <Helmet> tag and the dynamic tags inside
Summary:
We installed the react-helmet-async library to handle dynamic metadata in the React component.
We modified the Layout.jsx component to wrap the entire app with the HelmetProvider, which allows child components to use Helmet to manipulate head tags.
We implemented Helmet in the GuestFigureDetail.jsx component, where:
We imported the Helmet component from react-helmet-async
We created variables for the dynamic metadata based on the current figure
We added the dynamic OG tags inside the Helmet component in the render
We included metadata for Facebook and Twitter
This is how my "main.wasp" client part looks like:
Two questiosn:
1. Do I need to remove the "head" tags from the main.wasp to make the react-helmet-async work?
2. What am I missing?
@kapa.ai can you help me?
Let me check the knowledge base for you again. One moment! :books:
Wohooo @kessius85, you just became a Waspeteer level 1!
----------------------
I'd be happy to help you with your Wasp project! However, your question is quite general. Based on our previous conversation, I understand you're working on implementing dynamic Open Graph tags for your action figure web app.
To help you more effectively, could you please specify what aspect you need help with? For example:
1. Setting up react-helmet-async in your Wasp project
2. Implementing dynamic OG tags for your action figure pages
3. Understanding how to use Wasp's rootComponent for this purpose
4. Something else related to your Wasp implementation
With more details, I can provide you with more specific guidance for your use case.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------
Sorry @kessius85, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist:
Perhaps try again in 15mins?
Hey @kessius85 what meta-tags are you trying to show?
I'm trying to set up the OG tags (Open Graph)
I'm specially interested in making this viralizable, so if I share the URL the small image is displayed
Tu figura de acción
🦾 Crea tu figura de acción personalizada en segundos
@kapa.ai I'm interested to know how to setup react-helmet-async
Let me check the knowledge base for you again. One moment! :books:
@NEROX do you know if there is any sample project or reference that I look at?
----------------------
I'd be happy to help you set up react-helmet-async in your Wasp project. Based on the knowledge sources, here's how you can implement it:
Setting up react-helmet-async in Wasp
1. First, install the package in your Wasp project:
2. Create a root component that will wrap your entire application with the HelmetProvider. You can do this by creating a file like
src/RootComponent.jsx
(or .tsx
if using TypeScript):
3. Configure this as your root component in your main.wasp
file:
4. Now you can use the Helmet component in any of your page components to set dynamic meta tags. For example, in your action figure detail page:
This approach allows you to dynamically set different meta tags for each page based on the data you have for that specific action figure. The Helmet component will inject these tags into the document head at runtime.
The Wasp team specifically recommends this approach as a workaround until they implement native support for dynamic meta tags in the future Discord Support Thread.
Is there anything specific about the implementation you'd like me to explain further?
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------
Sorry @kessius85, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist:
Perhaps try again in 15mins?hm I understand, it's currently not possible as it's SPA.
react-helmet-async
is a good solution to handle SEO but not perfect:
- The head of main.wasp
is rendered only in the initial HTML, and then React only manipulates the DOM, but generally (with the exception of Google and some other) bots/crawlers (Linkedin, Facebook, Twitter, etc. ) usually only read the initial HTML, not the DOM modified by JS.
- react-helmet-async
only changes the head in the browser DOM, but not in the HTML that the bots/crawlers receive, unless you use SSR (Server Side Rendering), which Wasp doesn't support yet.
So, even if you change the <meta property="og:image" ...>
with Helmet, the bots only see the one in the initial HTML (the one in main.wasp).One solution (external to Wasp) is to use some pre-render service (prerender as an example) or any Open-Source.
They act as middleware/proxy between your app and the bots/crawlers.
When a bot (Google, Facebook, Twitter, etc.) requests a page from your SPA, Prerender launches a headless browser (like Puppeteer/Chrome), loads your app, waits for the JS to run and the DOM to update (including React Helmet changes), and then returns the rendered HTML to the bot.
For normal users, the app works as usual (SPA).
But as I said at the beginning, as of today it's not possible with Wasp.
Prerender
Prerender Seamlessly Renders JavaScript for Faster Indexing
Get higher rankings by serving search engine crawlers a static HTML version of your JavaScript website without compromising your customers’ experience.
thanks a lot, @NEROX 🙂 ! appreciate your explanation ❤️ !