Fumapress 2
Fumapress 2
- This release has breaking changes, follow the migration guide.
Changed the site config to createPress()
press.configexportscreatePress(content, options).plugins(...).config({...}), replacingdefineConfig(),.adapters()and.layouts().- Removed
loaderOptions: its fields are options ofcreatePress(), andloaderPluginsreplacesloaderOptions.plugins. .config()is optional:createPress(content).plugins(...)is a complete site.ui.renderPage(props)renders every page, content pages and plugin views, typed byprops.type.props.renderDefault()is the built-in UI:layoutpicks a Fumadocs layout, andlayoutPropsandpagePropsare typed by it.- A custom layout reads
props.layoutProps,props.pageData,props.toc,props.bodyandprops.slots. - Removed the layout factories of
fumapress/layouts/*, userenderDefault({ layout })or the Fumadocs UI layouts directly inui.renderPage.selectTreeRoot(tree, "docs")offumapressreplaces theirtreeRootoption. ui.renderRootreplacesrenderRootand also receives the styles ashead.ui.layoutPropsreplacesdefaultLayoutProps,ui.translationsreplacestranslations, and theheadtags replacemeta.ui.providerPropssets the root provider of every page, likethemeor a customsearch.SearchDialog.- Removed
renderNotFound. The 404 page is a customsrc/pages/404.tsx, else a plugin view at/404, else the built-in page in the Home Layout. presettakes a list:preset: []replacespreset: false.recommendedPreset({ rss: false })drops one default plugin,recommendedPreset({ sitemap: { path: "/map.xml" } })passes it options.- The MDX renderer is built in:
press({ components: "./src/components/mdx.tsx" })offumapress/vitereplacesfumadocsMdx()offumapress/adapters/mdx. RenderPageProps<typeof app>,UIOptions<typeof app>,WakuRouteProps<typeof app, "/showcase/[slug]">andgetPressContext<typeof app>()type custom files, replacing$contextand.utils().WakuRouteConfigreplacesRouteConfig.- Fumapress needs the Base UI build of Fumadocs UI,
fumadocs-ui@npm:@fumadocs/base-ui. The Radix UI build is no longer supported. - Update
fumadocs-coreandfumadocs-uito 16.18.2 or later, andfumadocs-mdxto 15.5.1 or later.
Changed rendering to be per route
modeofcreatePress()replaces themodeoption, for one source or per source key.autoprerenders static sources and renders dynamic ones on demand,force-dynamicrenders content on demand, andforce-staticprerenders a dynamic source loaded at build.- Removed
this.modeandBuildMode. Plugins readthis.getContentRender(source?)instead. - By default, pages of dynamic content sources render on demand, pages of static sources are prerendered, and one site can mix both.
- Pages rendered on demand from a dynamic source with
staleTime, and their.mdfile and OG image, getCache-Control: public, s-maxage=<staleTime in seconds>. - The
.mdfile and OG image of a page follow its route. The sitemap, RSS,llms.txtandllms-full.txtare prerendered unless a content source is dynamic. - Custom pages default to
render: "static"and custom API routes torender: "dynamic". A static API route setsrender: "static"ingetConfig(), and can setstaticPaths. flexsearchPlugin()andoramaSearchPlugin()follow the content source: static sources export an index at/api/search.json, dynamic sources search on the server.renderoverrides it.- A site deploys as static files when no route renders on demand and no plugin has
middleware. On a platform, thestaticoption of Waku in a server entry leaves out the function of the adapter. - A build without a server warns that the
middlewareof plugins never runs, naming the plugins.
Changed the plugin API
- Plugins are
Pluginoffumapress, replacingPressPlugin, and extend the framework plugins offumadocs-core/framework/plugin.PressContext<typeof app>replacesAppContext. - Hooks:
routes({ createApi, createView }),deriveRoutes(),middleware(),head(),slots(),layoutProps(),providerProps(),configureLoader(),transformPage(),getPageView()andbuild(). middleware()runs first on every request of the server, the prerendered pages and static files of a Node.js server included. Files a platform serves never reach it.- The
wakuhookscreatePages,honoMiddlewareandunstable_serverEntryreplacecreatePages,createMiddlewaresandunstable_onServerEntry. Plugin layouts live in route groups only. - To replace a default plugin, set it to
falseinrecommendedPreset()and list your plugin. layoutProps()of plugins sets the props of every layout, likesidebar,tabsandaiChat.useLayoutProps()offumapress/clientand@fumapress/astro/clientreturns the layout props that plugins give from client state, like the AI chat: spread it into a custom layout. The built-in UI applies them.- Slot items have a unique name and a region:
actions,footer,toc-header,toc-footer,sidebar-banner,sidebar-footer,banner,body-wrapperorlayout-wrapper. The built-in UI places them, andui.renderPagereceives them by name inprops.slots. - The built-in page buttons are the slot items
core:markdownandcore:view-options. PageDatais the data of every page.getConfig()of custom pages andcreateView()takedata, like thetitleanddescriptionof the page in<head>. Plugins read it withthis.getPageData().- For components per page, list the renderer, like
mdxPlugin()offumadocs-mdx/press, withcomponentsas a function of the page. - Removed
preinit,configureRoutes, pluginrenderPage,this.dataandAdapter. fumapressexports the types that plugins use, likeContext,HeadTag,SlotItemandPageData.
Removed packages and entries
- Removed
fumapress/plugins/openapi,fumapress/plugins/asyncapi,@fumapress/graphql,@fumapress/notion,@fumapress/sanityand@fumapress/obsidian. Use the default export offumadocs-openapi/press,@fumadocs/asyncapi/press,@fumadocs/graphql/press,@fumadocs/notion/press,@fumadocs/sanity/pressandfumadocs-obsidian/press. - Removed
fumapress/plugins/blogandfumapress/layouts/blog*, use@fumapress/blog.fumapress/css/preset.cssleaves out the blog styles, import@fumapress/blog/css/preset.csswith it. - Removed
fumapress/adapters/mdx/schema.pageSchemaandmetaSchemaare infumapress/schema,blogPageSchemain@fumapress/blog/schema. - Removed
fumapress/i18n, the translations of plugins are added for you.
Changed images
vercelImage(),cloudflareImage()andselfHostedImage()replaceimagePlugin()offumapress/plugins/image/*. The preset picks the platform's.selfHostedImage()needs a server andsite.baseUrl, without them images stay as they are.vercelImage()andcloudflareImage()work with static output.data.ogImageingetConfig()replacestakumiOptions, andtakumiPlugin()takespathandgetImageinstead ofbasePathandgenerate.- On Cloudflare Workers, Open Graph images use the WebAssembly build of Takumi without passing it yourself.
Fixes
- A
basePathworks on Cloudflare, which needs Wrangler 4.148 or later, and on Netlify. Its root opened without a trailing slash hydrates on every host. llms.txtand the Markdown of pages link full page URLs, with the base path.- The browser fetches the page tree once, instead of receiving it with every page. Change its lists in
pageTree.transformersof the loader, not inui.renderPage. - On a Node.js server,
.mdfiles are served astext/markdownandAccept: text/markdownalso serves the Markdown of prerendered pages. - Markdown negotiation works on URLs with a trailing slash.
- The robots.txt sitemap link follows the sitemap
pathofrecommendedPreset(), and sitemaps escape&in alternate links. - Without a home page, the navbar title goes to the first page of the language, and so does
/with i18n. - When pages render on demand, a language root like
/cnrenders its page instead of a 404.
Fixed client state between pages
- Client state of a page, like selected code tabs, no longer carries over to the next page. Tabs of the next page could show no content.
Secured requests
- Other spellings of a URL path, like
//docs,/%64ocs,/docs/or/docs/index.html, redirect to the normal path, so middleware sees the path the router matches. - Middleware sees the page URL on every client navigation, whatever the request method.
- The self-hosted image optimizer fetches relative images from
site.baseUrl, never from theHostof a request, and limits its memory. - The route of
llmsPlugin({ routes: "all" })that renders Markdown is unreachable from outside. - A fully dynamic source no longer writes its page tree to the public directory.
Last updated on