Hosting your Next.js website on Azure Static Web Apps is a great way to take advantage of the scalability and reliability of the cloud. You can configure your Next.js app to use Azure Static Web Apps by following the steps outlined in the article.
Azure Static Web Apps provides a cost-effective solution for hosting Next.js websites, with a free tier available for small projects. This means you can get started without breaking the bank.
To get started, you'll need to create an Azure Static Web Apps instance and configure it to work with your Next.js app. This involves setting up a GitHub repository and linking it to your Azure account.
Prerequisites
To host your Next.js app on Azure, you'll need to meet some prerequisites.
First and foremost, you'll need an Azure account with an active subscription. Don't worry, you can create one for free if you don't already have one.
You'll also need a GitHub account, which you can also create for free if you don't already have one.
Next, make sure you have Node.js installed on your local machine. You can install the latest version of Node.js to get started.
Another crucial step is to install the Next.js CLI, which you can do by following the Next.js Getting Started guide for details.
Here's a quick rundown of what you'll need to get started:
Hosting on Azure
To host a Next.js app on Azure, you can create a static web app from the Azure portal. Select Create a Resource, search for Static Web Apps, and choose Static Web Apps to create a new one.
You'll need to select your Azure subscription and create a new resource group, such as "static-web-apps-test". Then, choose a plan type, like Free, and select GitHub as the source. Sign in to GitHub and enter your repository information, including the organization, repository, and branch.
To deploy your Next.js project, you'll need to configure your package.json file to indicate the required Node version, which is currently Node 18.17.1. You can then create a new Azure Static Web Apps resource from the Azure Portal, selecting your GitHub repository and specifying the Next.js build preset. This will configure your GitHub Actions deployment with the proper configuration.
To manage environment variables, you may need to go through trial and error to find the correct approach for your application.
Static Web App
To create a static web app on Azure, you can use the Azure portal. Select Create a Resource, then search for Static Web Apps. After that, select Static Web Apps and click Create.
The first step is to select your Azure subscription, then choose a resource group. You can either select an existing one or create a new one by clicking the Create new link. Enter a name for your resource group, such as "static-web-apps-test".
Next, you'll need to select a plan type. For a static web app, the Free plan is a good option. Then, select GitHub as your source and sign in to your GitHub account if necessary.
After signing in, enter your repository information. Select your organization and repository, and choose the main branch.
If you don't see any repositories, you may need to authorize Azure Static Web Apps in GitHub or your Azure DevOps organization.
For the build preset, select Next.js from the dropdown. Keep the default value in the App location box, and leave the Api location and Output location boxes empty.
Once you've completed these steps, your deployment build will start running. You can track its progress in the Static Web Apps Overview window.
Here's a summary of the settings you need to select:
Remember, you can always adjust these settings later if needed.
Create Staging Slots
To create staging slots, start by opening your app service and navigating to the deployment slots section.
Give a name for the slot, then select the main app service in the clone settings dropdown. Click "Add" to create the slot.
You'll now see one more app service with a slot, which is a duplicate of your main app service.
To give startup commands in both staging and production slots, you'll need to do that in the deployment settings of each slot.
Configuration
Configuration is a crucial aspect of hosting Next.js on Azure. You'll need to set environment variables for Next.js, both within the build and deploy task, and in the Environment variables of your Azure Static Web Apps resource.
You're likely familiar with environment variables, which help manage configuration and settings between environments. Azure supports environment variables too, with variables in Azure Pipelines exposed as environment variables and application settings in Azure app services exposed as environment variables.
There's a catch, though - if both the pipeline and the app service need to know about your environment variable(s), you'll need to define them separately for both. This can be mitigated by storing settings in Azure key vault and linking them to your pipeline via variable groups, and to your app service via app settings, or by defining the settings in the pipeline and passing them to the app service via your deployment task's appSettings argument.
Server Side Rendering
Server Side Rendering is a powerful feature that allows you to render your site on the server, improving performance and user experience.
In Next.js, a managed backend is automatically available for every hybrid deployment in all plans, giving you a solid foundation to build upon.
However, you can take more control of the backend by assigning a custom backend to your site, fine-tuning performance to your liking.
If you switch between a managed backend to a linked backend, your site experiences no downtime, so feel free to experiment and find the setup that works best for you.
Set Environment Variables
Setting environment variables is crucial for managing configuration and settings between environments in your Next.js application. Next.js uses environment variables at both build time and request time.
Environment variables are a common approach in Next.js, and Azure supports them well. Variables in Azure Pipelines are exposed as environment variables, and application settings in Azure app services are also exposed as environment variables.
However, there's an additional concern to consider: if both the pipeline and the app service need to know about your environment variable(s), you need to define them separately for both. This is because they don't share configuration settings.
Here are some ways to mitigate this issue:
You'll also need to think about what environment variables are needed when and by what: what's needed at build time or runtime (or both)? What's needed by the client or the server (or both)? Are the variable values going to be the same or different between environments?
Configure Routing and Middleware
To configure your Next.js project for deployment, you need to handle routes with custom redirects, rewrites, and middleware.
Custom handling affects the default routing of your Next.js site, and the configuration must be compatible with hosting on Static Web Apps.
Static Web Apps validates your site's deployment by adding a page at build time, named public/.swa/health.html.
Middleware and custom routing can prevent Static Web Apps' deployment validation if they affect the access of the /.swa/health.html path.
To configure middleware and routing for a successful deployment, follow these steps:
- Exclude routes starting with .swa in your middleware.ts (or .js) file by using a matcher that matches all request paths except for the ones starting with .swa.
- Configure your redirects in next.config.js to exclude routes starting with .swa by using a source pattern that excludes .swa paths.
- Configure your rewrite rules in next.config.js to exclude routes starting with .swa by using a source pattern that excludes .swa paths.
These code snippets ensure that paths resolve as expected during deployment validation by excluding .swa paths from custom routing and middleware.
Static HTML Export
Static HTML export is a feature of Next.js that generates static HTML files during the build process, which are then cached and reused for all requests.
To enable static HTML export, you need to add 'output: 'export'' to your nextConfig in next.config.js.
You also need to specify the output location in your GitHub Actions or Azure DevOps configuration, which is set to 'out' by default.
If you're using a custom build script, set IS_STATIC_EXPORT to true in the Static Web Apps task of your GitHub Actions or Azure DevOps YAML file.
Static Next.js sites are hosted on the Azure Static Web Apps globally distributed network for optimal performance.
You can add linked backends for your APIs to your static Next.js site.
To deploy a statically exported Next.js application to Azure, follow the deploy static-rendered Next.js websites tutorial.
A Detour Through Node_modules
A detour through node_modules can be a necessary part of your deployment process, especially when working with custom servers that require access to production dependencies.
Node_modules is typically a large folder containing hundreds or thousands of files, making it impractical to deploy via FTP. However, you can use the Kudu console to run npm install on the app service, which will get node_modules installed and in place.
You may have already deployed your package.json file, which is a good starting point. But if you're using yarn locally, you'll want to use your yarn.lock file to ensure consistent dependencies across environments.
Two problems arise when trying to use yarn with Azure app services: npm is installed by default, but not yarn, and you need to trigger yarn execution at the right point in your automated release pipeline.
Fortunately, a custom deployment script from the kudu-yarn repo on GitHub can help solve both these problems. This script installs yarn globally via npm and then executes yarn post-deployment.
However, you may need to make some modifications to get it working smoothly. For example, you'll need to update the deploy.cmd file to use the full path to the yarn executable, which can be found by executing npm root -g via the Kudu console.
You may also want to increase the default timeout length for yarn by adding the --network-timeout=100000 argument.
By adding three more files to your deployment package - yarn.lock, .deployment, and deploy.cmd - you can avoid deploying node_modules altogether, which is a significant win.
Supporting a CDN
Supporting a CDN is a crucial step in delivering static resources efficiently. By using an Azure CDN, you can significantly reduce the load on your application and improve user experience.
To set up a CDN, you can use the assetPrefix config setting in Next, which automatically adds the CDN endpoint URL to JavaScript and CSS files loaded from the /_next/ path. This setting can be exposed as an environment variable, making it easy to integrate with your pipeline and app service environments.
However, the docs state that assetPrefix won't add the prefix to requests for paths under /_next/data/ or files in your public folder. This means you'll need to introduce the prefix yourself for public files.
One approach to handling public files is to set a build id variable in your pipeline, expose it as an environment variable, and use it to generate an absolute URL with the CDN endpoint, build id, and path. This can be done using a getCdnUrl function in your app.
The getCdnUrl function takes a path and produces an absolute URL that combines the CDN endpoint URL, build id, and path. This ensures that public files are served via the CDN with a far-future max-age, and the cache is busted by a new build.
To make this work, you'll also need to include a rewrite rule in your web.config to remove the build id from incoming requests to public files, and a client cache rule to add a Cache-Control header to responses.
Frequently Asked Questions
How to avoid backend failures when hosting a Next.js application on Azure?
To ensure a stable backend for your Next.js app on Azure, update your Server.js file, package.json, and add a web.config file to handle URL rewriting, and choose Azure App Services over Azure Static Web Apps. By following these steps, you can prevent common backend failures and ensure a smooth hosting experience.
Sources
- https://learn.microsoft.com/en-us/azure/static-web-apps/deploy-nextjs-hybrid
- https://learn.microsoft.com/en-us/azure/static-web-apps/nextjs
- https://techcommunity.microsoft.com/t5/apps-on-azure-blog/build-full-stack-next-js-apps-with-azure-static-web-apps/ba-p/4093389
- http://meeg.dev/blog/using-azure-pipelines-to-build-and-deploy-a-next-js-app-to-azure-app-services
- http://mkumaran.net/posts/2023/deploy-nextjs-azure-devops/
Featured Images: pexels.com