---
title: "Walkthrough: Statically generating an MVC application"
slug: "walkthrough--statically-generating-an-mvc-application"
abstract: "Render MVC layouts and renderings using Headless Services and a Next.js JSS app"
---
# Walkthrough: Statically generating an MVC application

Using headless rendering solutions provided by Sitecore, such as [Sitecore Headless Services](https://doc.sitecore.com/xp/en/developers/hd/23/sitecore-headless-development/sitecore-headless-services.html "Sitecore Headless Services") and the [Sitecore JavaScript Services SDK (JSS)](https://doc.sitecore.com/xp/en/developers/hd/23/sitecore-headless-development/sitecore-javascript-services-sdk--jss-.html "Sitecore JavaScript Services SDK (JSS)"), you can statically generate your MVC application using a JSS Next.js app.

Before starting the process of statically generating your MVC application using JSS, you must meet the following prerequisites:

- You have access to a Sitecore instance with Sitecore XM/XP version 10.2+ and Sitecore Headless Services module version 19+.
- You have some familiarity with the [Sitecore JavaScript Services SDK (JSS)](https://doc.sitecore.com/xp/en/developers/hd/23/sitecore-headless-development/sitecore-javascript-services-sdk--jss-.html "Sitecore JavaScript Services SDK (JSS)"), [Next.js](https://nextjs.org/), and the [Sitecore JavaScript Rendering SDK (JSS) for Next.js](https://doc.sitecore.com/xp/en/developers/hd/23/sitecore-headless-development/sitecore-javascript-rendering-sdk--jss--for-next-js.html "Sitecore JavaScript Rendering SDK (JSS) for Next.js").
- You must [install the JSS CLI](https://doc.sitecore.com/xp/en/developers/hd/23/sitecore-headless-development/install-the-jss-cli-globally.html "Install the JSS CLI globally") version 19+.
- You must [create an API key](https://doc.sitecore.com/xp/en/developers/hd/23/sitecore-headless-development/create-a-sitecore-services-client-api-key.html "Create a Sitecore services client API key").

> [!important]
> When following these instructions, keep in mind that you might want to support both existing MVC and static MVC pages if you are taking an incremental approach to conversion, which would require multiple Layout items or customization.

This walkthrough describes how to:

- Adapt the MVC application for static HTML generation.
- Include placeholders for MVC layouts in the Layout Service response.
- Configure the Sitecore Layout Service to output HTML for MVC renderings.
- Prepare a JSS Next.js application for rendering an MVC application.
- Adapt the Next.js application to serve your layouts and assets from existing MVC apps
- Start the Next.js application.

> [!important]
> This conversion process, depending on your choices for the JSS application and your existing setup for Sitecore and the MVC application has some [limitations](https://doc.sitecore.com/xp/en/developers/hd/23/sitecore-headless-development/limitations-and-workarounds-for-static-generation-of-mvc-apps-with-jss.html "Limitations and workarounds for static generation of MVC apps with JSS").

## Adapt the MVC application for static HTML generation

Your MVC application might require some changes to be compatible with static HTML generation using a JSS app.

To adapt the MVC application:

1. To enable editing and static generation support in the JSS app, ensure your site root inherits */sitecore/templates/Foundation/JavaScript Services/App template*.

    ![Site root item template inheritance](https://doc.sitecore.com/api/markdown-image/xp/en/developers/hd/23/sitecore-headless-development/images/StaticMVCRootItemPageTemplate.png)

2. To enable editing support, ensure the layouts for your pages use or inherit the template */sitecore/templates/Foundation/JavaScript Services/JSS Layout* . The `Path` value is not used, it must only be a valid file path. By default JSS uses `/Views/JssApp.cshtml`.
3. The [JSS Dictionary API](https://doc.sitecore.com/xp/en/developers/hd/23/sitecore-headless-development/jss-dictionary-api.html "JSS Dictionary API") requires specific templates and configuration, such as the `dictionaryDomain` attribute for the `<app>` configuration. You might have to adjust your MVC solution for compatibility.

## Include placeholders for MVC layouts in the Layout Service response

To render your MVC layouts in a JSS application, the placeholders available for the layouts must be included in the [Layout Service](https://doc.sitecore.com/xp/en/developers/hd/23/sitecore-headless-development/layout-service.html "Layout Service") response.

> [!tip]
> In this walkthrough, we use REST Layout Service endpoint examples but the procedure works equally well with GraphQL and Experience Edge and you can access the data with the help of a layout query.

To inspect the Layout Service response, visit the endpoint at `<cm_server>/sitecore/api/layout/render?item=/&sc_apikey=<api_key>`. You can see JSON output for the configured site start item `/` .

> [!note]
> For multisite solutions, add the `sc_site` query parameter. Disable editing mode layout data with the `sc_mode=normal` query parameter.

If the placeholder information is missing in the JSON data structure under `sitecore > route > placeholders`, for every one of your layouts, you must configure the **Layout Service Placeholders** field. This field determines which placeholder information to include in the Layout Service response data.

To populate the `placeholders` field for your layouts:

1. In the content tree, under *sitecore/layouts/Layouts*, for your selected Layout, add every *root* placeholder to the **Layout Service Placeholders** field.

    > [!note]
    > If a *Placeholder Settings* item does not exist, create it.

    ![Configuration interface for Layout Service Placeholders](https://doc.sitecore.com/api/markdown-image/xp/en/developers/hd/23/sitecore-headless-development/images/StaticMVCConfigurePlaceholders.png)

2. Refresh the Layout Service endpoint you accessed previously. The placeholder information located in the data at *Sitecore/route /placeholders* is now populated. The data includes all placeholders and components required to render your page.

## Configure the Sitecore Layout Service to output HTML for MVC renderings

Following the configuration of the **Layout Service Placeholders** field for your Layouts, you obtain JSON-formatted placeholder information.

To statically render the MVC application to HTML before [converting all the components to JavaScript](https://doc.sitecore.com/xp/en/developers/hd/23/sitecore-headless-development/convert-components-from-mvc--c--razor--to-next-js--javascript-react--incrementally.html "Convert components from MVC (C#/Razor) to Next.js (JavaScript/React) incrementally"), the component information must be converted to HTML before reaching the JSS application.

To configure the Layout Service to output HTML for MVC renderings:

1. Navigate to *sitecore/layout/Renderings* and enable HTML output for the renderings using one of the following methods:
    - For the relevant renderings, to enable HTML output manually, select the **Render as HTML** check box. You must enable this option for all nested renderings as well.

        > [!tip]
        > To identify the components requiring this setting, look in the JSON output for the `componentName` property. The `componentName` matches the rendering item name.

        ![View of the Render as HTML checkbox](https://doc.sitecore.com/api/markdown-image/xp/en/developers/hd/23/sitecore-headless-development/images/LayoutServiceRenderAsHTML.png)

    - If you have Sitecore PowerShell Extensions installed, run the following script in the Sitecore PowerShell ISE tool, to select the **Render as HTML** check box for *all* renderings:

        > [!note]
        > To run the script, you must have Sitecore PowerShell Extensions installed.

        ```powershell
        Get-ChildItem "/sitecore/layout/Renderings" -Recurse |
        	Where-Object { $_.TemplateName -eq "View rendering" -or $_.TemplateName -eq "Controller rendering" } |
        	ForEach-Object {
        		$val = $_.Fields["Render as HTML"].Value
        		if ($val -eq "1") {
        		    return
        		}
        		Write-Host "Setting '$($_.Name)'"
        		$_.Editing.BeginEdit()
        	    $_.Fields["Render as HTML"].Value = 1
        		$_.Editing.EndEdit()
        	}
        ```

    - Use a global configuration to disable JSON rendering and switch to HTML serialization for all renderings:

        ```xml
        <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"
                       xmlns:set="http://www.sitecore.net/xmlconfig/set/">
        	<sitecore>
        		<layoutService>
        			<!-- Disable JSON / enable HTML serialization for all MVC renderings -->
        			<serializableRenderingTypes>
        				<viewRendering>
        					<patch:delete />
        				</viewRendering>
        				<controllerRendering>
        					<patch:delete />
        				</controllerRendering>
        			</serializableRenderingTypes>
        		</layoutService>
        	</sitecore>
        </configuration>
        ```

2. Publish your changes.
3. Refresh the Layout Service endpoint and verify that the component data output is in HTML.

## Prepare a JSS Next.js application for rendering an MVC application

To statically generate the MVC application, we recommend you use the [JSS for Next.js](https://doc.sitecore.com/xp/en/developers/hd/23/sitecore-headless-development/sitecore-javascript-rendering-sdk--jss--for-next-js.html "Sitecore JavaScript Rendering SDK (JSS) for Next.js") to create a basic JSS Next.js application.

> [!tip]
> Before creating the application based on the sample Next.js application provided by JSS, consider whether you want to use GraphQL or REST services for fetching data and the pre-rendering method to use when the MVC application has been migrated to JavaScript.
>
> We recommend GraphQL for compatibility with Experience Edge for XM.

To create a Next.js JSS application for rendering the HTML output of your MVC app:

1. In a terminal, create a Next.js application with JSS by running the following command:

    ```text
    npx create-sitecore-jss nextjs
    ```

    > [!important]
    > The `<app-name>` must match your MVC site name, but you must be aware of app name formatting restrictions. For example, `MyMvcApp` is a valid MVC site name, but the JSS initializer allows only lower-case letters. When creating the JSS application, provide a lower-case app name, for example, `my-mvc-app`. When the process finishes, in the `package.json` file, update the `config.appName` property to `MyMvcApp`.

2. [Connect your Next.js JSS application to Sitecore](https://doc.sitecore.com/xp/en/developers/hd/23/sitecore-headless-development/walkthrough--connecting-a-code-first-jss-next-js-application-to-sitecore.html "Walkthrough: Connecting a code-first JSS Next.js application to Sitecore").
3. In the root directory of the Next.js application, review the Sitecore configuration patch file `/sitecore/config/<app-name>.config`. This configuration must be deployed to your Sitecore instance.

    > [!note]
    > Because you already have a matching `<site/>` configuration for your existing MVC site, you might want to merge the site configuration attributes.

4. [Enable editing using advanced Sitecore editors](https://doc.sitecore.com/xp/en/developers/hd/23/sitecore-headless-development/walkthrough--connecting-a-next-js-jss-app-to-sitecore-editors.html "Walkthrough: Connecting a Next.js JSS app to Sitecore editors").

## Adapt the Next.js application to serve your layouts and assets from existing MVC apps

To render a Sitecore MVC application in a JSS Next.js app, you must have matching layouts and access to the resources of the MVC app - such as styles and scripts.

To adapt the Next.js application:

1. If your app requires customizations to the `html` and/or `body` elements of the page, in the `src/pages` directory, [define a custom `Document component`](https://nextjs.org/docs/advanced-features/custom-document).
2. Adapt the `src/Layout.tsx` file, defining the root layout for your application, including base markup and root placeholders, to match your MVC-based layout.
3. Modify the `src/pages/_app.tsx` and/or `src/Layout.tsx` files to include your front-end assets.

    > [!tip]
    > Consider migrating to the [CSS solutions with built-in support in Next.js](https://nextjs.org/docs/basic-features/built-in-css-support) and loading external scripts using [the `next/script` component](https://nextjs.org/docs/basic-features/script).

    > [!note]
    > The generated app uses Bootstrap and custom CSS. For details refer to the directory `src/assets/`.

4. Place the files that you want to remain untouched during the build process in the `public` directory, located in the root directory of the Next.js application. For more information, refer to the Next.js documentation on [serving static files](https://nextjs.org/docs/basic-features/static-file-serving).
5. Adjust your existing JavaScript code that depends on `DOMContentLoaded` or document-ready events to use something like event delegation, because those events are no longer guaranteed with client-side route changes.
6. Configure rewrites for any requests that you want to be sent back to Sitecore Content Management or Content Delivery servers. The JSS application comes preconfigured with common redirects (Sitecore, media) but you must configure redirects for any customizations you might have in your MVC solution.

    > [!tip]
    > Next.js includes robust functionality for [configuring rewrites](https://nextjs.org/docs/api-reference/next.config.js/rewrites) to allow incremental adoption, especially for site functionality that you do not want to convert immediately to a Jamstack architecture.

7. If your MVC application does not use Sitecore Dictionaries at this time, you can temporarily remove Dictionary usage from the Next.js app. In the `src/lib/page-props-factory.ts` file, remove dictionary calls.
8. If your MVC application is multilingual, you must configure [internationalization in the Next.js application](https://doc.sitecore.com/xp/en/developers/hd/23/sitecore-headless-development/internationalization-in-the-jss-sample-app-for-next-js.html "Internationalization in the JSS sample app for Next.js") to match your Sitecore setup. Otherwise, [remove content translation functionality from the JSS Next.js app](https://doc.sitecore.com/xp/en/developers/hd/23/sitecore-headless-development/remove-content-translation-functionality-from-the-jss-next-js-app.html "Remove content translation functionality from the JSS Next.js app").
9. You must refactor any C# code injecting markup directly into your Razor view to use layout data instead. For example, add dynamic `<meta/>` tags to a *head* placeholder.

## Start the Next.js application

You can start the Next.js application in development or production mode.

To start the application and continue developing:

- In a terminal, in the root directory of your JSS Next.js app, run the following script:

    ```text
    jss start:connected
    ```

To start the application and preview its production behavior:

- In a terminal, in the root directory of your JSS Next.js app, run the following script:

    ```text
    jss start:production
    ```

When you have completed these procedures, you can [deploy your Next.js JSS application](https://doc.sitecore.com/xp/en/developers/hd/23/sitecore-headless-development/deployment-options-for-jss-next-js-apps.html "Deployment options for JSS Next.js apps").

You can also start the process of [incrementally converting components from MVC/Razor to React/Next.js](https://doc.sitecore.com/xp/en/developers/hd/23/sitecore-headless-development/convert-components-from-mvc--c--razor--to-next-js--javascript-react--incrementally.html "Convert components from MVC (C#/Razor) to Next.js (JavaScript/React) incrementally").