# Widget not showing

The change button never appears on the client site.

## Symptom

The site loads, and **Request a change** (**Demander un changement** / **Solicitar un cambio**) is not on the page.

## Causes

### The access marker is missing or was changed

On a site without login, the script hides the button until the page URL contains the marker. The default marker is `modifee`, so the link looks like `https://client.example/?modifee`.

**Confirm.** Open the site with no extra query string. The button is absent. Open the link from **Settings → Client access**. The button appears. The browser console does not warn about a missing script. After you change the marker, the old link no longer unlocks a new tab. The save confirm says "The old link will stop working. Send the new link to your client."

**Fix.** Send the current link. The marker is the query key, 3 to 64 letters, digits, `_`, or `-`. It cannot be `page`, `id`, `q`, `s`, `ref`, `fbclid`, `gclid`, or a name that starts with `utm_`. See [Access marker](https://www.modifee.com/docs/client-access/access-marker).

A site with login skips this gate when `data-token` is set. If that attribute is empty, the console says "Modifee: data-project and data-token are required". See [Token errors](https://www.modifee.com/docs/troubleshooting/token-errors).

### The script did not load

**Confirm.** In the browser network panel, the request for `widget.js` is missing, failed, or blocked. The console may say "Modifee: missing script element" or "Modifee: data-project is required". **Settings → Widget install** stays yellow: "Widget not found on the site". **Check installation** then reports one of these:

- "The widget on this page belongs to another project."
- "We couldn't find the widget on" the site URL. "Paste the snippet just before `</body>` and check again."
- "We couldn't reach" the site URL, then "Connection failed", "Timed out", or "HTTP" and a status. "The widget will be marked installed as soon as it loads on the site."
- "This page is rendered in the browser, so the widget script is not in the HTML we fetched from" the site URL.

**Fix.** Paste the snippet for this project and deploy. The `src` must be the Modifee `widget.js`, and `data-project` must be this project's public key. A browser-rendered page can still be fine: open the live site so the script can ping. The install mark turns green once that ping arrives, or once the HTML check finds this project's key. Install guides: [Next.js App Router](https://www.modifee.com/docs/install/nextjs-app-router), [Next.js Pages Router](https://www.modifee.com/docs/install/nextjs-pages-router), [HTML](https://www.modifee.com/docs/install/html), [Other frameworks](https://www.modifee.com/docs/install/other-frameworks).

### The tab forgot the marker

The script stores the unlock in `sessionStorage` under a key that starts with `modifee:access:` and ends with the project public key. The value is `1`. That lasts for the tab only.

**Confirm.** The button was visible, then a new tab or a cleared site storage hides it. The same tab still shows it. Ctrl+Shift+M shows it again and writes that storage key.

**Fix.** Open the marker link again, or press Ctrl+Shift+M. Do not rely on `sessionStorage` as the way clients get in. Send the link.

### Widget install looks fine, but the button is hidden

A green **Widget install** mark means the script loaded or the HTML contained this project's key. It does not mean the button is visible. The marker can still be hiding it.

**Confirm.** The section mark is green, or the check says the snippet matches, and the button is still absent without the marker link.

**Fix.** Use the marker link from [Access marker](https://www.modifee.com/docs/client-access/access-marker). If the check says the widget belongs to another project, replace the snippet with this project's key.

### The site URL is not HTTPS

**Confirm.** **Settings → Connection** is yellow: "Site URL must be a valid https address". **Check installation** cannot use an address that is not `http` or `https`, or a localhost, `.local`, or private-network host. Those come back as "We couldn't reach" the URL.

**Fix.** Save a public `https` URL, deploy the site there, and press **Check installation** again.

### An ad blocker stopped the script

**Confirm.** The network panel shows `widget.js` blocked by the client. Disabling the blocker makes the button appear. No Modifee error is returned.

**Fix.** Ask the client to allow `widget.js` from the script origin on that site. The usual origin is `https://www.modifee.com`.

### The site's Content Security Policy blocks the script

`widget.js` does four things that a strict policy can reject. Use the origin of the script `src`. The default install uses `https://www.modifee.com`.

- It loads as a classic script. Allow that origin in `script-src`.
- It calls `fetch` on `/api/widget/unlock`, `/api/widget/ping`, and `/api/widget/public-config` on that same origin. Allow it in `connect-src`.
- It creates an iframe at `/widget/` plus the public key, with `allow="microphone"`. Allow that origin in `frame-src`.
- It injects a `<style>` element inside a closed shadow root, with no nonce. Allow `style-src-elem 'unsafe-inline'`. If you only set `style-src`, that needs `'unsafe-inline'` as well, because the style element cannot carry your page nonce.

**Confirm.** The console reports a Content Security Policy violation for `widget.js`, for a `fetch` to the Modifee origin, for the iframe, or for an inline style.

**Fix.** Add the directives above for the script origin, deploy, and reload. If the page sets a Permissions Policy that omits `microphone` for that origin, dictation inside the iframe is blocked. The button itself still appears. See [MDF-WIDGET-005](https://www.modifee.com/docs/errors/MDF-WIDGET-005) when the open widget says "We can't reach the team right now. Try again in a few minutes."
