next-maintenance-mode
v1.1.0
Published
The intuitive cost-efficient middleware for effortless maintenance mode toggling. Supported by multiple configuration options and a straightforward API. Ready to integrate with your Next.js app directory!
Downloads
17
Readme
Overview
next-maintenance-mode
is a middleware specially designed for Next.js applications, enabling you to easily toggle maintenance mode on and off. When activated, it redirects users to a designated maintenance page. Its compatibility with configuration providers such as Upstash and Edge Config allows for flexible and dynamic maintenance state management.
Motivation
Setting up a maintenance mode in Next.js apps can be a hassle, particularly on certain hosting providers, which lack built-in support for this feature. Current methods are time-consuming and usually leave API routes vulnerable.
To solve this, we've created a straightforward solution that lets you choose between two different providers, making the setup process for maintenance mode quicker and more cost-effective, without skimping on security. This solution also includes an optional caching feature to help save bandwidth.
| Provider | Reads (free plan) | | ------------------ | ---------------------- | | Vercel/Edge-Config | 50k/month | | Upstash/Redis | ~ 300k/month (10k/day) |
Features
- ⚡️ Next.js Compatibility: Out-of-the-box integration with the new Next.js app directory, providing a smooth user experience.
- 🛠️ Seamless Integration: Designed to work hand-in-hand with Next.js applications, ensuring an intuitive setup process and seamless operation.
- 📚 Provider Options: Offers the flexibility to choose between Upstash and Edge Config as configuration providers, allowing you to tailor the solution to your existing workflow and tools.
- 💻 Simple API: One Wrapper to Rule Them All -
withMaintenanceMode
- 💾 Bandwidth Reduction: Our optional caching feature reduces bandwidth usage, making your maintenance mode not only more efficient but also cost-effective.
- 🔄 Dynamic Toggle: Easily toggle maintenance mode on and off without the need for a complete app rebuild, saving you time and effort.
Installation
To get started with next-maintenance-mode
, you can install the package using your preferred package manager:
$ yarn add next-maintenance-mode
# or
$ npm install next-maintenance-mode
# or
$ pnpm i next-maintenance-mode
Usage
To integrate next-maintenance-mode
into your Next.js application, insert the following code into your middleware file.
import { withMaintenanceMode } from 'next-maintenance-mode'
const middlewareOptions = {
provider: 'upstash' | 'edge-config', // Required
maintenancePageSlug: '/maintenance', // Optional
key: 'your_key_here', // Optional
cacheTime: 'number', //Optional - defined in ms for e.g. 60000 = one minute
}
withMaintenanceMode(
{
beforeCheck: NextMiddleware, // function which will be executed before checking the maintenance mode (if an instance of NextResponse is returned, checking maintenance mode status & afterCheck is skipped)
afterCheck: NextMiddleware, // function which will be executed after checking the maintenance mode (only if maintenance mode status is set to false)
},
'your_connection_string_here',
middlewareOptions,
)
Before using the middleware, you need to configure it with the necessary settings. Here are the options you can specify:
- provider: Identify your configuration provider, choose between 'upstash' or 'edge-config'. This field is mandatory.
- maintenancePageSlug: Specify the route to your maintenance page. The default setup directs to '/maintenance'.
- key: Create a unique key to indicate the maintenance mode state in your configuration provider, defaulting to 'isInMaintenanceMode'.
- cacheTime: Defined in milliseconds, determines how long data is stored in the cache before being refreshed. Utilizing an LRU (Least Recently Used) caching algorithm, helps to save bandwidth.
The connection string structure differs between Upstash and Edge Config:
- For Upstash: Include both the URL and token, formatted as
url@token
. - For Edge Config: Specify the API endpoint or path given by Edge Config.
⚠️ Keep in mind, due to edge functions nature the LRU cache might occasionally reset, but it's nothing to worry about. If this happens, the status is automatically checked in the provider and updated. This won't affect passed middleware's functions - they are not cached.
Setting maintenance status from different locations:
To toggle the maintenance mode status directly through code, you can use the updateMaintenanceModeStatus function. Here's how you can call this function with appropriate parameters:
updateMaintenanceModeStatus(true, {
provider: 'upstash' | 'edge-config', // specify the provider
connectionString: 'your_connection_string_here', // provide your connection string
key?: 'your_key_here', // optional, default is "isInMaintenanceMode"
maintenanceEdgeConfigId?: 'your_edge_config_id_here', // necessary for edge-config provider
maintenanceModeVercelApiToken?: 'your_vercel_api_token_here', // necessary for edge-config provider
})
Example use cases:
- Scheduled Updates: Activate maintenance mode during pre-set times.
- High Traffic: Enable maintenance mode when traffic exceeds server capacity.
- System Health: Trigger maintenance mode in response to health check failures.
⚠️ Note that if caching is activated, alterations to the maintenance status might not take effect immediately.
Access Parameters in Check Events:
You can directly access the following parameters during events:
- req: NextRequest
- _next: NextFetchEvent
These can be accessed in:
beforeCheck
afterCheck
Example integration with next-auth:
import { NextFetchEvent, NextRequest, NextResponse } from "next/server";
import { withMaintenanceMode } from "next-maintenance-mode";
import { getToken } from "next-auth/jwt";
async function firstMiddleware(req: NextRequest, _next: NextFetchEvent) {
const token = await getToken({ req });
if (!token) {
return NextResponse.rewrite(new URL("/sign-in", req.nextUrl));
}
if (token.role === "admin") {
return NextResponse.next(); //If you want you can disable checking maintenance mode for users with an admin role
}
}
async function secondMiddleware(req: NextRequest, _next: NextFetchEvent) {
console.log("secondMiddleware");
}
export default withMaintenanceMode(
{ beforeCheck: firstMiddleware, afterCheck: secondMiddleware },
process.env.MAINTENANCE_MODE_CONNECTON_STRING as any,
{
provider: process.env.MAINTENANCE_MODE_PROVIDER as any,
maintenancePageSlug: process.env.MAINTENANCE_MODE_PAGE_SLUG,
key: process.env.MAINTENANCE_MODE_KEY,
}
);
export const config = {
matcher: ["/((?!api/auth|_next/static|_next/image|favicon.ico).*)"],
};
Error Messages
There are specific error messages that may be encountered while using the middleware:
| Error Message | Description |
|---------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Maintenance Key Missing Error | This error occurs if the maintenance key is not found in your configuration provider. It can be encountered when checking the maintenance mode state. |
| Invalid Connection String | This error is triggered when the connection string does not match the selected provider. |
| Unsupported Provider Error | This error is thrown when an unsupported provider is passed to the function. |
| Middleware Configuration Error | This error is thrown when neither beforeCheck
nor afterCheck
middleware functions are defined during the setup. It ensures that at least one of these functions is implemented to proceed with the maintenance mode check. |
🙌 Contribution
Contributions are always welcome! To contribute, please follow these steps:
- Fork the repository.
- Create a new branch with a descriptive name.
- Make your changes, and commit them.
- Push your changes to the forked repository.
- Create a pull request, and we'll review your changes.
📡 Community
If you're looking for help or simply want to share your thoughts about the project, we encourage you to join our Discord community. Here's the link: https://blazity.com/discord. It's a space where we exchange ideas and help one another. Everyone's input is appreciated, and we look forward to welcoming you.