twittercard

Platforms

X Cards on Shopify, Next.js and Astro

How Shopify themes, the Next.js Metadata API and Astro output X (Twitter) Card tags, where to set the image and title, and the mistakes specific to each.

Short answer

Shopify's free themes already print Open Graph and card tags from your featured images and Online Store > Preferences; Next.js writes them from the metadata export's openGraph and twitter objects; Astro needs a small head component that builds absolute URLs from Astro.site.

Key takeaways

  • Shopify: set the store's social sharing image under Online Store > Preferences; products and posts use their featured images.
  • Next.js: set metadataBase once, then twitter.card and images per route, or use twitter-image files.
  • Astro: set site in the config, then render tags with absolute URLs.
  • In every stack, tags must be in the server-rendered HTML.

The tags are the same everywhere; what changes is where each platform wants you to put the values. Here is where to look on three common stacks. WordPress has its own guide.

How do X Cards work on Shopify?

Shopify's free themes already output Open Graph tags; you control them through images and SEO fields, not code. Shopify's help center says its free themes use Open Graph tags to tell social platforms about your pages.

Page type Image used Where to change it
Product, collection, blog post Its featured image The product, collection or post editor
Home page and pages without an image The store's social sharing image Online Store > Preferences > Social sharing image and SEO

The title and description come from each item's search engine listing fields, which default to the product title and description. To see exactly what your theme prints, open Online Store > Themes > Edit code and find the snippet that writes the meta tags; in many themes it is a file named along the lines of meta-tags.liquid. That is also where you would add twitter:site if your theme leaves it out.

Shopify-specific gotchas:

  1. Square product photos. Many stores shoot products on square canvases. On a large image card X crops them to 2:1 from the center, which can cut off the top and bottom of the product. Consider a landscape lifestyle shot as the featured image for products you promote on X.
  2. Password-protected stores. While the storefront password page is on, crawlers see that page, and its tags, instead of your products.
  3. Third-party SEO apps. Some apps add their own social tags. Check the source for duplicates after installing one.

How do X Cards work in Next.js?

In the App Router, export metadata or generateMetadata and fill in openGraph and twitter; Next.js renders the tags into the HTML.

// app/layout.tsx
export const metadata = {
  metadataBase: new URL('https://example.com'),
  openGraph: { siteName: 'Example', type: 'website' },
  twitter: { card: 'summary_large_image', site: '@example' },
}
// app/blog/[slug]/page.tsx
export async function generateMetadata({ params }) {
  const { slug } = await params
  const post = await getPost(slug)
  return {
    title: post.title,
    description: post.summary,
    openGraph: { title: post.title, description: post.summary, images: [post.cover] },
    twitter: { card: 'summary_large_image', title: post.title, images: [post.cover] },
  }
}

Things to know:

  • metadataBase lets you write relative image paths; without it, a relative URL in a URL field is a build error. Set it once in the root layout.
  • Merging is shallow. If a page sets openGraph, it replaces the whole openGraph object from the layout, so the page's object must include everything it needs. The same goes for twitter.
  • File-based images win. A twitter-image.png or opengraph-image.png in a route folder overrides the metadata object for that route.
  • Server components only. metadata and generateMetadata cannot be exported from a 'use client' file.

Recent versions can stream metadata for normal browsers, but the Next.js docs say they wait for metadata before responding to HTML-limited bots such as facebookexternalhit, detected by user agent. If a card is missing on X while Facebook works, check whether a request with a Twitterbot user agent gets the tags in <head> (Next.js lets you adjust the list with the htmlLimitedBots option).

How do X Cards work in Astro?

Astro leaves the head to you: write a small component and use it in your layout. The only Astro-specific rule is to set site in astro.config.mjs so you can build absolute URLs:

---
const { title, description, image, imageAlt } = Astro.props;
const url = new URL(Astro.url.pathname, Astro.site);
const img = new URL(image, Astro.site);
---
<meta name="twitter:card" content="summary_large_image" />
<meta property="og:url" content={url} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={img} />
<meta property="og:image:alt" content={imageAlt} />

new URL(image, Astro.site) turns /og/post.png into https://example.com/og/post.png and leaves absolute URLs alone. In static builds the tags are in the generated HTML, which is exactly what crawlers want. With server rendering they are rendered per request, which also works.

One check for every stack

Whatever the framework, run this against a deployed page:

curl -s -A "Twitterbot/1.0" https://example.com/your-page/ | grep -iE 'twitter:|og:'

If the tags are not in that output, X cannot see them either. The snippets tool generates the Next.js and Astro code above with your own values, and the inspector checks the result.

Questions

Does Shopify use summary_large_image?

Many themes print twitter:card as summary_large_image; check your theme's meta tags snippet in the code editor. Whatever it prints, the Open Graph image comes from the page's featured image or the store's social sharing image.

Next.js client components and metadata?

The metadata export and generateMetadata only work in server components. Keep page.tsx as a server component that exports metadata and move interactive code into a separate client component.

Can Next.js generate the image too?

Yes. A twitter-image or opengraph-image file in a route folder, either a static image or a file that generates one, is picked up automatically and takes priority over the metadata object.

Astro with a CMS?

Fetch the title, description and image URL from the CMS in the page's frontmatter and pass them to the head component. Make sure the image URL from the CMS is absolute.

Sources

Keep reading