You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs: update configuration docs for siteUrl, add changeset
Update public docs, skills reference, and demo config to document
siteUrl replacing passkeyPublicOrigin. Add EMDASH_SITE_URL / SITE_URL
to env vars table. Changeset: minor bump with breaking-change note.
Adds `siteUrl` config option to fix reverse-proxy origin mismatch. Replaces `passkeyPublicOrigin` with a single setting that covers all origin-dependent features: passkeys, CSRF, OAuth, auth redirects, MCP discovery, snapshots, sitemap, robots.txt, and JSON-LD.
6
+
7
+
Supports `EMDASH_SITE_URL` / `SITE_URL` environment variables for container deployments where the domain is only known at runtime.
8
+
9
+
Disables Astro's `security.checkOrigin` (EmDash's own CSRF layer handles origin validation with dual-origin support and runtime siteUrl resolution). When `siteUrl` is set in config, also sets `security.allowedDomains` so `Astro.url` reflects the public origin in templates.
10
+
11
+
**Breaking:**`passkeyPublicOrigin` is removed. Rename to `siteUrl` in your `astro.config.mjs`.
Copy file name to clipboardExpand all lines: docs/src/content/docs/reference/configuration.mdx
+16-9Lines changed: 16 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -200,13 +200,13 @@ Use Cloudflare Access as the authentication provider instead of passkeys.
200
200
magic links, and self-signup are disabled.
201
201
</Aside>
202
202
203
-
### `passkeyPublicOrigin`
203
+
### `siteUrl`
204
204
205
-
**Optional.**Pass a full **browser-facing origin**(scheme + host + optional port, **no path**) so WebAuthn **`rpId`** and **`origin`** match what the user’s browser sends in `clientData.origin`.
205
+
**Optional.**The public browser-facing origin for the site (scheme + host + optional port, **no path**).
206
206
207
-
By default, passkeys follow **`Astro.url`** / **`request.url`**. Behind a **TLS-terminating reverse proxy**, the app often still sees **`http://`** on the internal hop while the tab is **`https://`**, or the reconstructed host does not match the public name — which breaks passkey verification. Set `passkeyPublicOrigin` to the origin users type in the address bar (for example `https://cms.example.com` or `https://cms.example.com:8443`).
207
+
Behind a **TLS-terminating reverse proxy**, `Astro.url` returns the internal address (`http://localhost:4321`) instead of the public one (`https://cms.example.com`). This breaks passkeys, CSRF origin matching, OAuth redirects, login redirects, MCP discovery, snapshot exports, sitemap, robots.txt, and JSON-LD structured data. Set `siteUrl` to fix all of these at once.
208
208
209
-
The integration **validates** this value at load time: it must be a valid URL with **`http:`** or **`https:`** protocol and is normalized to **`origin`**.
209
+
The integration **validates** this value at load time: it must be a valid URL with **`http:`** or **`https:`** protocol and is normalized to **origin** (path is stripped).
210
210
211
211
```js
212
212
emdash({
@@ -215,17 +215,23 @@ emdash({
215
215
directory:"./uploads",
216
216
baseUrl:"/_emdash/api/media/file",
217
217
}),
218
-
passkeyPublicOrigin:"https://cms.example.com",
218
+
siteUrl:"https://cms.example.com",
219
219
});
220
220
```
221
221
222
-
#### Reverse proxy and passkeys
222
+
When `siteUrl` is not set in config, EmDash checks environment variables in order: `EMDASH_SITE_URL`, then `SITE_URL`. This is useful for container deployments where the public URL is set at runtime.
223
+
224
+
<Asidetype="tip">
225
+
`siteUrl` replaces `passkeyPublicOrigin` (removed). If you were using `passkeyPublicOrigin`, rename it to `siteUrl` -- it now covers passkeys and all other origin-dependent features.
226
+
</Aside>
227
+
228
+
#### Reverse proxy setup
223
229
224
230
Astro only reflects **`X-Forwarded-*`** when the public host is allowed. Configure [**`security.allowedDomains`**](https://docs.astro.build/en/reference/configuration-reference/#securityalloweddomains) for the hostname (and schemes) your users hit. In **`astro dev`**, add matching **`vite.server.allowedHosts`** so Vite accepts the proxy **`Host`** header.
225
231
226
-
Prefer fixing **`allowedDomains`** (and forwarded headers) first; use **`passkeyPublicOrigin`** when the reconstructed URL **still** diverges from the browser origin (typical when TLS is terminated in front and the upstream request stays **`http://`**).
232
+
Prefer fixing **`allowedDomains`** (and forwarded headers) first; use **`siteUrl`** when the reconstructed URL **still** diverges from the browser origin (typical when TLS is terminated in front and the upstream request stays **`http://`**).
227
233
228
-
With TLS in front, binding the dev server to loopback (**`astro dev --host 127.0.0.1`**) is often enough: the proxy connects locally while **`passkeyPublicOrigin`** matches the public HTTPS origin.
234
+
With TLS in front, binding the dev server to loopback (**`astro dev --host 127.0.0.1`**) is often enough: the proxy connects locally while **`siteUrl`** matches the public HTTPS origin.
229
235
230
236
<Asidetype="caution">
231
237
Your reverse proxy should forward a **port-aware**`Host` / `X-Forwarded-Host` when you use non-default ports. If the proxy strips the port, **`rpId`** and Astro’s rebuilt URL can be wrong.
@@ -255,7 +261,7 @@ export default defineConfig({
255
261
directory:"./uploads",
256
262
baseUrl:"/_emdash/api/media/file",
257
263
}),
258
-
passkeyPublicOrigin:"https://cms.example.com",
264
+
siteUrl:"https://cms.example.com",
259
265
}),
260
266
],
261
267
});
@@ -435,6 +441,7 @@ EmDash respects these environment variables:
Copy file name to clipboardExpand all lines: skills/building-emdash-site/references/configuration.md
+24-2Lines changed: 24 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -32,9 +32,31 @@ export default defineConfig({
32
32
});
33
33
```
34
34
35
-
### Reverse proxy and passkeys
35
+
### Reverse proxy
36
36
37
-
Passkey `rpId` / `origin` follow Astro `context.url`, which only reflects `X-Forwarded-*` when you declare **allowed public hosts** ([`security.allowedDomains`](https://docs.astro.build/en/reference/configuration-reference/#securityalloweddomains)). In dev, add matching **`vite.server.allowedHosts`** or Vite rejects the proxy `Host`. Use **`emdash({ passkeyPublicOrigin: "https://…" })`** when the browser origin and reconstructed URL still disagree (common with TLS termination). With TLS terminated in front, **`astro dev --host 127.0.0.1`** (loopback) is usually enough: the proxy reaches the dev server locally while **`passkeyPublicOrigin`** matches the browser’s HTTPS origin—without opening the Node port on the LAN.
37
+
When behind a TLS-terminating reverse proxy, `Astro.url` returns the internal address (e.g. `http://localhost:4321`) instead of the public one (`https://mysite.example.com`). This breaks passkeys, CSRF, OAuth, redirects, and more.
38
+
39
+
**Step 1:** Declare allowed public hosts via [`security.allowedDomains`](https://docs.astro.build/en/reference/configuration-reference/#securityalloweddomains) so Astro reconstructs the URL from `X-Forwarded-*` headers. In dev, add matching **`vite.server.allowedHosts`** or Vite rejects the proxy `Host`.
40
+
41
+
**Step 2:** If the reconstructed URL still disagrees with the browser (common with TLS termination), set **`siteUrl`**:
42
+
43
+
```javascript
44
+
emdash({
45
+
siteUrl:"https://mysite.example.com",
46
+
// ...
47
+
});
48
+
```
49
+
50
+
Or via environment variable (useful for container deployments):
51
+
52
+
```bash
53
+
EMDASH_SITE_URL=https://mysite.example.com
54
+
# or: SITE_URL=https://mysite.example.com
55
+
```
56
+
57
+
`siteUrl` replaces `passkeyPublicOrigin` (which only fixed passkeys). It applies to passkeys, CSRF origin matching, OAuth redirects, login redirects, MCP discovery, snapshot exports, sitemap, robots.txt, and JSON-LD structured data.
58
+
59
+
With TLS terminated in front, **`astro dev --host 127.0.0.1`** (loopback) is usually enough: the proxy reaches the dev server locally while **`siteUrl`** matches the browser’s HTTPS origin -- without opening the Node port on the LAN.
0 commit comments