next_redirects
If you have a Next.js site that needs to handle redirects based on redirect data managed in a Drupal CMS (via the Redirect module), this module is designed for you.
It follows the "redirects in next.config.js" method documented at:
https://nextjs.org/docs/app/api-reference/config/next-config-js/redirects
https://nextjs.org/docs/app/guides/redirecting#redirects-in-nextconfigjs
🚀 Features
New REST endpoint
Exposes a REST resource at /next_redirects that returns redirect data in JSON format, structured specifically for defining redirects in your next.config.js file. Example:
[
{
"source": "/about",
"destination": "/",
"permanent": true
},
{
"source": "/articles/redirecting-in-nextjs",
"destination": "/articles/introducing-nextjs-redirects-module",
"permanent": true
}
]
Query string support
Query strings in the source path are correctly parsed and added to the "has" field in the JSON response. Check the Next.js documentation on this topic: https://nextjs.org/docs/app/api-reference/config/next-config-js/redirect...
{
"source": "/sports/tournaments",
"destination": "/search",
"permanent": true,
"has": [
{
"type": "query",
"key": "sport",
"value": "soccer"
},
{
"type": "query",
"key": "team",
"value": "once-caldas"
}
]
}
Installation
Install the module as any other contributed module for Drupal (https://www.drupal.org/docs/extending-drupal/installing-modules).
Post-Installation
- Enable the Next.js Redirects resource at: /admin/config/services/rest
- Configure it as follows:
- Visit /next_redirects to verify that the endpoint returns the expected output.
- Granularity: Resource
- Methods: GET
- Accepted request formats: JSON
- Authentication providers: Select whichever you need for this resource
Integrating With Next.js
While the endpoint already provides a ready-to-use JSON array, the response still needs to be added to your next.config.js file.
To do this dynamically, we recommend implementing the following approach in your Next.js application:
- Create a pre-build script that fetches the redirect data from the Drupal endpoint and saves the result as a JSON file.
For general guidance on running scripts before every build in Next.js, refer to:
👉 How to run scripts before every build on Next.jsIn the example below, the contents returned by the Drupal endpoint are saved to
/public/static/redirects.json.You can copy the following code and place it in a file inside your pre-build directory, for example:
src/scripts/pre-build/saveRedirects.ts:import axios from "axios"; import fs from "fs"; import path from "path"; /** * Save redirects data retrieved from Drupal to a static file. */ export default async function saveRedirects() { try { // Get access token using the client credentials grant type. // Implement your own getAccessToken function to retrieve the token. const drupalAccessToken = await getAccessToken({ grant_type: "client_credentials", client_id: process.env.NEXT_PUBLIC_DRUPAL_CLIENT_ID, client_secret: process.env.NEXT_PUBLIC_DRUPAL_CLIENT_SECRET, }); // Fetch redirect data from Drupal, this request needs to be authenticated. const redirectDataResponse = await axios.get( `${process.env.NEXT_PUBLIC_DRUPAL_BASE_URL}/next_redirects`, { headers: { Authorization: `Bearer ${drupalAccessToken}`, "Content-Type": "application/json", }, } ); // Generate static file with redirects. const destinationFolder = path.join(process.cwd(), "public", "static"); const fullFilePath = path.join(destinationFolder, "redirects-example.json"); // Create folder for generated data if it doesn't exist yet if (!fs.existsSync(destinationFolder)) { fs.mkdirSync(destinationFolder); } if (fs.existsSync(fullFilePath)) { await fs.promises.unlink(fullFilePath); } await fs.promises.writeFile(fullFilePath, JSON.stringify(redirectDataResponse.data)); console.log("Redirects data saved successfully."); } catch (error) { console.error("Error", error); } } - From your
next.config.js, load the redirects from the static JSON file generated in the previous step and return them within theasync redirects()function.Here's an example of how your
redirects()function might look when reading data frompublic/static/redirects.json:import fs from "fs"; /** @type {import('next').NextConfig} */ const nextConfig = { async redirects() { try { const redirectsJsonData = await fs.promises.readFile("public/static/redirects.json", "utf-8"); const redirectsJsonObject = JSON.parse(redirectsJsonData); console.log("Successfully read redirects.json file"); return redirectsJsonObject; } catch (error) { console.error("Error reading JSON file:", error); } }, }; - Rebuild your Next.js application.