[#embedding-iframe] = Embedding OliveTin in an iframe You might want to show OliveTin inside another web page, such as a Home Assistant dashboard (Webpage card), Homarr, Organizr, Heimdall, or your own HTML page. These pages show OliveTin using an ` ---- === Checking what OliveTin is sending If it still does not work, check the headers that are actually being sent. Run this from a terminal, using the address you use to reach OliveTin: [source,shell] ---- curl -sI https://olivetin.example.com/ | grep -i -E 'content-security|x-frame' ---- You should see your dashboard's origin in the `frame-ancestors` part, and no `X-Frame-Options` line. If you still see `frame-ancestors 'none'`, your config change has not been applied. See the troubleshooting section below. == Troubleshooting [cols="2,3"] |=== | What you see | What to do | The error still says `frame-ancestors 'none'` a| OliveTin is still sending its default policy. Check that: * the keys are indented under `security:` and spelled exactly as shown, including upper and lower case letters (`contentSecurityPolicy` starts with a lower case `c`). * you edited the `config.yaml` that OliveTin is actually using (check the OliveTin startup logs). * you replaced `'none'` in the line you pasted. Older examples on the xref:security/content_security_policy.adoc[Content Security Policy] page still contain `'none'`. * a reverse proxy is not adding its own `Content-Security-Policy` header (see below). | The error lists your dashboard, but it is still blocked | The origin does not match exactly. Compare it carefully with the output of `location.origin` from Step 1. The most common mistakes are `http` vs `https`, a missing port number, or using an IP address in one place and a hostname in the other. | `Refused to display ... in a frame because it set 'X-Frame-Options' to 'deny'` | Add `headerXFrameOptions: false` under `security:`, as shown in Step 2. You may also see this if your reverse proxy adds its own `X-Frame-Options` header. | `Mixed Content: The page at 'https://...' was loaded over HTTPS, but requested an insecure frame 'http://...'` | Your dashboard uses `https://` but OliveTin uses `http://`. Browsers do not allow this, and no OliveTin setting can change it. Serve OliveTin over HTTPS too, for example behind a xref:reverse-proxies/intro.adoc[reverse proxy]. | The iframe works, but you have to log in every time or logging in does nothing | See <>. |=== === Reverse proxies Some reverse proxies and proxy add-ons (for example Traefik security header middlewares, Nginx Proxy Manager "block common exploits", or authentication proxies) add their own `Content-Security-Policy` or `X-Frame-Options` headers. Browsers enforce *every* policy they receive, so a strict policy from your proxy will still block the iframe even after you have changed OliveTin. To find out if this is happening, run the `curl` command from Step 3 twice: once directly against OliveTin (for example `http://192.168.1.10:1337/`) and once against the address that goes through your proxy. If the results are different, change the headers in your proxy configuration as well. [#logins-in-iframes] === Logins inside an iframe If you use xref:security/local.adoc[local users] or xref:security/oauth2.adoc[OAuth2], OliveTin remembers that you are logged in using a cookie. Browsers only send OliveTin's cookie to an iframe when the parent page and OliveTin are on the **same site**. The same site means the same scheme (`http` or `https`) and the same main domain. Subdomains and port numbers can differ. [cols="2,2,1"] |=== | Dashboard | OliveTin | Login works in iframe? | `https://ha.example.com` | `https://olivetin.example.com` | Yes | `http://192.168.1.50:8123` | `http://192.168.1.50:1337` | Yes | `https://ha.example.com` | `https://olivetin.otherdomain.net` | No | `https://ha.example.com` | `http://192.168.1.50:1337` | No |=== If your setup is in the "No" rows, the easiest fix is to make OliveTin available on a subdomain of the same domain as your dashboard, usually with a xref:reverse-proxies/intro.adoc[reverse proxy]. Many OAuth2 login providers also refuse to show their login page inside an iframe. If the login page does not appear, open OliveTin in a normal browser tab, log in there, and then reload your dashboard. This only works when the parent page and OliveTin are on the same site, as described above.