ix
ix

informatix

PL version Book a discovery call
Home / Blog / Inertia.js SEO Guide — SSR, Meta Tags and Core Web Vitals [2...
• 8 min read •

Inertia.js SEO Guide — SSR, Meta Tags and Core Web Vitals [2026]

Inertia.js apps can rank as well as Blade apps — with SSR, server-generated meta tags, structured data, a correct canonical and healthy Core Web Vitals. The complete SEO stack for Laravel + React.

Inertia.js SEO Guide — SSR, Meta Tags and Core Web Vitals [2026]
Web development

Inertia.js applications can rank as well as Blade applications — but only if the HTML Google receives contains the content, the meta tags and the structured data it needs. The difference between a fast, indexable Inertia app and an invisible one is usually server-side rendering, a correct <Head> setup and a sitemap. This guide covers the full SEO stack for Laravel + React + Inertia.

Key takeaway: The short version — enable SSR for public pages, render unique titles and meta descriptions with <Head>, generate structured data on the server, keep canonical and hreflang correct, submit a sitemap and protect Core Web Vitals. Client-only Inertia can be indexed, but SSR removes the risk.

How Google sees an Inertia application

The first request to an Inertia page returns a normal HTML document. Laravel renders the root Blade template with the page object embedded as JSON, and — if SSR is enabled — the React tree is rendered to HTML on the server. Googlebot receives that HTML, parses the content and follows the links.

Without SSR, the HTML contains the root element and the JSON payload, but not the rendered content. Google can execute JavaScript and render the page, but rendering is a second wave: it is slower, less reliable and competes with crawl budget. For pages that must rank, SSR is the safer default.

The same rule applies to social previews and AI crawlers: many of them do not execute JavaScript. If the title, description and Open Graph tags are generated only in React, they may never be seen.

SSR vs client-only rendering

Aspect Client-only Inertia SSR Inertia
Initial HTML Root element + JSON Full rendered HTML
First contentful paint After JS loads Before JS loads
Google indexing Possible, second wave Direct
Social previews Unreliable Reliable
Server cost Lower Node process + memory
Best for Logged-in apps, dashboards Public pages, marketing, content

A pragmatic architecture is a hybrid: Blade for marketing pages that must rank, Inertia + SSR for the product and for public content that benefits from the SPA experience. You do not have to choose one rendering model for the entire application.

Meta tags with the Head component

Inertia provides a <Head> component that renders into the document head on both the client and the server.

import { Head } from '@inertiajs/react';

export default function Pricing({ plans }) {
    return (
        <>
            <Head>
                <title>Pricing — Acme</title>
                <meta name="description" content="Simple pricing for teams of every size." />
                <link rel="canonical" href="https://example.com/pricing" />
                <meta property="og:title" content="Pricing — Acme" />
                <meta property="og:description" content="Simple pricing for teams of every size." />
                <meta property="og:type" content="website" />
            </Head>

            <main>{/* ... */}</main>
        </>
    );
}

Rules that prevent duplicate tags

  • Render <Head> once per page, not in every component.
  • Keep the root Blade <head> minimal; let the page own its title and description.
  • Use the data-inertia attribute (v3) or inertia attribute (v2) on fallback tags in the root template so Inertia can replace them.
  • Do not hard-code a title in Blade if the page also renders one — you will get duplicates.

Structured data

Generate JSON-LD on the server whenever possible. For an article, product or FAQ page, the data should describe the same content the user sees.

$jsonld = [
    '@context' => 'https://schema.org',
    '@type' => 'Article',
    'headline' => $post->title,
    'datePublished' => $post->published_at->toIso8601String(),
    'dateModified' => $post->updated_at->toIso8601String(),
    'author' => ['@type' => 'Person', 'name' => $post->author_name],
    'mainEntityOfPage' => route('posts.show', $post),
];

return Inertia::render('Posts/Show', [
    'post' => $post,
    'jsonld' => $jsonld,
]);
<Head>
    <script type="application/ld+json">
        {JSON.stringify(jsonld)}
    </script>
</Head>

Use the types that match the page: Article or BlogPosting for editorial content, Product for products, FAQPage for visible FAQs, BreadcrumbList for navigation and Organization for the company. Do not add schema for content that is not on the page.

Canonical, hreflang and sitemap

  • Canonical. Every public page should have a self-referencing canonical. If the same content is available under multiple URLs (filters, pagination, tracking parameters), canonicalize to the primary URL.
  • Hreflang. For multilingual sites, add reciprocal hreflang links for every language and an x-default. The URLs must return 200 and contain the same content.
  • Sitemap. Generate a sitemap from the database, include lastmod, and submit it in Google Search Console. Exclude noindex pages and redirects.
  • Robots. Do not block CSS or JavaScript that the page needs. Do not rely on robots.txt to hide pages — use noindex.

Core Web Vitals

Inertia apps often have good TTFB and terrible LCP because the page waits for JavaScript. The fixes are architectural

  • SSR for LCP. The largest element should be in the initial HTML, not rendered after hydration.

  • Code splitting. Load only the page chunk needed for the current route.

  • Image optimization. Use modern formats, explicit dimensions and loading="lazy" below the fold. Preload the hero image.

  • Font discipline. Preconnect to the font host, use font-display: swap and subset where possible.

  • Avoid layout shifts. Reserve space for images, ads and dynamic panels.

  • Reduce prop size. Large JSON payloads delay hydration and increase memory use.

  • Measure on mobile. Lighthouse and CrUX, not a fast desktop connection.

  • A realistic budget: LCP under 2.5 s, INP under 200 ms and CLS under 0.1 on mobile. Track it in CI with Lighthouse CI and in the field with the Chrome UX Report.

Common SEO mistakes in Inertia apps

  1. No SSR on public pages. Google can render JavaScript, but it is a second wave.
  2. Duplicate titles. The Blade fallback and the React <Head> both render a title.
  3. Meta tags only in React. Social crawlers and AI bots may never execute JavaScript.
  4. No canonical. Filters and tracking parameters create duplicates.
  5. Broken hreflang. One language links to a 404 or to a different page.
  6. Sitemap missing dynamic pages. The blog and product pages are not discovered.
  7. Client-side-only links. Use <Link> with real href values, not onClick divs.
  8. Blocking CSS/JS in robots.txt. Google cannot render the page correctly.
  9. No structured data. You lose rich result opportunities.
  10. Ignoring the SSR process. A dead SSR server silently degrades the page.

SEO checklist for an Inertia app

  • SSR enabled for public pages.
  • Unique <title> and meta description per page.
  • Self-referencing canonical.
  • Reciprocal hreflang and x-default.
  • Open Graph and Twitter tags with an image.
  • JSON-LD for the page type.
  • Sitemap generated from the database and submitted.
  • robots.txt allows CSS/JS and points to the sitemap.
  • Semantic headings (one H1, logical H2/H3).
  • Real <a href> links for navigation.
  • Image alt text and dimensions.
  • LCP, INP and CLS within budget.
  • SSR process monitored and restarted on deploy.
  • URL Inspection shows the rendered content.

FAQ

Can Google index an Inertia.js app?

Yes. Google can render JavaScript, but SSR makes indexing faster and more reliable. For competitive pages, use SSR.

Is Inertia.js SEO friendly?

It can be, with SSR and server-generated meta tags. Without SSR, the page depends on Google's JavaScript rendering, which is a risk.

Do I need SSR for SEO?

Not strictly, but it is strongly recommended for public pages. Logged-in dashboards do not need SSR for SEO; marketing pages do.

How do I add meta tags in Inertia?

Use the <Head> component in React and @inertiaHead in the root Blade template. For SSR, the tags are rendered on the server.

How do I add structured data?

Generate JSON-LD in Laravel and render it inside <Head>. Keep it consistent with the visible content.

Does Inertia support hreflang?

Yes. Add <link rel="alternate" hreflang="..."> tags in <Head> or in the root Blade template. Keep them reciprocal.

How do I generate a sitemap?

Query published pages in Laravel, render XML with lastmod, and submit the URL in Google Search Console. Exclude noindex pages.

Why is my Inertia page slow?

Usually oversized props, a large JavaScript bundle, missing code splitting or a dead SSR process. Measure with Lighthouse and Laravel Pulse.

Sources


Need an SEO audit of your Inertia.js application? Check our Laravel development services or hire a Laravel developer.

Read more: Inertia.js with Laravel and React, Inertia.js SSR with Laravel, Inertia.js performance optimization and Laravel performance optimization.

KS

Krzysztof Słonina

Full stack developer and owner of Inoventis Solutions (informatix). Since 2009 he has built Laravel/PHP web applications, e-commerce integrations and process automations — including OneCRMApp and FamilyTimelineApp, both running on Laravel, React and Inertia.js.

About the author

Related posts