Page SEO
Weaverse Studio lets merchants edit per-page SEO metadata (title, description, canonical, robots, Open Graph, Twitter card, JSON-LD) on every Weaverse page. To render those tags on the storefront, your theme needs to forwardweaverseData to a single helper — getWeaverseSeoMeta — from a meta export.
This guide explains where to wire the helper, how it interacts with code-defined SEO, and how to clean up any legacy override layer. It is written so you can apply it to any Hydrogen theme without prior knowledge of the file layout.
What changes on the storefront? Each Weaverse-served route exports meta that returns the SEO tags configured in Studio. Pages without SEO configured fall through silently (no overrides).
Prerequisites
@weaverse/hydrogen>= 5.14.0 (the version that introducedgetWeaverseSeoMeta).- A Hydrogen route that loads a Weaverse page via
context.weaverse.loadPage(...).
TL;DR
In every route that loads a Weaverse page, exportmeta like this:
getWeaverseSeoMeta reads the SEO record embedded in the loaded page and returns the meta-tag array that React Router’s meta export expects. If the page has no SEO configured, it returns a minimal robots: index,follow descriptor — safe to call unconditionally.
The rest of this guide covers three real-world patterns and the cleanup steps you typically need.
Where to wire it
You wiregetWeaverseSeoMeta into every route whose loader calls context.weaverse.loadPage(...). In a typical theme that means two routes you must both wire: the catch-all that serves custom pages and the home/index route. A third recipe — template routes — is an optional supplement.
The two required recipes are independent of each other; the route file determines which one applies. Together they make Studio-edited SEO apply across the homepage and every custom page, with code-defined SEO (e.g. seoPayload.home()) filling in any field a merchant leaves blank.
Catch-all route — CUSTOM pages
Most themes have a catch-all route that resolves any unmatched URL into a Weaverse CUSTOM page. Typical filenames:routes/catch-all.tsx, routes/($locale).$.tsx, routes/$.tsx. If your catch-all currently has no meta export, add one.
Before
Home / index route — INDEX (and root-level CUSTOM)
Many themes serve both the real homepage (type: "INDEX") and root-level CUSTOM handles from the same _index / locale-index route. If Weaverse Studio has SEO configured for the homepage, the theme should apply the Weaverse SEO settings; otherwise, it should fall back to the code-defined SEO (seoPayload.home()).
Skipping this pattern? Studio’s SEO Manager lets merchants edit homepage SEO regardless of theme wiring. If you don’t wire this pattern, any title / description / OG image a merchant sets for the homepage will silently have no effect on the storefront. Either wire it, or surface that limitation in your team’s onboarding so merchants don’t waste time configuring fields that won’t apply.Loader — compute
seo only for INDEX, leave it null for CUSTOM, and return both weaverseData and seo:
seo:
Template routes — optional supplement (product, collection, blog, page)
Routes for Shopify resources (product, collection, blog, article, Shopify pages) typically build their SEO from the Shopify payload viaseoPayload.product(...), seoPayload.collection(...), etc. Leave those as-is. For templates, Shopify-driven SEO already covers the resource-specific fields (including structured JSON-LD with price, availability, ratings, etc.) that Weaverse Studio does not surface today.
If you want Weaverse SEO to supplement template routes: AddgetWeaverseSeoMetato the template’smetaexport and append it after the Shopify tags, not replace them. Avoid concatenating arrays naively — duplicate<meta name="description">tags can confuse crawlers. The safest pattern is to let Shopify SEO win and only pull in Weaverse tags that are absent from the Shopify payload (e.g. a customrobotsoverride or extra OG fields).
Step-by-step: applying this to a theme
- Bump the SDK to
@weaverse/hydrogen@^5.14.0and reinstall. - Locate every route that calls
context.weaverse.loadPage(...)—grep -rln "weaverse.loadPage" app/routes. - For each, match it to the matching recipe above (catch-all, home/index, or — optionally — template) and apply it.
- Remove legacy overrides (see next section), if any.
- Run
typecheckandbuild. Fix anyerrorComponentregression caused by the SDK bump (see SDK 5.14 side effect). - Smoke test: open a Weaverse page in Studio, set a Title and Description, save, view source on the storefront URL. The tags should appear.
Removing a legacy override layer
Some themes shipped a hardcoded SEO override config to brand custom pages before Studio could edit SEO. Typical signatures:- A file like
app/.server/seo-overrides.ts,app/utils/seo-overrides.ts, or similar, with a hardcodedRecord<string, { title, description }>. - A helper like
seoPayload.customPage({ url })that maps the URL to one of those overrides. - A route that does
seoPayload.customPage({ url: request.url })and returns it in the loader.
- Delete the override file (e.g.
seo-overrides.ts). - Remove
customPagefrom your SEO payload module — both the function and its export. - Update routes that called
seoPayload.customPage({ url: request.url })— replace with themetaexport pattern above. The loader no longer needsrequestfor SEO purposes.
Why remove it? Studio-edited SEO is per-page and merchant-controlled. A static override would silently shadow whatever the merchant configures in Studio.
SDK 5.14 side effect: errorComponent prop type
@weaverse/hydrogen 5.14 narrowed WeaverseHydrogenRoot’s errorComponent prop to React.FC<{ error: unknown }>. If your theme passes a custom error component typed as { error?: { message; stack? } }, TypeScript will now complain. The fix is to accept unknown and narrow at runtime:
.stack or other fields off the error.
Verification checklist
-
@weaverse/hydrogenis at^5.14.0(or newer) inpackage.jsonand the installednode_modulesversion matches. - Every route that loads a Weaverse page exports a
metafunction returninggetWeaverseSeoMeta(data?.weaverseData)(or branches per the home/index recipe). - Any legacy
seo-overrides.ts/customPagehelper is deleted. -
typecheckpasses (or only flags pre-existing, unrelated errors). -
buildsucceeds. - Setting a Title/Description in Studio is reflected in the storefront’s
<head>for that page.