--- title: getSeoMeta description: Generate a [Remix meta array](https://remix.run/docs/en/main/route/meta) from one or more SEO configuration objects. Pass SEO configuration for the parent route(s) and the current route to preserve meta data for all active routes. Similar to [`Object.assign()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign), each property is overwritten based on the object order. The exception is `jsonLd`, which is preserved so that each route has it's own independent jsonLd meta data. Learn more about [how SEO works in Hydrogen](https://shopify.dev/docs/custom-storefronts/hydrogen/seo). api_version: 2025-05 api_name: hydrogen source_url: html: https://shopify.dev/docs/api/hydrogen/latest/utilities/getseometa md: https://shopify.dev/docs/api/hydrogen/latest/utilities/getseometa.md --- # get​Seo​Metautility Generate a [Remix meta array](https://remix.run/docs/en/main/route/meta) from one or more SEO configuration objects. Pass SEO configuration for the parent route(s) and the current route to preserve meta data for all active routes. Similar to [`Object.assign()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign), each property is overwritten based on the object order. The exception is `jsonLd`, which is preserved so that each route has it's own independent jsonLd meta data. Learn more about [how SEO works in Hydrogen](https://shopify.dev/docs/custom-storefronts/hydrogen/seo). ## getSeoMeta * seoInputs SeoConfig\[] required `getSeoMeta` takes an arbitrary number of configuration object parameters. Values in each object are overwritten based on the object order. \`jsonLd\` properties are preserved between each configuration object. ### SeoConfig * alternates The \`alternates\` property is used to specify the language and geographical targeting when you have multiple versions of the same page in different languages. The \`url\` property tells search engines about these variations and helps them to serve the correct version to their users. ```ts LanguageAlternate | LanguageAlternate[] ``` * description The description of the page. This is used in the \`name="description"\` meta tag as well as the \`og:description\` meta tag. ```ts Maybe ``` * handle The handle is used to generate the \`twitter:site\` and \`twitter:creator\` meta tags. Include the \`@\` symbol in the handle. ```ts Maybe ``` * jsonLd The \`jsonLd\` property is used to generate the \`application/ld+json\` script tag. This is used to provide structured data to search engines. The value should be an object that conforms to the schema.org spec. The \`type\` property should be the type of schema you are using. The \`type\` property is required and should be one of the following: - \`Product\` - \`ItemList\` - \`Organization\` - \`WebSite\` - \`WebPage\` - \`BlogPosting\` - \`Thing\` The value is validated via \[schema-dts]\(https\://www\.npmjs.com/package/schema-dts) ```ts WithContext | WithContext[] ``` * media The media associated with the given page (images, videos, etc). If you pass a string, it will be used as the \`og:image\` meta tag. If you pass an object or an array of objects, that will be used to generate \`og:\\` meta tags. The \`url\` property should be the URL of the media. The \`height\` and \`width\` properties are optional and should be the height and width of the media. The \`altText\` property is optional and should be a description of the media. ```ts | Maybe | Partial | (Partial | Maybe)[] ``` * robots The \`robots\` property is used to specify the robots meta tag. This is used to tell search engines which pages should be indexed and which should not. ```ts RobotsOptions ``` * title The \`title\` HTML element defines the document's title that is shown in a browser's title bar or a page's tab. It only contains text; tags within the element are ignored. ```ts Maybe ``` * titleTemplate Generate the title from a template that includes a \`%s\` placeholder for the title. ```ts Maybe | null ``` * url The canonical URL of the page. This is used to tell search engines which URL is the canonical version of a page. This is useful when you have multiple URLs that point to the same page. The value here will be used in the \`rel="canonical"\` link tag as well as the \`og:url\` meta tag. ```ts Maybe ``` ````ts export interface SeoConfig { /** * The `title` HTML element defines the document's title that is shown in a browser's title bar or a page's tab. It * only contains text; tags within the element are ignored. * * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/title */ title?: Maybe; /** * Generate the title from a template that includes a `%s` placeholder for the title. * * @example * ```js * { * title: 'My Page', * titleTemplate: 'My Site - %s', * } * ``` */ titleTemplate?: Maybe | null; /** * The media associated with the given page (images, videos, etc). If you pass a string, it will be used as the * `og:image` meta tag. If you pass an object or an array of objects, that will be used to generate `og:` meta tags. The `url` property should be the URL of the media. The `height` and `width` properties are * optional and should be the height and width of the media. The `altText` property is optional and should be a * description of the media. * * @example * ```js * { * media: [ * { * url: 'https://example.com/image.jpg', * type: 'image', * height: '400', * width: '400', * altText: 'A custom snowboard with an alpine color pallet.', * } * ] * } * ``` * */ media?: | Maybe | Partial | (Partial | Maybe)[]; /** * The description of the page. This is used in the `name="description"` meta tag as well as the `og:description` meta * tag. * * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta */ description?: Maybe; /** * The canonical URL of the page. This is used to tell search engines which URL is the canonical version of a page. * This is useful when you have multiple URLs that point to the same page. The value here will be used in the * `rel="canonical"` link tag as well as the `og:url` meta tag. * * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link */ url?: Maybe; /** * The handle is used to generate the `twitter:site` and `twitter:creator` meta tags. Include the `@` symbol in the * handle. * * @example * ```js * { * handle: '@shopify' * } * ``` */ handle?: Maybe; /** * The `jsonLd` property is used to generate the `application/ld+json` script tag. This is used to provide structured * data to search engines. The value should be an object that conforms to the schema.org spec. The `type` property * should be the type of schema you are using. The `type` property is required and should be one of the following: * * - `Product` * - `ItemList` * - `Organization` * - `WebSite` * - `WebPage` * - `BlogPosting` * - `Thing` * * The value is validated via [schema-dts](https://www.npmjs.com/package/schema-dts) * * @example * ```js * { * jsonLd: { * '@context': 'https://schema.org', * '@type': 'Product', * name: 'My Product', * image: 'https://hydrogen.shop/image.jpg', * description: 'A product that is great', * sku: '12345', * mpn: '12345', * brand: { * '@type': 'Thing', * name: 'My Brand', * }, * aggregateRating: { * '@type': 'AggregateRating', * ratingValue: '4.5', * reviewCount: '100', * }, * offers: { * '@type': 'Offer', * priceCurrency: 'USD', * price: '100', * priceValidUntil: '2020-11-05', * itemCondition: 'https://schema.org/NewCondition', * availability: 'https://schema.org/InStock', * seller: { * '@type': 'Organization', * name: 'My Brand', * }, * }, * } * } * ``` * * @see https://schema.org/docs/schemas.html * @see https://developers.google.com/search/docs/guides/intro-structured-data * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script * */ jsonLd?: WithContext | WithContext[]; /** * The `alternates` property is used to specify the language and geographical targeting when you have multiple * versions of the same page in different languages. The `url` property tells search engines about these variations * and helps them to serve the correct version to their users. * * @example * ```js * { * alternates: [ * { * language: 'en-US', * url: 'https://hydrogen.shop/en-us', * default: true, * }, * { * language: 'fr-CA', * url: 'https://hydrogen.shop/fr-ca', * }, * ] * } * ``` * * @see https://support.google.com/webmasters/answer/189077?hl=en */ alternates?: LanguageAlternate | LanguageAlternate[]; /** * The `robots` property is used to specify the robots meta tag. This is used to tell search engines which pages * should be indexed and which should not. * * @see https://developers.google.com/search/reference/robots_meta_tag */ robots?: RobotsOptions; } ```` ### LanguageAlternate * default Whether the alternate page is the default page. This will add the \`x-default\` attribution to the language code. ```ts boolean ``` * language Language code for the alternate page. This is used to generate the hreflang meta tag property. ```ts string ``` * url The url of the alternate page. This is used to generate the hreflang meta tag property. ```ts string ``` ```ts export interface LanguageAlternate { /** * Language code for the alternate page. This is used to generate the hreflang meta tag property. */ language: string; /** * Whether the alternate page is the default page. This will add the `x-default` attribution to the language code. */ default?: boolean; /** * The url of the alternate page. This is used to generate the hreflang meta tag property. */ url: string; } ``` ### SeoMedia * altText The alt text for the media. This is used to generate the og:\:alt meta tag. ```ts Maybe | undefined ``` * height The height in pixels of the media. This is used to generate the og:\:height meta tag. ```ts Maybe | undefined ``` * type Used to generate og:\ meta tag ```ts 'image' | 'video' | 'audio' ``` * url The url value populates both url and secure\_url and is used to infer the og:\:type meta tag. ```ts Maybe | undefined ``` * width The width in pixels of the media. This is used to generate the og:\:width meta tag. ```ts Maybe | undefined ``` ```ts { /** * Used to generate og: meta tag */ type: 'image' | 'video' | 'audio'; /** * The url value populates both url and secure_url and is used to infer the og::type meta tag. */ url: Maybe | undefined; /** * The height in pixels of the media. This is used to generate the og::height meta tag. */ height: Maybe | undefined; /** * The width in pixels of the media. This is used to generate the og::width meta tag. */ width: Maybe | undefined; /** * The alt text for the media. This is used to generate the og::alt meta tag. */ altText: Maybe | undefined; } ``` ### RobotsOptions * maxImagePreview Set the maximum size of an image preview for this page in a search results Can be one of the following: - \`none\` - No image preview is to be shown. - \`standard\` - A default image preview may be shown. - \`large\` - A larger image preview, up to the width of the viewport, may be shown. If no value is specified a default image preview size is used. ```ts 'none' | 'standard' | 'large' ``` * maxSnippet A number representing the maximum of amount characters to use as a textual snippet for a search result. This value can also be set to one of the following special values: - 0 - No snippet is to be shown. Equivalent to nosnippet. - 1 - The Search engine will choose the snippet length that it believes is most effective to help users discover your content and direct users to your site - -1 - No limit on the number of characters that can be shown in the snippet. ```ts number ``` * maxVideoPreview The maximum number of seconds for videos on this page to show in search results. This value can also be set to one of the following special values: - 0 - A static image may be used with the \`maxImagePreview\` setting. - 1 - There is no limit to the size of the video preview. This applies to all forms of search results (at Google: web search, Google Images, Google Videos, Discover, Assistant). ```ts number ``` * noArchive Do not show a cached link in search results. ```ts boolean ``` * noFollow Do not follow the links on this page. ```ts boolean ``` * noImageIndex Do not index images on this page. ```ts boolean ``` * noIndex Do not show this page, media, or resource in search results. ```ts boolean ``` * noSnippet Do not show a text snippet or video preview in the search results for this page. ```ts boolean ``` * noTranslate Do not offer translation of this page in search results. ```ts boolean ``` * unavailableAfter Do not show this page in search results after the specified date/time. ```ts string ``` ```ts export interface RobotsOptions { /** * Set the maximum size of an image preview for this page in a search results Can be one of the following: * * - `none` - No image preview is to be shown. * - `standard` - A default image preview may be shown. * - `large` - A larger image preview, up to the width of the viewport, may be shown. * * If no value is specified a default image preview size is used. */ maxImagePreview?: 'none' | 'standard' | 'large'; /** * A number representing the maximum of amount characters to use as a textual snippet for a search result. This value * can also be set to one of the following special values: * * - 0 - No snippet is to be shown. Equivalent to nosnippet. * - 1 - The Search engine will choose the snippet length that it believes is most effective to help users discover * your content and direct users to your site * - -1 - No limit on the number of characters that can be shown in the snippet. */ maxSnippet?: number; /** * The maximum number of seconds for videos on this page to show in search results. This value can also be set to one * of the following special values: * * - 0 - A static image may be used with the `maxImagePreview` setting. * - 1 - There is no limit to the size of the video preview. * * This applies to all forms of search results (at Google: web search, Google Images, Google Videos, Discover, * Assistant). */ maxVideoPreview?: number; /** * Do not show a cached link in search results. */ noArchive?: boolean; /** * Do not follow the links on this page. * * @see https://developers.google.com/search/docs/advanced/guidelines/qualify-outbound-links */ noFollow?: boolean; /** * Do not index images on this page. */ noImageIndex?: boolean; /** * Do not show this page, media, or resource in search results. */ noIndex?: boolean; /** * Do not show a text snippet or video preview in the search results for this page. */ noSnippet?: boolean; /** * Do not offer translation of this page in search results. */ noTranslate?: boolean; /** * Do not show this page in search results after the specified date/time. */ unavailableAfter?: string; } ``` ### Examples * #### Example code ##### Description I am the default example ##### JavaScript ```js import {getSeoMeta} from '@shopify/hydrogen'; export async function loader({context}) { const {shop} = await context.storefront.query(` query layout { shop { name description } } `); return { seo: { title: shop.title, description: shop.description, }, }; } export const meta = ({data, matches}) => { // Pass one or more arguments, preserving properties from parent routes return getSeoMeta(matches[0].data.seo, data.seo); }; ``` ##### TypeScript ```ts import {MetaFunction} from 'react-router'; import {LoaderFunctionArgs} from 'react-router'; import {getSeoMeta} from '@shopify/hydrogen'; export async function loader({context}: LoaderFunctionArgs) { const {shop} = await context.storefront.query(` query layout { shop { name description } } `); return { seo: { title: shop.title, description: shop.description, }, }; } export const meta: MetaFunction = ({data, matches}) => { // Pass one or more arguments, preserving properties from parent routes return getSeoMeta((matches as any)[0].data.seo, data!.seo); }; ```