ZeDaq.ai
Shopper using virtual try-on for a tailored suit

Single-Page Apps and Product Page Widgets: Routing Pitfalls

By the ZeDaq.ai team · · 5 min read

On this page
  1. Why do widgets misbehave in single-page apps?
  2. What does the ZeDaq.ai widget do when it loads?
  3. What are the common routing pitfalls?
  4. How do you plan around these pitfalls?
  5. How do you test routing properly?
  6. Where do other platforms fit in?

Widgets break in single-page apps (SPAs) because the browser loads the page once and the router swaps content afterward. A script that runs only when the page loads never learns that the shopper moved from a category page to a product page.

This guide covers the most common routing pitfalls and how to plan around them. The examples use the ZeDaq.ai script-tag widget, which is the same one described in the guide to virtual try-on for WooCommerce and other script-tag stores.

Why do widgets misbehave in single-page apps?

On a classic store, every link loads a new HTML page. Scripts in that page start fresh each time.

In an SPA, client-side routing changes the URL and the visible content without a full reload. Scripts in the page stay loaded, and nothing tells them the page has "changed".

That causes two opposite problems. A widget can fail to appear on the new page, or it can stay on screen after the shopper has left the product.

What does the ZeDaq.ai widget do when it loads?

The widget is one script tag with your key, as described in the widget documentation:

<script src="https://www.zedaq.ai/widget/zedaq.js" data-key="YOUR_WIDGET_KEY" defer></script>

Reading the widget script as we checked it in November 2026, it behaves like this:

  • It starts once, when the page finishes loading.
  • It looks for a product image on the page, using data-product-image if you set it.
  • If it finds no product image, it stops and shows nothing.
  • It adds one button, either floating or inside the element you name in data-target.
  • It does not watch for route changes after that.

This is how many simple script-tag widgets work, and it suits stores where each product has its own page load. Check the current script and docs before relying on any detail, since they can change.

What are the common routing pitfalls?

Pitfall 1: The first page is not a product page

A shopper lands on your home page, and the script starts there. It finds no product image and stops. When they click through to a product using client-side routing, the script does not run again.

The result is a product page with no button, even though the same page works when opened directly.

Pitfall 2: The button stays from the last product

The opposite case is a shopper who lands on a product first. The widget reads that product's image once. If they then move to another product without a reload, the old button and image remain.

A shopper could try on the wrong garment. Test this path on purpose.

Pitfall 3: The target element does not exist yet

If you use data-target to place a button inline, the element must exist when the script starts. In an SPA, the product component may render later than the script.

Pitfall 4: Loading the script in the wrong place

Putting the tag in a component can load it more than once, or never. Putting it in the base HTML shell loads it once, which brings back Pitfalls 1 and 2.

Pitfall 5: Hydration changes the page

Frameworks that render on the server and then take over in the browser can replace elements after load. A button added before that handover may be removed.

How do you plan around these pitfalls?

You have three practical options. Pick the one that matches how your store is built.

  1. Use full page loads for product URLs. If your framework lets product pages be served as normal documents, the script starts fresh on each one. This is the simplest fix when it is possible.
  2. Load the script only on product routes. Add the tag when the product route mounts, and test what happens when the shopper moves between products. Because the widget starts only once per full page load, you may need a reload on navigation between products.
  3. Build the experience with the API. If you control the front end, call the try-on endpoint from your server and render the button as part of your own component. Your component then follows your router naturally.

The third option takes more work. It is the route for headless and custom builds, because the UI stays in your code.

How do you test routing properly?

Open the store in a fresh tab and test these paths, in this order:

  • Load a product URL directly. The button should appear.
  • Load the home page, then click to a product. Check for the button.
  • Go from one product to another. Check that the product shown in the try-on window matches the page.
  • Press the browser back button. Check for duplicate or missing buttons.
  • Use a slow network setting in your browser tools to catch timing problems.

Write down the result of each path. When you change your theme or framework, repeat the list.

Where do other platforms fit in?

Classic platforms with full page loads avoid most of this. If you run WooCommerce, the guide to WooCommerce hooks for a try-on button shows where to place the tag. On Wix, adding custom code to product pages covers the page-level options.

Building a custom storefront? Start with the API

FAQs

Does the widget work on a React or Vue storefront?

It can, if the script starts on a page that contains the product image and you don't depend on client-side navigation between products. For anything more dynamic, test the paths above or use the API.

Why does the button not show after I click a product?

The script starts once per full page load and does not listen for route changes. If you arrived by client-side navigation, reload the product page to confirm the setup is correct, then fix the load order.

Do I need to lock my key to a domain in an SPA?

Yes. The widget key is visible in your page source, so it must be locked to your store's domain in the dashboard under API keys. Unlocked keys are refused.

Should I use the widget or the API for a headless store?

If your product pages navigate without a reload, the API gives you more control. If they load as full pages, the widget is usually quicker to set up.

Try ZeDaq.ai free

Virtual try-on and Find my size for your store, plus client, order and invoicing tools for tailors, in one subscription.

Related articles