Deploy hybrid Next.js websites on Azure Static Web Apps

In this tutorial, you learn to deploy a Next.js website to Azure Static Web Apps, leveraging the support for Next.js features such as Server-Side Rendering (SSR) and API routes.

Prerequisites

Unsupported features in preview

During the preview, the following features of Static Web Apps are unsupported for Next.js with server-side rendering:

  • APIs using Azure Functions, Azure AppService, Azure Container Apps or Azure API Management.
  • Deployment via the SWA CLI.
  • Static Web Apps provided Authentication and Authorization.
  • The staticwebapp.config.json file.
    • Features such as custom headers and routing can be controlled using the next.config.js file.
  • skip_app_build and skip_api_build can't be used.
  • Incremental static regeneration (ISR) does not support caching images and on-demand revalidation

Note

The maximum app size for the hybrid Next.js application is 100 MB. Use standalone feature by Next.js for optimized app sizes. If this is not sufficient, consider using Static HTML exported Next.js if your app size requirement is more than 100 MB.

Set up a Next.js app

Begin by initializing a new Next.js application.

  1. Initialize the application using npm init. If you are prompted to install create-next-app, say yes.

    npm init next-app@next-12-3-2 --typescript
    
  2. When prompted for an app name, enter nextjs-app.

  3. Navigate to the folder containing the new app:

    cd nextjs-app
    
  4. Start Next.js app in development:

    npm run dev
    

    Navigate to http://localhost:3000 to open the app, where you should see the following website open in your browser:

    Screenshot of a Next.js app running in the browser.

  5. Stop the development server by pressing CMD/CTRL + C.

Configure your Next.js app for deployment to Static Web Apps

To configure your Next.js app for deployment to Static Web Apps, enable the standalone feature for your Next.js project. This step reduces the size of your Next.js project to ensure it's below the size limits for Static Web Apps. Refer to the standalone section for more information.

module.exports = {
    output: "standalone",
}

Deploy your Next.js app

The following steps show how to link your app to Azure Static Web Apps. Once in Azure, you can deploy the application to a production environment.

Create a GitHub repo

Before deploying to Azure, you'll need to create a GitHub repo and push the application up.

  1. Navigate to https://github.com/new and name it nextjs-app.

  2. From the terminal on your machine, initialize a local git repo and commit your changes using the following command.

    git init && git add -A && git commit -m "initial commit"
    
  3. Add your repo as a remote and push your changes to the server.

    git remote add origin https://github.com/<YOUR_GITHUB_USERNAME>/nextjs-app && git push -u origin main
    

    As you run this command, make sure to replace <YOUR_GITHUB_USERNAME> with your GitHub user name.

Create a static web app

Now that the repository is created, you can create a static web app from the Azure portal.

  1. Navigate to the Azure portal.
  2. Select Create a Resource.
  3. Search for Static Web Apps.
  4. Select Static Web Apps.
  5. Select Create.

In the Basics section, begin by configuring your new app and linking it to a GitHub repository.

Screenshot of the Static Web Apps Basics tab in the Azure portal.

  1. Select your Azure subscription.
  2. Next to Resource Group, select the Create new link.
  3. Enter static-web-apps-test in the textbox.
  4. Under to Static Web App details, enter my-first-static-web-app in the textbox.
  5. Under Azure Functions and staging details, select a region closest to you.
  6. Under Deployment details, select GitHub.
  7. Select the Sign-in with GitHub button and authenticate with GitHub.

After you sign in with GitHub, enter the repository information.

Repository details

  1. Enter the following GitHub values.

    Property Value
    Organization Select the appropriate GitHub organization.
    Repository Select nextjs-app.
    Branch Select main.
  2. In the Build Details section, select Next.js from the Build Presets and keep the default values.

Review and create

  1. Select the Review + Create button to verify the details are all correct.

  2. Select Create to start the creation of the App Service Static Web App and provision a GitHub Action for deployment.

  3. Once the deployment completes select, Go to resource.

  4. On the Overview window, select the URL link to open your deployed application.

If the website doesn't load immediately, then the build is still running.

To check the status of the Actions workflow, navigate to the Actions dashboard for your repository:

https://github.com/<YOUR_GITHUB_USERNAME>/nextjs-app/actions

Once the workflow is complete, you can refresh the browser to view your web app.

Now any changes made to the main branch starts a new build and deployment of your website.

Note

If you have trouble deploying a Next.js Hybrid application with more than 100Mb app size, use the standalone feature of Next.js. Refer to the standalone section for more information.

Sync changes

When you created the app, Azure Static Web Apps created a GitHub Actions file in your repository. Synchronize with the server by pulling down the latest to your local repository.

Return to the terminal and run the following command git pull origin main.

Add Server-Rendered data

To insert data server-rendered data to a Next.js page, you need to first export a special function.

  1. Open the pages/index.ts file and add an exported function named getServerSideProps.

    export async function getServerSideProps() {
        const data = JSON.stringify({ time: new Date() });
        return { props: { data } };
    }
    
  2. Update the Home component to receive the server-rendered data.

    export default function Home({ data }: { data: { time: string } }) {
        const serverData = JSON.parse(data);
    
        return (
            <div className={styles.container}>
                <Head>
                    <title>Create Next App</title>
                    <meta name="description" content="Generated by create next app" />
                    <link rel="icon" href="/favicon.ico" />
                </Head>
    
                <main className={styles.main}>
                    <h1 className={styles.title}>
                        Welcome to <a href="https://nextjs.org">Next.js! The time is {serverData.time}</a>
                    </h1>
                // snip
    
  3. Commit and push the changes.

Once the changes are pushed, a new GitHub Actions workflow begins and the changes are deployed to your site.

Adding an API route

Next.js has API routes which is an alternative to Azure Functions for creating APIs for the Next.js client application.

Begin by adding an API route.

  1. Create a new file at pages/api/time.ts.

  2. Add a handler function to return data from the API.

    import type { NextApiRequest, NextApiResponse } from "next";
    
    export default async function handler(req: NextApiRequest, res: NextApiResponse) {
        res.status(200).json({ time: new Date() });
    }
    
  3. Open pages/index.ts to add a call to the API, and display the result.

    export default function Home({ data }: { data: { time: string } }) {
        const [time, setTime] = useState<Date | null>(null);
        useEffect(() => {
            fetch('/api/time')
            .then(res => res.json())
            .then(json => setTime(new Date(json.time)));
        }, []);
        return (
            <div className={styles.container}>
                <Head>
                    <title>Create Next App</title>
                    <meta name="description" content="Generated by create next app" />
                    <link rel="icon" href="/favicon.ico" />
                </Head>
    
                <main className={styles.main}>
                    <h1 className={styles.title}>
                    Welcome to{" "}
                    <a href="https://nextjs.org">
                        Next.js!{" "}
                        {time &&
                        `The time is ${time.getHours()}:${time.getMinutes()}:${time.getSeconds()}`}
                    </a>
                    </h1>
                    // snip
    }
    
  4. The result from the API route will be displayed on the page.

Display the output from the API route

Enable standalone feature

When your application size exceeds 100Mb, the Next.js Output File Tracing feature helps optimize the app size and enhance performance.

Output File Tracing creates a compressed version of the whole application with necessary package dependencies built into a folder named .next/standalone. This folder is meant to deploy on its own without additional node_modules dependencies.

In order to enable the standalone feature, add the following additional property to your next.config.js:

module.exports ={
    output:"standalone",
}

Enable logging for Next.js

Following best practices for Next.js server API troubleshooting, add logging to the API to catch these errors. Logging on Azure uses Application Insights. In order to preload this SDK, you need to create a custom start up script. To learn more:

Clean up resources

If you're not going to continue to use this application, you can delete the Azure Static Web Apps instance through the following steps:

  1. Open the Azure portal.
  2. Search for my-nextjs-group from the top search bar.
  3. Select on the group name.
  4. Select on the Delete button.
  5. Select Yes to confirm the delete action.