StoreLingo - Webflow Marketplace resubmission changelog
Date: 2026-06-19 Submission: v2 (resubmission after initial rejection) Reviewer: Pablo Miranda + Webflow Marketplace team
This document accompanies the resubmission. It explains what changed since the first submission, why each change exists, and what reviewers should look at to validate.
The headline change: StoreLingo now leads with ownership. Every architectural choice in this product flows from the promise that translated content belongs to the customer's Webflow site, not to StoreLingo's servers. We rewrote the landing page, the docs, and the comparison pages around this single message, and we added or hardened the features that make the promise real.
What was wrong with v1
Pablo's rejection feedback pointed at three categories of problem:
- Demo video was unclear. Reviewers couldn't follow what the app actually did or how a customer would use it.
- Edge-case flows were untested. Disconnecting and reconnecting a site exposed broken states. Slug collisions on re-publish bricked the flow. Designer threw "Unable to open this product because a variant is missing" on translated duplicates.
- The value prop wasn't legible. Why does this exist when Weglot and Linguana exist? What problem is StoreLingo uniquely solving?
We addressed each.
What changed: features
Hreflang automation (new, end-to-end)
Reviewer concern from v1: how does SEO work on a duplicate-row architecture?
StoreLingo now registers a per-site script via the Webflow Custom Code API that injects <link rel="alternate" hreflang> tags into every translated page's head. Three modes:
- Automatic (default): zero customer action. Script registers on first publish, re-registers when the locale set changes.
- Manual: copy-paste snippet for customers who want server-rendered tags.
- Off: for customers running a separate SEO tool.
OAuth scopes added: custom_code:read, custom_code:write. Both are gated behind a per-feature re-auth UX: if a customer connected before the scopes existed, the Hreflang dialog renders an inline "Reauthorize StoreLingo" CTA instead of failing silently.
Verification: open any translated product URL on the live demo site, view source - the script tag and 3+ <link rel="alternate"> entries are in the head.
Docs: /docs/seo-and-hreflang
Orphan Recovery (new dialog + collision-safe matching)
The disconnect/reconnect flow was the v1 review's biggest stumbling block. Now:
- After every site connect, StoreLingo runs an orphan probe in the background.
- If we find translated CMS rows in the Webflow site that aren't linked to anything in our DB, a toast appears: "Found N translations from a previous install."
- The Recover button opens a dialog listing every orphan, with Adopt / Delete per-row actions and bulk Adopt-all / Delete-all.
- Adopt re-stamps the linkage so future publishes update the existing row instead of creating a new one (preventing slug collisions).
- The matcher uses three-layer fuzzy: exact slug, compacted slug, compacted name from DB fallback.
- Collision-safe: if two source products compact to the same key, the matcher refuses to auto-pick one and shows "No match" so the customer decides per row.
Verification: disconnect a connected site in the panel, reconnect, watch the toast appear with the previously published rows.
Docs: /docs/orphan-recovery
Per-item completion chip (new)
Every locale in the sidebar now shows a done / total chip. The count aggregates products + every CMS item across every collection. An item is "done" when every source-content field has a non-empty translation. Auto-updates after every save, AI translate, or orphan adoption.
Verification: open the panel, look at the DE chip. Translate a product, watch the count go up. No refresh needed.
Scope-aware re-auth UX (new)
Customers who connected before a new OAuth scope existed previously had no clean recovery path. Now: granted scopes are persisted at the OAuth handshake; feature gates check before calling Webflow; missing scopes surface as an inline "Reauthorize for [feature]" CTA on the specific feature, not a forced full re-install.
What changed: bugs fixed
"Unable to open this product because a variant is missing" in Webflow Designer
The most damaging v1 bug. Translated product duplicates couldn't be opened in Webflow Designer because their default-sku field pointed at the SOURCE product's SKU ID, not the duplicate's own SKU ID. The publish flow was spreading the source's full fieldData into the duplicate's PATCH body, clobbering the linkage.
Fix: strip default-sku and sku-properties from the source spread before every CREATE and PATCH. Existing duplicates were repaired with a one-time backfill script. Designer now opens every translated product cleanly with the correct price showing.
Slug-collision on republish (after disconnect/reconnect)
Previously: customers who disconnected and reconnected a site lost the DB linkage to existing Webflow duplicates. The publish flow then tried CREATE instead of PATCH, hit "slug already in database," and the slug-retry exhausted after 10 attempts. Stuck.
Fix: Orphan Recovery (above) restores the linkage with one click. The publish flow correctly does PATCH on adopted rows, no slug conflict.
Webflow PATCH 404 on duplicate self-heal
When a duplicate was deleted in Webflow Designer between publishes, our PATCH 404'd and the whole batch crashed. Now the PATCH 404 path nulls the stored ID and falls through to CREATE, so the publish self-heals instead of failing.
Initial-sync polling race (read-after-write)
After the initial sync job flipped to "completed," the next listProducts call could land before all the product upserts had settled on the DB pool. Result: empty product list visible briefly until manual refresh.
Fix: the watcher retries listProducts with backoff (0, 400, 800, 1500 ms) when the job claims completedItems > 0 but the query returns empty.
Initial-sync polling tolerance
The watcher was bailing on the first "no job found" poll because the backend writes the job row after kicking off the sync (small lag window). Now it tolerates up to 15s of "no job yet" before giving up.
Per-tab publish indicator stuck stale
After publishing a locale, the green dot on Products / CMS tabs stayed stale until manual refresh. Now a publishTick is bumped from both publish flows (Products + each CMS tab) and the per-tab status effect re-fires immediately.
Translation-set completeness mismatch
The completion chip was counting source fields that bulk translate doesn't actually translate (e.g., fields outside the per-collection translatable-fields allowlist). Customers saw "9/21" forever even after translating everything. Now the chip intersects the source-field set with the same allowlist the editor and AI translate use - what the customer can see is what the customer gets counted for.
Add-locale backfill used the wrong field list
The Add-Locale path was backfilling empty translation rows using a hardcoded [name, description, summary] instead of the site's actual translatableFields allowlist. Custom fields like short-description were never seeded, so AI translate had nothing to fill, and the chip stayed below 100%. Fixed: backfill respects the site's current allowlist.
Orphan matcher collision guard
The fuzzy matcher could silently pick the wrong source product when two compacted slugs collided. Now the matcher tracks collision keys and drops colliding entries from the suggestion pool, surfacing "No match" instead of an incorrect auto-match.
Reusable docs + screenshots route
Added /docs/screenshots/*.png static route so embedded screenshots in markdown docs render correctly. Layout CSS caps full-panel shots at content width, sidebar crops at 320px, toast notifications at 380px.
What changed: landing page + comparison pages
The v1 landing led with "Flat pricing, native API." Reviewers (correctly) couldn't tell why anyone would pick StoreLingo over Weglot from that pitch alone.
v2 landing leads with ownership:
- New hero: "Translate your Webflow store. Own every word of it."
- New three-card wedge: "Real Webflow CMS rows", "Hreflang on autopilot", "Disconnect-reconnect proof"
- Comparison table expanded with "You own the translations" and "Survives if the app disappears" as the top two rows
- FAQ expanded with the two highest-leverage questions: what "you own" means in practice, and what happens on disconnect-reconnect
Comparison pages (/vs/weglot, /vs/linguana) updated with the same ownership angle and new feature rows (automatic hreflang, orphan recovery).
What changed: docs
The v1 docs were 9 thin markdown files. v2 has 10 files (added ownership.md + orphan-recovery.md) and every existing file was substantially expanded.
Headline additions:
/docs/ownership— the long-form ownership pitch with the full architecture-comparison table and the "what happens after day one" case grid./docs/orphan-recovery— complete walkthrough of the disconnect/reconnect recovery flow, including collision safety./docs/getting-started— rewritten as a 7-step onboarding with 7 embedded screenshots./docs/seo-and-hreflang— full coverage of all three hreflang modes./docs/publishing— accurate full flow including the variant-link fix history./docs/ai-translation,/docs/glossary,/docs/locales,/docs/plans,/docs/troubleshooting- all expanded with usage detail and cross-links.
15 screenshots embedded across the docs, captured at 2x retina and sized correctly by CSS.
What changed: OAuth and session management
Two related architectural cleanups:
OAuth token is account-level, not per-site. Disconnecting a site no longer invalidates the OAuth token. Customers can connect/disconnect/reconnect without going through Webflow's consent screen each time. Matches the standard Marketplace app pattern (Stripe, Slack, GitHub apps).
Granted scopes persisted at handshake. When OAuth completes, we save the exact scope list Webflow granted. Feature gates check the stored scopes before calling Webflow, so a missing scope surfaces as an inline "Reauthorize for [feature]" CTA instead of a 403 error after the fact.
What didn't change
Honest list of things v1 had that v2 still has at the same level:
- DeepL is still the only AI translation provider. Multi-engine selection (DeepL vs GPT vs Google) is a v1.1 follow-up.
- No visual in-context editor (clicking a string on the rendered page). Edits happen in the panel. v1.1.
- No permanent free tier. Plans start at $19/mo with a 14-day card-not-required trial. v1.1.
- No translation memory sharing across sites (each site has its own TM). Pro/Agency feature for v1.1.
These are all v1.1 candidates, not Marketplace gating issues.
What reviewers should test
In priority order:
- Install + initial sync. Connect the demo site, watch products + CMS sync without manual refresh.
- AI translate to one locale. Translate the Products tab to DE, watch the completion chip go from 0/21 to N/21 live.
- Publish. Click Publish DE, watch the publish-complete toast, open the published German URL.
- Open a published product in Webflow Designer. Should open cleanly with price showing (this was the worst v1 bug).
- View source on a translated URL. Confirm the hreflang script + alternate link tags in the head.
- Disconnect + reconnect. Watch the orphan toast appear, click Recover, Adopt all, confirm translations survive intact.
- Hreflang dialog. Toggle Auto → Manual → Off → Auto. Confirm each mode behaves correctly.
- Cancel subscription. Confirm translated pages stay live in the Webflow site after cancellation (the ownership promise made real).
Demo video
Loom: https://www.loom.com/share/18de6d78168648518fb9f2a45368a316
The video is silent (~2:15). Three onscreen captions hit the resubmission narrative:
- "Disconnect, reconnect, everything survives." (after Adopt All)
- "Automatic hreflang. Set and forget." (in the Hreflang dialog)
- "Real Webflow CMS rows. Not a runtime overlay." (at Publish complete)
Sequence: connect → orphan recovery → adopt all → AI translate → manual edit + approve → hreflang dialog → publish.
The video opens with the disconnect-reconnect orphan recovery flow on purpose - that was the v1 review's biggest stumbling block, so we lead by demonstrating it works cleanly.
One-line summary for the reviewer
StoreLingo writes real translated CMS rows into the customer's own Webflow site. Customers own them forever. Strategy A. Every fix in this changelog protects that promise.
Pablo: thank you for the v1 review. Every flag you raised is addressed above. Happy to answer questions on any specific item.