Skip to Content
GuidesCMS Pages

CMS Pages

The Admin → CMS Pages section lets you edit the public-facing static pages of your PicPeak instance — the legal pages every German-hosted instance needs (/datenschutz, /impressum), the “Gallery Not Found” copy guests see when an archived gallery’s URL is hit, and any custom pages you want to add.

Built-in CMS pages

These pages exist by default and are editable:

SlugURLWhen shown
impressum/impressumLinked in the gallery footer (German legal requirement)
datenschutz/datenschutzLinked in the gallery footer (privacy policy)
gallery-not-foundrendered when a gallery URL doesn’t resolveArchived event, deleted event, typo’d slug
page-not-foundrendered for any other 404Catches non-gallery 404s
gallery-expiredshown for events past expires_at but not yet archivedBrief window between expiry and archive

The “Gallery Not Found” and “Page Not Found” pages are intentionally distinguished — they let you write different copy for “I expected a gallery but it’s gone” vs “I followed a broken link to your site.”

Editing

The editor is rich-text (TipTap-based), with HTML output. Supported elements include headings, paragraphs, lists, links, images, blockquotes. Inline HTML pasted from another tool is sanitised on save (<script>, <iframe> removed; URL attributes validated).

Each page has:

  • Title — used as the <title> tag
  • Body — the rich-text content
  • Meta description — used in <meta name="description"> (search-result snippet)
  • Visible toggle — pages can be hidden without being deleted

Adding a custom page

Click + Add Page:

  • Slug — URL fragment (/{slug}). Letters, digits, and hyphens only.
  • Title, Body, Meta description — same as built-ins.

Custom pages are served at /{slug} and use the same gallery footer/header chrome as the built-in pages. Useful for things like an “About Us”, “FAQ”, “Pricing”, or photographer biography page.

Templating

The CMS body supports the same brand-token substitutions as the public landing page (set in Branding):

{{ company_name }} {{ company_tagline }} {{ support_email }} {{ brand_logo_url }} {{ brand_primary_hex }}

These substitute at render time, not edit time — so changing your company name in Branding propagates to every CMS page automatically.

Per-language content

If your instance serves multiple languages, the rich-text editor doesn’t (yet) split content per locale. The recommended pattern is to use bilingual copy in the body and rely on the visitor to scroll to their language, or maintain duplicate pages with a slug suffix (e.g. impressum, impressum-en).

A proper i18n flow for CMS pages is on the roadmap.

Where it’s served

CMS routes are mounted under the public router and bypass admin authentication. Pages are cached in process memory for 60 seconds; saving in the admin invalidates the cache immediately so changes are visible on next request.

Last updated on