Known Issues & Platform Quirks
P1 is in alpha. Everything on this page is a real, reproduced issue we hit while building Herradura, not speculation. Some of these may already be fixed by the time you read this; if you find one resolved, update or remove the entry rather than leaving stale info here.
Platform gaps & limitations: the master list
The sections below this one are specific bugs and traps we hit and reproduced. This section is different: it’s the consolidated index of every structural platform gap (something P1 simply doesn’t do yet) discovered while writing this documentation, gathered in one place so “what does P1 not do today” has a single answer instead of being scattered across a dozen pages. Each line links to the page with the full evidence and the plan for closing the gap.
Content authoring & site structure
- No content localization/i18n mechanism. No locale field anywhere in the CCR data model; Puck’s own “Localization” feature only translates the editor’s UI, not site content. See Localization.
- No API-level site cloning or multi-site capability.
SitesEndpointonly exposesget()/list(): no create, no duplicate, no site-template mechanism; standing up a new market or brand site is a manual, one-at-a-time dashboard action. See Localization → Option B. - No write API for a Template’s layout. Template metadata (name, label, URL pattern) is scriptable; the actual component tree is editor-authored only, with no config-as-code export. See Templates.
- No relationship/reference field for editor-curated subsets. Listing every document of a Template is native, no custom code required, see Data Sources & Queries. Picking a specific, hand-curated set (these 3 cocktails, not all of them) is not: no filter parameter on the auto-generated query, no document-picker field type shipped anywhere in the SDK. See Content Relationships.
- No header/footer/site-chrome management. The starter kit ships a genuinely
blank canvas: no theme, no customizer, nothing equivalent to
header.php/footer.php. See Managing the Header & Footer. - No site-wide search. Zero search endpoint anywhere in the installed SDK. Full stop, not partially supported. See Site Search.
- No scheduled/future-dated publishing. The
Documenttype has nopublishAt/scheduledAtfield. Publish is immediate-only. See Publishing.
Forms & communication
- No native form builder. Neither P1 nor Puck ships end-user form-authoring tooling. See Form Builder.
- No durable form-submission storage. A CRM POST failure or validation error currently means silent data loss, with no record a submission ever happened. See Form Builder → Submission Storage.
- No email-sending capability at all. Zero transactional-email concept anywhere in the installed SDK. See Email Delivery.
Media
- WebP/AVIF delivery is supported but not automatic. Only one pre-built helper
(
createMediaFigureBlock) defaults to format-negotiated delivery; every other call site must opt in explicitly or ships with no format negotiation at all. See Media Library. - Alt text is supported but not enforced, and has no storage mechanism at all in basic mode. Whether rich-mode alt text is actually required is a Pantheon-side, platform-global schema decision this project can’t override. See Media Library.
- No cross-site asset sharing, no bulk-replace/“find everywhere used” tooling, and
only four fixed metadata field names (
alt,caption,credit,byline; no custom fields). See Media Library. - This project ships two competing “add an image” components, and only one uses
the media library. Confirmed from this project’s own editor code: the plugin is
active, but the Image block’s
srcfield doesn’t match any pattern that triggers the picker, so it silently stays a raw URL field. See Media Library → Why the Picker Isn’t Showing.
SEO
- No sitemap.xml, robots.txt, or JSON-LD structured data by default. Real gaps in the scaffold, not unique to P1, but a production site can’t ship without at least the first two. See Sitemap, Robots & Redirects.
- Redirects exist at the platform/API level but aren’t wired into this scaffold’s
rendering.
P1ContentClient.getRedirect()and a realRedirectInfotype (301/302/303/307/308, permanent/temporary) exist in the SDK, but nothing inapp/[...puckPath]/page.tsxcalls it, so a redirect created via the platform wouldn’t currently take effect on this site. See Sitemap, Robots & Redirects.
This list will grow as we cover more of the platform. Treat it as a living index, not a final tally. When a gap gets fixed upstream by Pantheon, or we finish building around it ourselves, move the line here instead of just deleting it, so there’s a record of what used to be a gap.
Pages don’t render immediately after creation
Created a page in the dashboard’s Site Structure editor (+Create new), on the Live
workstream, on the main branch. It appeared instantly in the dashboard’s page list.
Locally, visiting that page’s URL returned a genuine 404: “This page hasn’t been
created yet” (for roughly 30–45 minutes), then started rendering with no action
taken on our end (no explicit publish click, no site “launch”).
Now understood: see Workflows for the
full mechanism, confirmed by reading the SDK source directly: unauthenticated page reads
(every public/local render with no user logged in) only serve published checkpoints,
not raw draft versions. Editing in the Puck editor autosaves continuously as draft
versions; a separate, explicit “Publish” action (or, off the main branch, a
“Review and Publish” merge) is what creates the checkpoint the public read path
actually serves.
At the time, the dashboard’s per-page ”…” menu had no Publish/Unpublish action for a page created via “+Create new” in Site Structure: only Open in visual editor, Edit settings, View page content (JSON), and Delete. Our best read: the dashboard’s create flow likely does publish automatically, and the ~30-45 minute gap was propagation/ indexing delay on the publish pipeline rather than a genuinely missing action on our part, but we did not get a definitive confirmation of that from Pantheon, and the site also showed “Site status: Not launched” at the time, untested as a possible contributing factor.
What this means for you: if a page isn’t rendering on the public/local read path, first open it in the editor and confirm it’s actually been published (not just autosaved). See Publishing. If it has, and it’s still not showing, it might just need to propagate: give it up to an hour before assuming something’s broken.
CSS_API_KEY vs. P1_CSS_API_KEY: a real naming trap, not a typo
The token the P1 dashboard hands you when you generate a site token is easy to end up
labeling P1_CSS_API_KEY. The running app never reads that name. Every runtime
consumer (middleware.ts, the auth route, the editor page, the API route) reads
process.env.CSS_API_KEY only.
Confusingly, P1_CSS_API_KEY does appear elsewhere in the scaffolded starter kit: in
scripts/sync-puck-registry.ts (a separate CI script for syncing the Puck component
registry), where it’s referenced in a comment as “your read-scoped site token” and
explicitly guarded against. That script wants a third, differently-scoped token
(CSS_REGISTRY_API_KEY, needs write:registry scope) which you don’t need for local
dev.
So the starter kit’s own source treats P1_CSS_API_KEY as a real, expected name, just
not the one .env.example or the live app’s runtime code actually use. If you paste
your dashboard token in under that name, the app silently no-ops: no error, no
warning, it just behaves as though no key was set. Always use CSS_API_KEY in
.env.local for the site token.
@pantheon-systems/create-p1-starter-kit has no non-interactive mode
pnpm create @pantheon-systems/p1-starter-kit is fully interactive (built on
@clack/prompts), with no flags to skip the prompts. Can’t be scripted or driven
without a real TTY. If you need to scaffold headlessly (CI, an agent, etc.), the
workaround is to download the npm tarball directly and replicate what the CLI does:
copy template/ into the target directory, then stamp package.json’s name field
and add a p1.templateVersion entry: that’s the entirety of what the CLI does beyond
prompting.
Template ships without a .gitignore
Pantheon’s own getting-started guide calls this out as a manual step (“Add a
.gitignore”), so it’s expected, but worth knowing going in. Every new P1 project
needs a standard Next.js .gitignore added by hand.
“Private release” language in Pantheon’s docs is stale
Pantheon’s getting-started guide describes the starter kit as requiring manual
provisioning, implying the CLI itself is access-gated. In practice
@pantheon-systems/create-p1-starter-kit is public on npm: no special access needed to
run it. Unclear whether dashboard account access (content.pantheon.io) is still gated
separately.
The OpenAPI docs page is an empty stub
Pantheon’s docs site (live-p1-docs.pantheonsite.io/dev-guide/openapi) has an OpenAPI
page in the nav: it’s currently just a title with no content, no spec link. If you’re
looking for a REST API reference and land there, that’s not you missing something.
“Adding P1 to an existing Next.js site” is unwritten
The path you’d want if starting from an existing Next.js app rather than the starter kit is listed in Pantheon’s getting-started guide, but the section itself just says “Instructions coming soon.” No timeline given.
Harmless Yjs was already imported console warning
Shows up in next dev output out of the box on a freshly scaffolded project, not
something introduced by project code:
Yjs was already imported. This breaks constructor checks and will lead to issues!
- https://github.com/yjs/yjs/issues/438Likely a duplicate/mismatched yjs version pulled in by two different dependencies
(probably the Puck editor’s collaboration features). Didn’t visibly break anything in
testing, just noisy.