Upgrading to 3.0
3.0 has one change: the server no longer serves the Studio. The site mounts it, as a router, like anything else in Express.
Before 3.0, @trokky/trokky served the admin UI by dynamically importing @trokky/studio/dist/server/assets.js, a build artifact, behind a type-check suppression. That made the two packages depend on each other, promoted a private path to public API, and failed silently: if the import broke, the server started normally and /studio was a 404 with no explanation. Owning the mount in your server file makes a missing Studio a build error you can see, and lets the server package stop knowing the UI exists.
The change, in every server file
Section titled “The change, in every server file”import { startServer } from '@trokky/trokky/express'import { studioRouter } from '@trokky/studio/express'import config from './trokky.config.js'
const server = await startServer(config)server.app.use('/studio', studioRouter({ apiPath: '/api' }))
// then your own routes, static files and frontend catch-all, as beforeMount it before anything that catches all paths, such as a frontend handler or express.static at the root, or that will swallow /studio. If you use TrokkyExpress.create() and mount() yourself, the same line goes right after mount().
@trokky/studio was already a dependency of every site that showed the Studio, so nothing new to install.
The config change
Section titled “The config change”// beforestudio: { enabled: true, path: '/studio', structure, branding: { title: 'My CMS' },}
// afterstructure,studio: { branding: { title: 'My CMS' },}structuremoves to the top level. The server reads it to enforce singletons and to refuse to start when structure and schemas disagree; it was never only the Studio’s.studio.enabledandstudio.pathare gone: whether and where the Studio is served is decided by theapp.use()line.studio.apiUrlandstudio.requireAuthare gone: neither did anything.studio.branding,studio.fields,studio.settingsandstudio.sessionstay. They are served to the UI over the API.
The server refuses to start on the old shape and prints, for each removed key, what to do instead. You cannot upgrade and miss it.
3.1: one URL for the Studio
Section titled “3.1: one URL for the Studio”3.1 adds studio.url, the public URL of the mounted Studio (default: the STUDIO_URL environment variable). It replaces two knobs that described the same fact: the device-flow approval page is now <studio.url>/auth/device (with oauth2.verificationUri kept as an override), and system emails link from it. Set it once:
studio: { url: process.env.STUDIO_URL, // https://cms.example.com/studio branding: { title: 'My CMS' },}3.1 also stops pretending about two keys nothing read: studio.settings and studio.fields are ignored with a boot warning. studio.session now actually reaches the Studio; it did not before.
Smaller changes
Section titled “Smaller changes”mount()no longer takesstudioPath, andgetMountedPaths()returns{ apiPath }only.getInfo()fromstartServerno longer reportsstudioPathorstudioEnabled, so a startup banner that printed the Studio URL needs its own constant.- The device-flow approval page defaulted to
${issuer}/studio/auth/deviceand still does; if you mount the Studio at another path, setoauth2.verificationUri. @trokky/studiono longer exports./dist/server/assets.js. If you importedgetStudioHTMLorgetStudioAssetfrom there, they are exported from@trokky/studio/expressand from the package root.
Things worth checking in your own code
Section titled “Things worth checking in your own code”- Middleware that skipped
/studioby prefix, such as cache headers or redirects, keeps working if you keep the same path. It is your path now, so keep the two in sync. - Anything that derived the Studio’s API URL from the request
Hostheader, such as a proxy fix inserver.lifecycle.beforeStart, can usually be replaced by passingbackendUrltostudioRouter(). - Cloudflare or CDN rules that exclude
/studiofrom caching are unaffected as long as the mount path stays/studio.
The CLI
Section titled “The CLI”trokky migrate detects the old shape and prints these instructions for your files. trokky create scaffolds the new shape.