SEO Support

Wix-managed headless projects can serve the same SEO tags that the Wix platform generates for a site's business solutions — titles, meta descriptions, canonical links, Open Graph and Twitter tags, and structured data — so that SEO settings a site owner edits in the Wix dashboard reach your custom frontend. This guide shows how to wire SEO support into dynamic pages for Wix business solutions such as Wix Stores, Wix Bookings, Wix Events, and Wix Blog.

Note: This guide assumes an Astro project created with the Wix CLI. The same two APIs (@wix/astro-pages and @wix/astro) apply to any Wix-managed headless frontend.

How it works

SEO support for a dynamic page has two independent parts. You need both for full coverage:

  1. Page registration — a wixMetadata export on each dynamic route. The @wix/astro-pages integration reads these exports and exposes them at a /_wix/pages.json endpoint that enumerates every page in your project. Wix platform services use this to:

    • Generate server-side sitemap entries for your dynamic URLs.
    • Power the dashboard SEO editor (for example, "Edit SEO for Product pages"), so the owner's edits map back to the right route.
    • Resolve deep links from dashboard, email, and analytics surfaces to the correct headless URL.
  2. Tag rendering — at request time, fetch the Wix-resolved SEO tags for the specific item with loadSEOTagsServiceConfig() and render them into the page <head> with the <SEO.Tags> component. This is what puts the owner's dashboard SEO edits onto the live page.

wixMetadata registers the route with the platform; <SEO.Tags> renders the tags for a specific item. A page that exports wixMetadata but never mounts <SEO.Tags> is listed in the sitemap but ships generic markup; the reverse renders correct tags but stays invisible to the sitemap and SEO editor.

Before you begin

Projects created with the Wix CLI already include the @wix/astro and @wix/astro-pages dependencies, with the wix() and wixPages() integrations pre-configured in astro.config.mjs. You don't need to install or wire them yourself — the integration that reads your wixMetadata exports and serves /_wix/pages.json is ready out of the box:

Copy

The packages this guide adds are not predefined — install them yourself:

  • @wix/seo — the tag-fetching service and the <SEO.Tags> component.
  • @wix/essentials — exports the WIX_APPS constant used below for app IDs and page metadata.
Copy

WIX_APPS is a typed map of Wix app IDs and, for the solutions with dynamic pages, their page metadata. Prefer it over hardcoded strings — it gives you the appDefId, the pageIdentifier, and the slug token without copying literals into your code:

Copy

Source the appDefId, the pageIdentifier, and the slug-token value from the constant. The one thing you write by hand is the key inside identifiers — it must be the dynamic parameter of your route file (your code), not necessarily the key the SDK uses — see the note under Set up the SEO tags slot.

Note: The page-metadata accessor differs per vertical: WIX_APPS.checkoutAndOrders.productPageMetadata and .categoryPageMetadata (Stores), WIX_APPS.bookings.servicePageMetadata (Bookings), WIX_APPS.events.eventPageMetadata (Events), and WIX_APPS.blogs.postPageMetadata and .categoryPageMetadata (Blog).

Note: Dynamic pages must be server-rendered (output: "server"). The SDK calls used to fetch SEO tags depend on request context, so do not set prerender = true or use getStaticPaths() on these routes.

Set up the SEO tags slot

Expose a named seo-tags slot in the <head> of your shared layout. Dynamic pages fill this slot with Wix-generated tags; when it's empty, the layout falls back to its own default meta tags.

Copy

Each dynamic page imports the SEO helpers once in its frontmatter:

Copy

loadSEOTagsServiceConfig() takes three fields:

FieldDescription
pageUrlThe canonical URL of the current page — use Astro.url.href.
itemTypeA seoTags.ItemType value identifying the business-solution page type.
itemDataThe dynamic identifier for the item, as { slug: "<value>" }.

Important: The key inside wixMetadata.identifiers must match the name of your Astro route parameter. A route file named [handle].astro uses the key handle; [slug].astro uses slug. A mismatch breaks sitemap expansion.

The sections below show, per vertical, the wixMetadata export and the fetch-and-render snippet.


Wix Stores

The Stores app registers two dynamic sub-pages: product pages and category pages. Both use the same Stores page-registration app ID (1380b703-ce81-ff05-f115-39571d94dfcd).

Product pages

src/pages/product/[handle].astro

Register the route:

Copy

Fetch and render the SEO tags:

Copy

Tip: Run loadSEOTagsServiceConfig() in parallel with your data fetch via Promise.all to avoid an extra round trip.

Category pages

src/pages/search/[collection].astro

Register the route:

Copy

Fetch and render the SEO tags:

Copy

Wix Bookings

The Bookings app registers a dynamic service page (app ID 13d21c63-b5ec-5912-8397-c3a5ddb27a97).

src/pages/bookings/[slug].astro

Register the route:

Copy

Fetch and render the SEO tags:

Copy

Wix Events

The Events app registers a dynamic event page (app ID 140603ad-af8d-84a5-2c80-a0f60cb47351).

src/pages/events/[slug].astro

Register the route:

Copy

Fetch and render the SEO tags:

Copy

Wix Blog

The Blog app registers two dynamic sub-pages: post pages and category pages. Both use the same Blog app ID (14bcded7-0066-7c35-14d7-466cb3f09103).

Post pages

src/pages/blog/[slug].astro

Register the route:

Copy

Fetch and render the SEO tags:

Copy

Category pages

src/pages/blog-category/[slug].astro

Register the route:

Copy

Fetch and render the SEO tags:

Copy

Reference

The values that differ per vertical:

VerticalRoute fileappDefIdpageIdentifieridentifiersseoTags.ItemType
Stores — Productproduct/[handle].astroWIX_APPS.checkoutAndOrders.idwix.stores.sub_pages.producthandle: "STORES.PRODUCT.SLUG"STORES_PRODUCT
Stores — Categorysearch/[collection].astroWIX_APPS.checkoutAndOrders.idwix.stores.sub_pages.categorycollection: "STORES.CATEGORY.SLUG"STORES_CATEGORY
Bookings — Servicebookings/[slug].astroWIX_APPS.bookings.idwix.bookings.sub_pages.service_pageslug: "BOOKINGS.SERVICE.SLUG"BOOKINGS_SERVICE
Events — Eventevents/[slug].astroWIX_APPS.events.idwix.events.sub_pages.eventslug: "EVENTS.EVENT.SLUG"EVENTS_PAGE
Blog — Postblog/[slug].astroWIX_APPS.blogs.idwix.blog.sub_pages.postslug: "BLOG.POST.SLUG"BLOG_POST
Blog — Categoryblog-category/[slug].astroWIX_APPS.blogs.idwix.blog.sub_pages.categoryslug: "BLOG.CATEGORY.SLUG"BLOG_CATEGORY

Note: The identifiers column shows the key as it appears in each route file in this guide (handle, collection, slug). The key is always your own route's dynamic parameter; only the token value (STORES.PRODUCT.SLUG, etc.) is fixed by Wix.

Note: WIX_APPS.checkoutAndOrders.id (the page-registration ID, 1380b703-…) is not the same as the Stores catalog/install ID WIX_APPS.stores.id (215238eb-…) used for catalogReference.appId in cart operations. Both are correct; they identify different entities.

Optional: add structured data

<SEO.Tags> covers the tags managed in the Wix dashboard. To add schema.org structured data (rich results), render a JSON-LD script from the item you already fetched:

Copy

Use the schema type that fits the page — Product for store products, Event for events, and so on.

Verify your setup

  1. Run a production build and start the server (wix build, then wix preview or wix release).
  2. Request a dynamic page (for example, a product or event URL) and confirm the rendered <head> contains the Wix-generated <title>, <meta>, and <link rel="canonical"> tags rather than your layout's defaults.
  3. Open /_wix/pages.json and confirm your dynamic routes are listed with their wixMetadata.
  4. In the Wix dashboard, edit the SEO settings for the relevant page type and re-request the page to confirm the change reaches the live frontend.

Last updated: 25 June 2026

Did this help?