Releases: nicknow/pagelively
Releases · nicknow/pagelively
Release list
v1.4.0 - Raw Markdown hosting
Added
- Raw Markdown pages — a new
raw-markdownpage kind publishes a.md/.markdownfile verbatim with no HTML conversion: no rendering, no template, noindex.html. The file is stored as a singlesource.mdobject with content typetext/plain; charset=utf-8, so visiting the slug/id URL redirects to the CDN object and the browser displays the raw Markdown as text. - Available on both upload and paste tabs; the dashboard shows a dedicated kind badge and the edit page hides the show-source control (the page is the source).
- Password-protected raw pages are streamed by the Worker with
Cache-Control: no-store, never exposing the CDN URL.
Mode switching between rendered and raw is explicitly not supported. See ADR 0054.
Full Changelog: v1.3.0...v1.4.0
v1.3.0 - Markdown template system with dark mode
What's Changed
Full Changelog: v1.2.0...v1.3.0
Markdown template system with dark mode
Added
- Markdown template system — public Markdown pages now render through a full HTML template
with readable typography, responsive layout, and automatic dark mode via
@media (prefers-color-scheme: dark)(no JavaScript). Templates live in a new
src/templates/module behind an extensible registry; unknown template names fall back to
the"default"template rather than failing.MarkdownRenderOptionsgains an internal
template?: stringfield, laying the groundwork for future per-page theme selection without
requiring a migration today. The<base>-injection,{{CONTENT}}slot,showSource, and
raw-HTML contracts are all unchanged. See ADR 0053.
Changed
- Edit form save confirmation — saving page metadata now shows a green "Page updated."
success toast, then reloads after a 1.5-second delay, instead of reloading immediately. The
error path is unchanged.
v1.2.0 - Tags, listing pages, settings, and UI polish
What's Changed
Full Changelog: v1.1.0...v1.2.0
Tags, listing pages, settings, and UI polish
Added
- Tags — pages can have zero or more tags (comma-separated labels). Tags are set on upload
or edit, stored in a junction table, and accessible via the admin API. See the
user guide. - Listing pages — a special page kind that dynamically renders a list of all public pages
matching ALL configured tags. Listing pages are created by selecting "Listing page" from the
Page kind selector on upload or paste forms. See the user guide. - Settings — a new
/admin/settingspage lets operators configure a default page slug
served at the root URL, overriding env-var-based configuration. Managed via
GET/PATCH /api/settings. - AI guidance — a new section in the README tells AI agents how to create
Pagelively-compatible content (relative paths, inline CSS, self-contained bundles).
Changed
- Back navigation — on edit and upload pages, the Back/Cancel buttons have moved from the
bottom form toolbar to a top-left navigation bar with an arrow icon, matching common web app
patterns. - Date formatting — dashboard dates now render in
<time datetime="...">elements and are
formatted client-side usingIntl.DateTimeFormatwith the user's browser locale, instead of
raw ISO-8601 strings.
Fixed
- Publishing a multi-file bundle whose entry is a Markdown file (e.g. multiple
.mdfiles, or
a.mdfile alongside images/assets) stored the page'sentry_pathat the original upload
path (e.g.site/index.md) instead ofindex.html— the path R2 actually stores the
rendered entry under. Every such page 404'd when visited.entry_pathnow matches the stored
object for bundle pages with a Markdown entry, consistent with the top-levelmarkdownkind. - Tags on a page were not persisted across page reloads on the edit form — the tags input now
pre-fills with existing tags from the database. - Listing pages returned a 404 when visited because the serving logic tried to read the entry
HTML from R2 before checking the page kind. Listing pages (which have no uploaded files) now
render before the R2 lookup occurs. - Listing pages matched pages having ANY of the configured tags instead of ALL. The SQL query
now usesGROUP BY … HAVING COUNT(DISTINCT tag) = nto require all specified tags. parseTags()was scoped inside the upload page's inline script and unavailable to the edit
page, causing aReferenceErrorwhen saving tags on the edit form. Moved to the shared
SHARED_JSblock.- A duplicate
const isPasteListingdeclaration in the paste form submit handler would throw a
SyntaxErroron paste form submission. Removed the re-declaration.
v1.1.0 - Password protection & multi-domain support
What's Changed
- ci(process): add development integration branch and PR gate workflow by @nicknow in #1
- chore(release): sync main with development by @nicknow in #2
Full Changelog: v1.0.0...v1.1.0
Password protection & multi-domain support
Added
- Per-page password protection (S23): admins can set or clear one password per page on create
or edit (min 5 chars, max 256; empty = not protected). Visitors see a server-rendered
password prompt; a successful unlock sets an opaque-token HttpOnly cookie (pl_unlock).
Protected pages bypass the CDN — all entry HTML, image bytes, and assets are served by the
Worker withCache-Control: no-storeand a Worker-origin<base>href. See ADR 0041 for
the locked design decisions, OQ-19..OQ-24 for the open-questions log, and §10 of the roadmap
for the full slice table.
Fixed
setup.mjsnow detects and rejects deployments that would silently corrupt an existing
deployment when run with the same projectName but different workerDomain/cdnDomain. A
multi-domain collision guard (checkDomainCollisions) queries the real Cloudflare API to
find existing Worker and R2 custom-domain associations before creating or modifying any
resource, and aborts with an actionable error message when a collision is detected. An
explicit opt-in override (SETUP_ALLOW_REPOINT) is available for deliberate repointing.
See ADR 0044 for the detection heuristic and rationale.setup.mjsnow rewrites the top-levelnamefield inwrangler.tomlso that the Worker
script targets the correct name when deploying to multiple domains from the same checkout.
A newderiveWorkerName()helper mirrors the existingderive*Namehelpers.
Changed
- CI process: switched to a
feature → development → mainbranching workflow. Feature
branches PR intodevelopment(the integration branch), andmainonly moves when a
human deliberately promotesdevelopmentinto it for release. A CI workflow runs the
full local gate (typecheck, lint, format:check, test) on PRs intodevelopment/main
and pushes todevelopment.
v1.0 - Initial Release
The initial production ready release of Pagelively.