7 min read
Google MerchantHow-toFeed XML

How to create a Google Shopping feed XML manually (2026)

A Google Shopping feed is not a special format. It is plain RSS 2.0 with one extra namespace (g:, Google's product namespace). If your store platform exports one for you, use that. But when you have a small catalog, a custom backend with no feed plugin, or you just want to understand what Google actually reads, you can write the file by hand. Here is the minimal working version, the attributes that matter, and how to check it before Google rejects it.

The minimal working feed

This is a complete, valid single-product feed. Copy it, change the values, repeat the <item> block per product, and host it at a public URL Google can fetch.

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0">
  <channel>
    <title>My Store</title>
    <link>https://mystore.example</link>
    <description>Product feed</description>

    <item>
      <g:id>SKU-001</g:id>
      <g:title>Merino wool beanie, charcoal</g:title>
      <g:description>Soft 100% merino beanie. One size.</g:description>
      <g:link>https://mystore.example/products/beanie-charcoal</g:link>
      <g:image_link>https://mystore.example/img/beanie-charcoal.jpg</g:image_link>
      <g:availability>in_stock</g:availability>
      <g:price>24.90 EUR</g:price>
      <g:brand>Acme</g:brand>
      <g:condition>new</g:condition>
    </item>

  </channel>
</rss>

Three structural rules that trip people up: the xmlns:g declaration must be exactly http://base.google.com/ns/1.0; every product attribute carries the g: prefix while the channel-level tags (title, link, description) do not; and the file must be served as UTF-8 with a realContent-Type Google can read.

The required attributes

Google requires 7 attributes on every product. Everything else is conditional or recommended. The common mistake is treating condition or google_product_category as mandatory, they are not.

AttributeStatusNotes
g:idRequiredUnique per product, stable over time (≤50 chars)
g:titleRequiredOr g:structured_title; ≤150 chars shown
g:descriptionRequiredOr g:structured_description; ≤5000 chars
g:linkRequiredCrawlable product URL
g:image_linkRequiredPublic https URL; see image rules below
g:availabilityRequiredin_stock / out_of_stock / preorder / backorder
g:priceRequiredNumber + ISO code, e.g. "24.90 EUR"
g:conditionConditionalRequired only for used / refurbished
g:brandConditionalRequired for new branded products (except media)
g:gtinConditionalRequired when a manufacturer GTIN exists
g:mpnConditionalOnly when the product has no GTIN
g:google_product_categoryOptionalAuto-classified if omitted; set it to compete in apparel/electronics

The four attribute formats that cause the most rejections:

  • Price: a number, a space, and a 3-letter ISO 4217 code: 24.90 EUR. Period as the decimal point, no currency symbol, no thousands separator. Casing is tolerated (24.90 eur works) but stay consistent.
  • Availability: Google wants the underscored vocabulary: in_stock, out_of_stock, preorder, backorder. The spaced "in stock" form is Meta's, not Google's.
  • Identifiers: if a real GTIN exists, send it. If the product genuinely has none (handmade, custom), send g:identifier_exists = false rather than leaving Google to guess. Missing all of GTIN/MPN/brand is no longer a hard rejection, it caps visibility (a warning).
  • Condition: only new, refurbished, used. Omit it entirely for new products; it defaults to new.

Image rules you have to meet

The feed can be perfect and still get disapproved on the image. The rules that matter in 2026:

  • Size: a 500×500 px minimum is enforced for every product from January 31, 2027 (warnings show before then). Aim for 1200×1200+; smaller images get downranked regardless.
  • No promotional overlay. Sale badges, "20% OFF" chips, price stickers, and watermarks on g:image_link are a hard disapproval, this is Google-specific (Meta and TikTok allow them).
  • Real product, clean background. Google prefers white/transparent backgrounds with the product filling 75–90% of the frame. A logo or "coming soon" placeholder is a "generic image" rejection.
  • AI-composited images need a tag. If you AI-replace or generate part of the image, it must carry IPTC DigitalSourceType metadata (mandatory since Feb 2024) or Google disapproves it.

Validate before you submit

Catch errors locally, a rejected feed can take 24–48h to re-review. In order:

  • Well-formed XML. xmllint --noout feed.xml (or any XML validator) must return no errors. A single unescaped & in a title or URL breaks the whole file, encode it as &amp;.
  • Required attributes present. Every <item> has all 7. A quick grep for <g:price> count vs <item> count surfaces gaps fast.
  • Test fetch in Merchant Center. Add the feed URL as a data source and use "Fetch now" on a small sample before you point your live catalog at it. Read the diagnostics tab, it names the exact attribute and product for each issue.

For the specific rejection messages and their one-rule fixes, the 20 most common Merchant Center disapprovals guide maps each one to a cause and a fix, and the missing-GTIN page covers the identifier trap in depth.

When hand-editing stops being worth it

Writing the file by hand is fine for a handful of products or a one-off. It stops scaling the moment prices change, stock moves, or the catalog grows past a few dozen SKUs, now you are re-exporting and re-validating XML by hand every time anything changes, and a single typo silently disapproves a product mid-campaign.

Related

Ship better catalog ads this afternoon.

Free for 3 months on one feed up to 1,000 products. Connect your XML feed, design a template, paste the new URL into Meta / Google / TikTok.