Upgrade Next.js Renderer
Overview
The Sitefinity Next.js Renderer application contains middleware and endpoints that are regularly updated. You can see the latest version of the middleware in the starter template package.json file at Github.
Upgrade procedure
The project files that need to be upgraded must be upgraded manually.
- Go to the GitHub repository of our starter template and verify that your project is up to date with the basic files in the starter template – middleware,
tsconfig, next.config.js and routes.
- If any files need to be updated, navigate to the root directory of your project and ensure it contains a
package.json file:
cd /path/to/project
- In your project root directory, run one of the following commands to see the current version of your middleware:
npm outdated – lists the current version of the middleware and the latest available version
Or
npm list – lists the project middleware with versions
- Update individually any outdated packages.
Upgrade projects based on Sitefinity CMS 15.4 version earlier than 15.4.8630
With version Sitefinity CMS 15.4.8631, the Next.js Renderer is updated to Next.js 16.2 and React 19.2.
This framework update is a breaking change, if you are upgrading projects based on Sitefinity 15.4 version earlier than 15.4.8630. To maintain compatibility, you must manually apply the necessary changes in the Renderer.
Refer to the required actions below.
Summary of breaking changes
The following table summarizes the affected areas and the actions you need to take to update your project:
| Area |
Required action |
| Frameworks version updates |
Update next, react, and react-dom |
| Node.js version update |
Upgrade the Node.js runtime |
| Root middleware file convention |
Rename middleware.ts to proxy.ts and update the code |
Default bundler is changed to Turbopack |
Port webpack: configuration to turbopack: |
| Stricter form-widget client handler typings |
Update forked widget event types |
Following are the details of the changes and how you change your project.
Frameworks version updates
The Next.js SDK @progress/sitefinity-nextjs-sdk and the starter template have their peerDependencies updated to the following:
{
"next": "16.2.6",
"react": "19.2.6",
"react-dom": "19.2.6"
}
To avoid peer-dependency resolution warnings or errors, update your project's package.json to matching versions of these dependencies.
Refer to the following upstream upgrade guides for upgrading the corresponding frameworks:
Node.js version update
You must upgrade the Node.js runtime on all your development and server environments to version 20.9 or newer. We recommend using version Node.js 22.15.
Root middleware file convention
Next.js 16 renames the root middleware convention from middleware.ts to
proxy.ts.
To update your existing project, perform the following:
- Rename your existing
middleware.ts file to proxy.ts.
This file usually is located in the src directory.
- Inside the new
proxy.ts file, rename the existing middleware(request: NextRequest) function to proxy. It otherwise retains its signature.
The full signature of the proxy function is:
export async function proxy(request: NextRequest) { /* your code */ }
- Update any
include entries in your project's tsconfig.json that reference src/middleware.ts to use src/proxy.ts.
- Update all deployment scripts, Dockerfiles, and build pipelines that copy
middleware.ts into the build output.
The Next.js Renderer application, the starter template, and the example applications have already been updated with this change.
Default bundler is changed to Turbopack
The starter template's next.config.js no longer configures bundling through the webpack: hook. It now uses the Turbopack's resolveAlias configuration:
module.exports = {
- webpack: (config, options) => {
- config.resolve['alias']['@widgetregistry'] = path.resolve(__dirname, 'src/app/widget-registry');
- return config;
+ turbopack: {
+ resolveAlias: {
+ '@widgetregistry': './src/app/widget-registry.ts'
+ }
+ },
// ...
+ };
Keep in mind the following differences from the previous webpack-based alias:
- The alias value is a relative path string that includes the file extension.
For example './src/app/widget-registry.ts'.
It is not the absolute path produced by path.resolve(__dirname, …).
- Turbopack is configured declaratively.
If your project has existing logic expressed as a JavaScript function inside webpack: (config) => { … }, such as custom loaders or plugin tweaks, you must rewrite it using the turbopack configuration object.
You can find an example for configuration using Turbopack in the diagnostics module-swap pattern documented in examples/src/diagnostics/README.md:
module.exports = {
turbopack: {
resolveAlias: {
'@progress/sitefinity-nextjs-sdk/diagnostics/empty':
'@progress/sitefinity-nextjs-sdk/diagnostics/dev'
}
},
serverExternalPackages: ['@opentelemetry/sdk-node']
};
To update your project, perform the following:
- If your project's
next.config.js only added module aliases through webpack:, you port them to turbopack.resolveAlias using relative path strings.
- If your project requires custom webpack behavior that cannot be expressed through the
turbopack configuration, retain the webpack: block. Webpack remains supported in Next.js 16 as an opt-in.
Stricter form-widget client handler typings
The internal event handlers of the following client components have their typings changed to match the stricter event typings introduced in React 19.2:
widgets/form-widgets/checkboxes/checkboxes-client.tsx
widgets/form-widgets/date-time/date-time-field-client.tsx
widgets/form-widgets/multiple-choice/multiple-choice-client.tsx
widgets/form-widgets/number/number-field-client.tsx
widgets/form-widgets/paragraph/paragraph-client.tsx
widgets/form-widgets/textfield/textfield-client.tsx
EXAMPLE: For example, if the existing code looks like this:
const handleInputEvent = (e: React.ChangeEvent<HTMLInputElement>) => {
setInputValue((e.target as HTMLInputElement).value);
you need to change it to:
const handleInputEvent = (e: React.FormEvent<HTMLInputElement>) => {
setInputValue(e.currentTarget.value);
Or, if the existing code looks like this:
function handleOtherInputInput(event: React.ChangeEvent<HTMLInputElement>) {
setOtherInputText(event.target.value);
you need to change it to:
function handleOtherInputInput(event: React.InputEvent<HTMLInputElement>) {
setOtherInputText((event.target as HTMLInputElement).value);
This change affects only the TypeScript source code and does not affect the runtime behavior.
If your project imports and uses these widgets without modification, you do not need to take any action.
If you project has forked one of the listed components or wrap them with a callback whose parameter is explicitly typed as React.ChangeEvent<HTMLInputElement>, you must upgrade the code.
Perform the following:
- Change the parameter type to
React.FormEvent<HTMLInputElement> for onChange-style handlers, or React.InputEvent<HTMLInputElement> for onInput-style handlers.
- Either replace
event.target.value with event.currentTarget.value, or cast event.target to HTMLInputElement where necessary.