@parhelia/next
v1.0.12951
Published
Serve a Next.js rendering head in the Parhelia editor: withParhelia() for next.config.js (/config), plus the React bindings of @parhelia/react and everything of @parhelia/head under the same entries (the editing bridge, slot markers, the in-place refresh,
Readme
@parhelia/next
Serve a Next.js rendering head in the Parhelia editor. Plain JavaScript, no build step: it can be copied into a head that is built elsewhere.
// next.config.js
const { withParhelia } = require('@parhelia/next/config');
module.exports = withParhelia({ /* the head's config, or a config function such as next-compose-plugins' */ });// pages/_app.tsx (or a client component of the App Router layout)
import { ContentfulLivePreviewProvider } from '@contentful/live-preview/react';
import { ParheliaBridge, withBasePath } from '@parhelia/next';
import { contentfulLivePreviewOrigins } from '@parhelia/next/contentful'; // a CMS's own helpers: its entry
<ContentfulLivePreviewProvider locale={locale} targetOrigin={contentfulLivePreviewOrigins()}>
<ParheliaBridge />
{children}
</ContentfulLivePreviewProvider>;
// a root-relative URL below the rendering proxy: a browser fetch, or markup (the server render writes the same URL)
fetch(withBasePath('/api/content'), { method: 'POST', body });
<img src={withBasePath('/logo.svg')} alt="" />;| Setting | Read | Effect |
|---|---|---|
| PARHELIA_RENDERING_PROXY_PATH (/parhelia/proxy/<head name>) | at build | the basePath; NEXT_PUBLIC_BASE_PATH is read when it is unset, / means none |
| PARHELIA_ORIGIN (e.g. https://cms.example.com) | at build | the editor may frame the head directly (CSP frame-ancestors; X-Frame-Options gives way to the same list), and the browser loads the editing bridge from it |
Both come from the head's Head settings block in Parhelia (Settings › Rendering Hosts).
- Proxy mode (the editor frames
/parhelia/proxy/<head name>/…from its own origin) needs only the base path:contentfulLivePreviewOrigins()adds the page's own origin in the browser, and Parhelia injects the bridge itself. Moving the editor to another origin needs no rebuild. - Direct mode (the editor frames the head's own URL) needs
PARHELIA_ORIGIN: the framing rule, the Live Preview target and the bridge (ParheliaBridgeloads it after hydration on?parhelia=1, only in a cross-origin frame;ParheliaBridgeScriptrenders it into the server's HTML instead, with a CSP nonce: see@parhelia/react).
Without withParhelia the helpers fall back to nothing: no basePath, no Parhelia origin.
Server render and browser read the same values
withParhelia inlines both values into the head's bundles and adds @parhelia/next to transpilePackages (after the
head's own entries). That entry matters: Next.js inlines only into code it bundles, and the Pages Router's server loads a
package from node_modules at run time instead (webpack and Turbopack alike). Without it, withBasePath('/logo.svg')
rendered /logo.svg on the server and /parhelia/proxy/<head name>/logo.svg in the browser: a broken URL in the server's
HTML and a hydration mismatch. A head that lists the package in serverExternalPackages keeps it external (Next.js
refuses a package in both lists) and renders on the server with what the server's own environment sets.
A CMS's own helpers live in its entry (@parhelia/next/contentful). The root still re-exports contentfulLivePreviewOrigins
and CONTENTFUL_APP_ORIGINS for heads built before the entry existed (deprecated; removed in 2.0).
Everything else: @parhelia/head and @parhelia/react
This package is the Next.js adapter over @parhelia/head, which holds everything a head renders with
whatever its framework (the frame-mode marker and empty-component hints, the rendered identity /identity, the editor signal
/server, rich-text sanitising /rich-text, the in-place refresh /refresh, the CMS entries /contentful and
/umbraco), and @parhelia/react, its React components (ParheliaBridge,
ParheliaBridgeScript, ParheliaSlot, useParheliaRefresh). Every entry of this package but /config is the same-named
entry of @parhelia/head, and the root also re-exports @parhelia/react: the very same bindings, so existing imports keep
working; read their documentation there. withParhelia transpiles all three packages, so the server render reads the
build's values as the browser does.
