Marc Perrin-Pelletier
Marc Perrin-Pelletier

Reputation: 13456

How do I put a nextjs app in maintenance mode (using Vercel)

I've just released my nextjs app to production using Vercel.

I'm loving the whole experience except for one tiny part: I would have loved to be able to put my app in maintenance mode, but this option does not seem available on Vercel.

My question is: Has anyone achieved this before and could share some details here?

I'm guessing it could be done at 2 levels:

Upvotes: 17

Views: 16189

Answers (5)

Andy Werner
Andy Werner

Reputation: 31

In 2023, Vercel suggests another way to implement a maintenance mode which does NOT require a re-deployment: Vercel Example App: Maintenance Page

The idea is to use Vercel's Edge Config and Next.js Middleware.

  1. Define a key isInMaintenanceMode in the Edge Config of your project. Changes to the Edge Config storage are propagated within ~10 seconds (according to Vercel). The downside is that you can not read it from wherever you want. That's why you need step 2. (Further downside: it's not free.)
  2. In your Next.js project create a middleware.js file, which checks for the value of isInMaintenanceMode and changes the routing accordingly:
import { NextRequest, NextResponse } from 'next/server'
import { get } from '@vercel/edge-config'

export const config = {
  matcher: '/big-promo',
}

export async function middleware(req: NextRequest) {
  // Check Edge Config to see if the maintenance page should be shown
  const isInMaintenanceMode = await get('isInMaintenanceMode')

  // If in maintenance mode, point the url pathname to the maintenance page
  if (isInMaintenanceMode) {
    req.nextUrl.pathname = `/maintenance`

    // Rewrite to the url
    return NextResponse.rewrite(req.nextUrl)
  }
}

Upvotes: 3

Bawantha Rathnayaka
Bawantha Rathnayaka

Reputation: 170

  1. Create a new file called _app.js inside the pages directory if it doesn't already exist.

  2. Add the following code to the file:

import React from 'react';

function MyApp({ Component, pageProps }) {
  const isMaintenance = true; // Set this to false when you're done with maintenance
  const MaintenancePage = () => <div>Maintenance mode</div>;
  
  return (
    <>
      {isMaintenance ? <MaintenancePage /> : <Component {...pageProps} />}
    </>
  );
}

export default MyApp;
  1. Customize the <MaintenancePage> component as per your requirements.

  2. When you want to enable maintenance mode, set isMaintenance variable to true. When you're done with maintenance, set it back to false.

  3. Optionally, you can also add some styling for the maintenance page by creating a CSS

Upvotes: 0

Fesch
Fesch

Reputation: 313

A different solution I am currently using would be to create a separate maintenance page and then conditionally intercept the rendering of the actual component based on an environment variable.

I achieve this by adjusting the _app.js code to:

function MyApp({ Component, pageProps }) {
  if (process.env.NEXT_PUBLIC_MAINTENANCE_MODE === 'false') {
    return <Component {...pageProps} />
  } else {
    return <Maintenance />
}

Note that as mentioned in earlier answers, this relies on the Vercel env variables, per their website: "A new Deployment is required for your changes to take effect."

Upvotes: 4

nightcoder
nightcoder

Reputation: 43

To add on to comment by @ptrkcsk, if you are going the route of putting a maintenance page in pages directory and are rendering images with the <Image> component from next/image you will also want to include your static folder to the redirects regex.

This is the source pattern that is working for me: /((?!maintenance)(?!_next)(?!static).*)

Upvotes: 1

styfle
styfle

Reputation: 24610

"Maintenance Mode" can be achieved with an Environment Variable and redirects property in your next.config.js (requires Next.js 9.5.0 or newer).

module.exports = {
  redirects() {
    return [
      process.env.MAINTENANCE_MODE === "1"
        ? { source: "/((?!maintenance).*)", destination: "/maintenance.html", permanent: false }
        : null,
    ].filter(Boolean);
  }
};

This adds a wildcard route that matches incoming requests and then issues a temporary redirect the /maintenance.html location.

Note that you cannot make changes to a deployment (config or environment variables) without deploying again.


Old Answer

If you're not using Next.js or using an old version of Next.js, "Maintenance Mode" can be achieved with the redirects property in vercel.json.

{
  "redirects": [
    { "source": "/((?!maintenance).*)", "destination": "/maintenance.html", "permanent": false }
  ]
}

Upvotes: 32

Related Questions