Webflow CMS duplicate-row architecture explained
Why every serious Webflow localization choice eventually comes down to runtime overlay or duplicate CMS rows. The case for Strategy A, with the real tradeoffs and the things we got wrong on the way.
Every Webflow localization tool eventually picks one of two architectures: rewrite the DOM at render time, or write real translated CMS rows back into the customer's Webflow site. The first is faster to build. The second survives more interesting scenarios. The choice you don't realize you're making when you pick a tool determines what happens to your translated catalog the day you cancel.
We picked Strategy A — duplicate rows in your own CMS — when we started building StoreLingo. This post is a working architect's account, not a pitch.
The two architectures, plainly
Runtime overlay
- One copy of your content lives in Webflow (the source language).
- The translation tool's servers store the translated strings.
- When a visitor hits the German URL, either the tool's CDN serves a rewritten copy or a JavaScript snippet runs in the browser to swap text in the DOM.
- Webflow's CMS never has German content. From Webflow's perspective, you have one English store.
Duplicate rows (Strategy A)
- The translation tool writes a real Webflow CMS row for every translated piece of content.
- The German product is a new row in your Webflow Products collection, with a German slug, German fields, German SKU variants.
- Webflow renders these pages from its own CMS exactly like any other product page.
- The translation tool's job ends once the row is written; Webflow's CDN handles serving.
Both architectures produce something a visitor can browse in German. They diverge sharply once you ask: what happens when something changes?
The decision tree we walked
Before we settled on Strategy A, we considered three alternatives. Worth showing the reasoning because if your situation differs, you might land on a different answer.
Why we didn't pick runtime overlay
Why we didn't ask customers to roll their own
For a five-product store, manual duplication is honestly fine. At any meaningful catalog size, the upkeep is the problem — source updates ported by hand, SKU variants cloned, hreflang wired manually. We weren't going to charge for an app that just automates what customers could do for free, but manual genuinely doesn't scale.
Why we didn't wait for Webflow native Ecommerce localization
Webflow shipped native Localization in 2024 for static and CMS content. They've not committed to extending it to Ecommerce. Customers selling on Webflow need a solution now. We chose to build it and bake in a "one-click migration to native" path for whenever Webflow ships it.
The concrete architecture
Per-product duplicate creation
For every (source product × target locale) pair, we create one new row in your Webflow
Products collection. Slug gets a locale prefix (de-blue-mug). Translatable text
fields get translated values. Non-translatable fields (price,
inventory, tax-category) are copied verbatim so the duplicate is a
valid Ecommerce product from creation.
A locale PlainText field is auto-created on the Products collection if absent,
set to the target locale code on each duplicate. Your storefront list components can then
filter by locale natively.
Per-SKU duplicate creation
For products with SKU variants, every source SKU gets a duplicate SKU row. Locale-prefixed
slug, translated name, structured price copied verbatim, inventory
copied verbatim. The duplicate's default-sku pointer is auto-resolved by
Webflow — explicitly NOT spread from the source. (See our
SKU variant post for that bug story.)
Hreflang automation
Webflow's Custom Code API lets us register an inline script on the site. We use it to inject
a ~1.5kb script that runs on every page load, detects the URL's slug pattern, strips any
locale prefix to find the source slug, and inserts
<link rel="alternate" hreflang> tags into the head. Toggleable to Manual
mode for customers who prefer to paste hreflang into Designer themselves.
Linkage tracking
When linkage is lost (disconnect/reconnect, database restore, account migration), Orphan Recovery probes Webflow for CMS rows tagged with a non-primary locale but not linked in our DB, matches them back with three-layer fuzzy logic (exact slug, compacted slug, compacted name), and offers one-click adoption. Collision-safe: if two source products compact to the same key, the matcher refuses to auto-pick one.
The hard parts (and how we solved them)
Slug collisions on re-publish
Webflow holds slug reservations for hours after a CMS item is deleted in Designer. If a
customer manually deletes de-blue-mug, our next publish trying to create
de-blue-mug fresh returns 400 "Unique value is already in database." We retry
with -2, -3 suffixes up to -10. After ten consecutive
reservations the customer gets a clear error.
The "variant is missing" bug we shipped
Detailed in our SKU variant post: our
publish flow spread the source product's full fieldData into the duplicate, which
carried the source's default-sku pointer into the duplicate. Designer refused to
open the duplicate because its default-sku resolved to a SKU that wasn't in its own SKU set.
Fix: strip default-sku and sku-properties from the spread.
Read-after-write race after initial sync
Our initial-sync job marks itself "completed" the moment its batch upserts return. The next
API call our panel makes sometimes lands on a different DB connection that hasn't seen the
upserts. Result: empty product list right after the sync toast. Fix: the watcher retries
listProducts with backoff (0, 400, 800, 1500ms).
OAuth scope migration without breaking existing customers
When we added automatic-hreflang, it needed the custom_code:write scope, which
wasn't in our v1 scope list. Standard pattern in larger SaaS apps: persist the granted scope
list at the OAuth handshake, gate the feature per-scope, surface an inline "Reauthorize for
[feature]" CTA in the panel when a customer hits a feature requiring a scope they don't have.
What Strategy A costs you
What Strategy A gives you
Is Strategy A the right choice for you?
Three honest tests:
- Does it matter that translated content lives in your Webflow CMS? If yes, Strategy A. If you don't care, runtime overlay is cheaper to build.
- Do you sell products with SKU variants? If yes, structured-row translation is Strategy A's natural strength.
- Are you on a Webflow Ecommerce plan with enough CMS budget? Multiply source products × (locales + 1). If you're tight, upgrade Webflow before adding locales.
The architecture matters more than the tool.
We make StoreLingo, which implements Strategy A as a managed tool. We're also fine with you hand-rolling it on a 5-product catalog.
We build StoreLingo: a Webflow Marketplace app for Ecommerce localization that writes real translated CMS rows back into the customer's own Webflow site. Everything in this post comes from shipping the product: actual Webflow Data API behavior, actual bugs we tripped on (and fixed), actual decisions we had to make about Strategy A duplicate-row architecture vs runtime overlay. We have no relationship with Weglot, Linguana, or Webflow other than as developer-API consumers. If we got something wrong, email hello@storelingo.com and we will fix the post within a business day.
Translate your Webflow store. Own every word of it.
StoreLingo writes real translated CMS rows into your own Webflow site. Flat pricing. Automatic hreflang. SKU variants done right. Pages survive uninstall.