Table of Contents

SEO Meta Tags in Next.js App not showing in Page Source

Solving the Mystery: Why Dynamic SEO Meta Tags Don't Appear in Next.js Page Source As a senior developer working with dynamic applications built on Next.js,...

2026-08-10

Solving the Mystery: Why Dynamic SEO Meta Tags Don't Appear in Next.js Page Source

As a senior developer working with dynamic applications built on Next.js, you often run into subtle but frustrating issues concerning Server-Side Rendering (SSR), Client-Side Rendering (CSR), and how metadata is exposed to the browser. The specific problem you are facing—where dynamically generated SEO meta tags disappear from the page source unless added through specific methods like _document.tsx—is a classic challenge in modern React frameworks.

This post will dive deep into why this happens, analyze your approach using GraphQL and Next.js, and provide a robust solution for ensuring your dynamic SEO information is correctly rendered and visible in the final HTML source code.


The SSR vs. CSR Metadata Paradox

The core of your issue lies in the fundamental difference between how Next.js renders content on the server versus the client. When you use components that rely solely on client-side data fetching (CSR), the initial HTML payload might not contain all the necessary SEO information, as this data is only populated after JavaScript executes in the browser.

The <head> section of your document is what search engine crawlers and browsers read first to understand the page context. If you inject dynamic content into this head using client-side logic alone, it often gets lost or rendered too late for the initial source snapshot.

When you correctly use getServerSideProps or getStaticProps, Next.js ensures that the data fetching and component rendering happen entirely on the server before the HTML is sent to the client. This process effectively pre-renders the metadata into the static HTML, making it visible in the page source.

Analyzing Your Approach with GraphQL and Next.js

You are using advanced techniques like graphql-codegen-next-ssr to pre-render your data via SSR. This is the correct architectural direction for SEO-critical content. However, the visibility issue suggests that while the data is being fetched on the server, the mechanism used to inject it into the document structure might be bypassed or incorrectly applied within a component context.

Let's look at your example code snippet:

// Inside your component rendering logic
  <Head>
    <title>
      Apex Blogs | {props?.data?.blogs?.data[0]?.attributes?.title}
    </title>
    <meta property="og:title" content={props?.data?.blogs?.data[0].attributes?.title} />
    {/* ... other meta tags */}
  </Head>
  

When you place these tags inside a component that renders dynamically based on props fetched via getStaticProps, Next.js should include them in the final SSR output. If they are still missing from the raw page source, it often points to one of two scenarios:

  1. Misplacement: The metadata is being conditionally rendered in a way that the server doesn't register it as part of the main document head structure.
  2. Next.js Metadata API Overriding: Next.js prefers using its built-in metadata object (or generateMetadata function in the App Router) for static SEO data, and injecting custom tags directly into <Head> can sometimes cause conflicts or be ignored if not handled carefully within the SSR context.

Best Practice: Mastering Server-Side Metadata Injection

To guarantee that your dynamic meta tags are visible in the page source, you must ensure they are generated during the server rendering phase.

1. Leverage getServerSideProps for Full Control

Since you are already using it, focus on ensuring all necessary data is resolved within this function and passed down to the component. The key is that the component receiving these props is the one responsible for outputting the <Head> tags based on that server-fetched data.

2. Consider Next.js Metadata API (The Modern Way)

For most standard SEO elements (title, description, og:image), the recommended and cleanest way in modern Next.js applications is to use the built-in metadata export, especially if you are using the Pages Router or the App Router's dynamic metadata functions. This gives search engines a direct signal without relying solely on injecting HTML tags within components.

If you need highly complex, dynamic data that changes per page, you can still combine both methods: use generateMetadata for static parts and handle dynamic, external API-driven details via server-side calls within your component structure.

3. Architectural Consistency (The Laravel Mindset)

Think about how data flows in a robust application architecture—like the principles underpinning frameworks such as those used in the Laravel ecosystem. Data should be validated, fetched on the server, and then rendered synchronously. Ensure that the process from database query $\rightarrow$ GraphQL fetch $\rightarrow$ component rendering $\rightarrow$ HTML output is unbroken on the server side. This consistency prevents data being lost between the server context and the final output stream.

Conclusion

The lack of visibility in the page source for dynamic meta tags is rarely an issue with client-side rendering itself; it is almost always a failure in ensuring that the necessary data is synchronously included during the initial Server-Side Rendering phase. By strictly adhering to SSR patterns—leveraging getServerSideProps or Next.js's metadata functions to pre-render all SEO information before the HTML is sent—you ensure that crawlers and browsers see the complete, correct picture of your content. Focus on server-side data resolution first, and the visibility issue will resolve itself.

Stefan

Stefan

SEO engineer and Laravel developer. Building tools to help Laravel applications rank higher in search results.

Share this article

Back to Blog