Content-Security-Policy¶
If your shop sends a Content-Security-Policy header (or a <meta http-equiv> equivalent), the browser blocks anything
the policy does not allow. This page lists exactly what the Ziex Try-On widget needs. It describes the widget as released
today (phase 1); the section What changes next says what is planned.
You do not need any of this when your page has no CSP.
What to allow¶
| Directive | Value to add | Why |
|---|---|---|
script-src |
https://api.ziex-tryon.com |
The widget (tryon-embed.js) and the loader (tryon-loader.js) are served from the API host. |
connect-src |
https://api.ziex-tryon.com |
Every request the widget makes (sending a try-on, status, the list of categories, the saved copy of a result) goes to the API host. |
img-src |
https://api.ziex-tryon.com https://media.ziex-tryon.com data: blob: plus your own image hosts |
media.ziex-tryon.com serves the result pictures; data: is used for previews of the shopper's photo; blob: for the thumbnails and the full-size view in "My looks". Product pictures are loaded through <img>, so the hosts that serve them (your shop's or its CDN) must be allowed here. |
style-src |
'unsafe-inline' |
The widget puts a <style> element into its own shadow root and uses a few inline style attributes. |
Notes:
- The widget does not use
frame-src,font-src,media-src,worker-srcorobject-src. - Product pictures are not fetched with
connect-src. The widget loads them as images, soimg-srcis the directive that matters for them. If the CDN sends CORS headers, the widget downsizes the picture in the browser; without them it sends the picture's address instead and our server fetches it. - If your policy has no
script-src,connect-srcorimg-src, the browser falls back todefault-src. Add the hosts to whichever directive your policy actually has.
A complete header¶
A shop that serves everything from its own domain and its product pictures from cdn.shop.example:
Content-Security-Policy: default-src 'self'; script-src 'self' https://api.ziex-tryon.com; connect-src 'self' https://api.ziex-tryon.com; img-src 'self' https://cdn.shop.example https://api.ziex-tryon.com https://media.ziex-tryon.com data: blob:; style-src 'self' 'unsafe-inline'
The same policy with one directive per line, to read it more easily (a header must be a single line):
default-src 'self';
script-src 'self' https://api.ziex-tryon.com;
connect-src 'self' https://api.ziex-tryon.com;
img-src 'self' https://cdn.shop.example https://api.ziex-tryon.com https://media.ziex-tryon.com data: blob:;
style-src 'self' 'unsafe-inline'
Add the Ziex Try-On hosts to the policy you already have; do not replace it. Keep your other directives as they are.
As a <meta> tag¶
If you cannot set headers, a <meta> tag in <head> works for these directives:
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self' https://api.ziex-tryon.com; connect-src 'self' https://api.ziex-tryon.com; img-src 'self' https://cdn.shop.example https://api.ziex-tryon.com https://media.ziex-tryon.com data: blob:; style-src 'self' 'unsafe-inline'">
Put it before the first <script>. A <meta> policy cannot carry frame-ancestors, report-uri or sandbox; those
need a real header.
Two things that are blocked under a strict policy¶
1. The inline onerror of the product preview. The window shows a small preview of the garment. If the picture
cannot be loaded, the widget hides it with an inline onerror handler. Under a script-src without 'unsafe-inline'
that handler is blocked, so a broken preview stays on screen as a broken-image icon. It is cosmetic: the try-on itself is
not affected. Make sure the product picture address is correct and the host is in img-src.
2. Inline configuration from a CMS. The usual way to pass the configuration is an inline script that calls
TryOn.init({ … }), for example one added by wp_add_inline_script in WordPress. Under a strict script-src an inline
script is blocked unless it carries a nonce or a hash. Use the nonce mechanism of your CMS or framework, or move the
init() call into a small script file you serve yourself and allow with 'self'.
A nonce or hash in style-src turns 'unsafe-inline' off
Browsers ignore 'unsafe-inline' in a directive that also contains a nonce or a hash. If your style-src has
one, the widget's <style> element is blocked and the window is drawn without its styles. Until a nonce is
supported (see below), style-src must contain 'unsafe-inline' without a nonce or a hash.
'strict-dynamic'
With 'strict-dynamic' the browser ignores host names in script-src. Give your own <script> tags the nonce
instead. The loader adds the widget script from code, which 'strict-dynamic' allows when the loader itself was
allowed by a nonce. Check it in the console as described below.
How to check¶
- Open the product page with the browser's developer tools open on the Console tab. Open the window and press
"Try on" (a test key is enough). The browser prints a line for each blocked request, such as
Refused to connect to 'https://api.ziex-tryon.com/…' because it violates the following Content Security Policy directive: "connect-src …". The directive named in the message is the one to fix. - In the Network tab, a blocked request is shown as
(blocked:csp). - Roll the change out safely first with
Content-Security-Policy-Report-Only: it takes the same value, blocks nothing and only reports. Addreport-uri https://your-endpoint.example/csp(orreport-to) to collect the reports from real visitors, and switch to the enforcing header when the reports are clean.
What each failure looks like:
| What is blocked | What you see |
|---|---|
script-src |
No launcher and no TryOn object: window.TryOn is undefined. |
connect-src |
The launcher is drawn (the check that hides it when your limit is used up fails open), but a try-on ends with a connection-lost message. |
img-src |
Broken pictures: the garment preview, the result, or the thumbnails in "My looks". |
style-src |
The window appears without its styles. |
What changes next¶
A later release of the widget will remove the need for 'unsafe-inline' in style-src: the widget will be drawn
without inline styles and will accept a nonce from the page. That is not released yet. Until it is, use the
directives above. When it ships, this page will say so, and the directives here will keep working.
Related: Widget reference, Lazy loading and pickup.