con un clic
enable-shopify-cms
// Wire Shopify metaobjects as the CMS for homepage and marketing page content. Adds GraphQL queries for cms_homepage and cms_page metaobject types and transforms them into domain types.
// Wire Shopify metaobjects as the CMS for homepage and marketing page content. Adds GraphQL queries for cms_homepage and cms_page metaobject types and transforms them into domain types.
Enable next-intl-based i18n in the shop template — locale-prefixed URLs, per-locale message catalogs, and a locale switcher. Use when the user wants "locale URLs", "multi-language", or "i18n" without Shopify Markets integration. For full Shopify Markets multi-region commerce (region-aware pricing, inventory, payments), use `enable-shopify-markets` instead — this skill is the routing/i18n layer only.
Replace the hardcoded nav and footer menus with Shopify-powered menus.
Reference Vercel Shop GraphQL patterns, fragments, cache conventions, and transforms for any Shopify GraphQL work in the template.
Enable Shopify Markets with multi-locale routing using next-intl. Use when the user wants to add internationalization, multi-locale support, locale-prefixed URLs, or Shopify Markets. Supports sub-path and per-domain routing strategies.
Add Vercel Analytics, Vercel Speed Insights, and Google Tag Manager to the storefront.
Use Shopify AI Toolkit to inspect live Storefront and Customer Account GraphQL schemas for Vercel Shop work.
| name | enable-shopify-cms |
| description | Wire Shopify metaobjects as the CMS for homepage and marketing page content. Adds GraphQL queries for cms_homepage and cms_page metaobject types and transforms them into domain types. |
Add Shopify metaobject-based CMS support to the shop template. This replaces the hardcoded homepage content with Shopify-managed content using cms_homepage and cms_page metaobject definitions.
cms_homepage and cms_pagecms_homepage| Field handle | Type | Description |
|---|---|---|
title | single_line_text | Page title |
meta_title | single_line_text | SEO title override |
meta_description | single_line_text | SEO description override |
hero_headline | single_line_text | Hero banner headline |
hero_subheadline | single_line_text | Hero banner subheadline |
hero_image | file | Hero background image |
hero_cta_text | single_line_text | Hero call-to-action label |
hero_cta_link | single_line_text | Hero call-to-action URL |
sections | json | Array of content section definitions |
cms_page| Field handle | Type | Description |
|---|---|---|
slug | single_line_text | URL slug |
title | single_line_text | Page title |
locale | single_line_text | Locale code (e.g. en-US) |
meta_title | single_line_text | SEO title override |
meta_description | single_line_text | SEO description override |
hero_headline | single_line_text | Hero banner headline |
hero_subheadline | single_line_text | Hero banner subheadline |
hero_image | file | Hero background image |
hero_cta_text | single_line_text | Hero call-to-action label |
hero_cta_link | single_line_text | Hero call-to-action URL |
sections | json | Array of content section definitions |
lib/shopify/operations/cms.tsImplement three operations that return domain types from lib/types.ts:
import { shopifyFetch } from "@/lib/shopify/client";
import type { Homepage, MarketingPage } from "@/lib/types";
export async function getHomepage(locale: string): Promise<Homepage | null> {
"use cache";
cacheLife("max");
cacheTag("cms-content");
// Query cms_homepage metaobject, transform to Homepage type
}
export async function getMarketingPage(
slug: string,
locale: string,
): Promise<MarketingPage | null> {
"use cache";
cacheLife("max");
cacheTag("cms-content");
// Query cms_page metaobject by slug, transform to MarketingPage type
}
export async function getAllMarketingPageSlugs(): Promise<
Array<{ slug: string; updatedAt: string }>
> {
"use cache";
cacheLife("max");
cacheTag("cms-content");
// Query all cms_page metaobjects, return slugs
}
Validate field names with shopify-ai-toolkit or vercel-shop:fetch-shopify-schema. Use metaobjects(type: "cms_homepage") and metaobjects(type: "cms_page") queries with @inContext locale directives.
Create lib/shopify/transforms/cms.ts to convert raw metaobject fields into the domain types:
sections JSON field into ContentSection[]ProductCard[] using getProductsByIdsHeroSectionMarketingImageUpdate app/page.tsx to use the CMS operation:
import { getHomepage } from "@/lib/shopify/operations/cms";
import { MarketingPageRenderer } from "@/components/cms/page-renderer";
export default async function HomePage() {
const locale = await getLocale();
const page = await getHomepage(locale);
if (!page) return <FallbackHomepage />;
return (
<Container>
<MarketingPageRenderer page={page} />
</Container>
);
}
Update app/pages/[slug]/page.tsx and app/sitemap.ts to use getMarketingPage and getAllMarketingPageSlugs.
Create app/api/webhooks/shopify-cms/route.ts:
import { updateTag } from "next/cache";
export async function POST(request: Request) {
// Verify Shopify webhook signature
updateTag("cms-content");
return new Response("OK");
}
lib/types.ts — Homepage, MarketingPage, ContentSection.ProductCard[] — components expect ready-to-render product data.alternates field on MarketingPage — this powers locale-aware URL switching.