Legal pages¶
The Legal pages — Privacy Policy and Terms of Service — are the app's legal copy, served as
public, unauthenticated pages at the site root (not behind /api/ and not a mobile-app payload).
They exist to give the app store listings, the app's own webview, and the future cslewis.com
marketing site one canonical URL each, backed by content that editors keep current in the CMS.
Where they live¶
One title plus a block-based body per page, edited from a single Settings → Legal pages screen
(data.models.legal.LegalSettings) — not a Page and not a snippet list, because there's exactly one
of each and no draft/publish workflow is needed. The body is a StreamField of Text and Table
blocks: a RichTextField can't hold a table, and the Privacy Policy has one. See
ADR-0008 for why content in this repo stays off the Wagtail
page tree; this doesn't reintroduce one.
Where they're served¶
| Page | App store URL | Mobile webview |
|---|---|---|
| Privacy Policy | /privacy-policy/ |
/privacy-policy/?format=embed |
| Terms of Service | /terms-of-service/ |
/terms-of-service/?format=embed |
The plain URL renders a browsable HTML page, so it can be pasted straight into an app-store listing as the Privacy Policy / Terms URL — the point is to unblock app-store submission before the cslewis.com marketing site exists. It's intentionally bare and unbranded (no header, nav, or footer).
The mobile app loads ?format=embed in its in-app webview. This variant must never show site
chrome. The page is bare today, so embed is a stub that sets an embed flag on the template; the
flag is the hook that strips a header, nav, or footer if the plain page ever gains one (for example
a branded marketing view).
No auth, no X-API-Key — the same public-surface pattern as the app-association files and sign-in
landing described in ADR-0003, because a store reviewer or an
external site can't carry either.
See also¶
- Editor Guide — where to edit the copy and what formatting is available.