Next.js
Goodfellow pages and the admin panel in a Next.js app, exported as static files, and how it compares with goodfellow build.
@goodfellow-cms/next puts a Goodfellow site in a Next.js app (App Router, Next.js 16), exported as static files so the same free hosts serve it. The Starter for Next.js has it all set up.
withGoodfellow()innext.config.tsexports static files with a folder per page, serves the site frombasePath(orGOODFELLOW_BASE), and innext devruns the admin panel's local backend, which saves to the files on disk. The local backend is never part of a build.goodfellowPages(config)gives the routes their parts:Layoutforapp/(site)/layout.tsx, which shows the header and footer once around every page, so they stay as they are when moving between pages (menus mark the current page in the browser, since a layout doesn't know it, and on a site in several languages the layout has the header and footer in each language and the browser shows the page's);Page,generateStaticParamsandgenerateMetadataforapp/(site)/[[...path]]/page.tsx;NotFoundforapp/not-found.tsx, with the header and footer of its own, since Next.js shows it outside the layout;sitemapandrobots, anddemoContentforapp/admin/demo-content.json/route.ts, which serves a demo's content.<GoodfellowAdmin site={site.admin()} />from@goodfellow-cms/next/adminis the admin panel, atapp/admin/page.tsx, a Server Component, so the admin panel's page knows the site's blocks only by their fields. The blocks themselves run in the editor,<GoodfellowEditor config={config} />from@goodfellow-cms/next/editorin a Client Component atapp/admin/editor/page.tsx, which the admin panel shows in a sandboxed frame (see the editor's sandbox). Anapp/admin/page.tsxfrom before the editor's frames, a Client Component passingconfig, loads every block's code itself, so the admin panel only says how to update it there.goodfellow-next updatereplaces it with the starter's, and addsapp/admin/editor/page.tsx, unless someone has changed it; otherwise copy the starter's two files. Innext dev, the editor's frames come from a bundle the local backend serves, rebuilt as the site's code changes, since Next.js won't serve its development files to sandboxed frames.- Pages render as Server Components. Links between the site's pages use
next/link, so moving between pages doesn't reload, and images usenext/imagewith their sizes filled in. Images are served as they are unless the site sets a custom image loader, since a static export can't resize them on request. - Blocks can render Client Components with any React hooks, and they run in the browser. They can read the site with
useSite(). - After
next build, the starter's build script runsgoodfellow-next finish out, which gives the editor's page its Content Security Policy, writes the calendar files of collections of events, collections' feeds, the content API, the pages at redirects' old addresses and_redirectsfor Cloudflare Pages, a copy of the site's Google Fonts, which the exported pages then load in place of Google's, plugins' admin frames and what their build steps write, the search index if a page has a Search block, andgoodfellow-build.jsonfor the nightly check, with the dates the pagesnext buildrendered say what they show changes on, and lists what automated accessibility checks find on the exported pages. On a site with an admin address, it then starts every exported page with the script that sends it away from there, and writes Cloudflare Pages' header rules;withGoodfellow()adds Vercel's. Innext dev, calendar files and feeds come from the local backend, and there's no content API. On Windows, it also moves the files Next.js uses to load pages ahead to where browsers look for them, since Next.js writes them into folders there. Keep it in your build script.
Compared with goodfellow build
Interactive blocks work with both, but goodfellow build runs each Client Component as a separate island, which can't share React context, can't change the content it's given, takes only plain props, and starts again on every page.
Next.js suits developers who want client-side navigation, their own Next.js pages beside the site's, or Next.js's ecosystem. It costs more: each page loads Next.js's JavaScript and carries its content again as data, builds take longer, and there are more dependencies to keep up to date. Most of Next.js's server features don't apply, because Goodfellow sites are static, unless the app is a full-stack site with a server of its own. For a content site with a few interactive parts at most, goodfellow build is lighter and simpler.