redirect-module
redirect-module copied to clipboard
redirect loop
I have the following redirect which seem to cause an infinite redirect loop. I can't quite figure out why. Do you know why this might be happening? If not, is there a way to set up some kind of log or debugger to track what the redirect module is actually doing behind the scenes for each redirect?
This is the rule:
/get-the-positive-edge => /forms/get-the-positive-edge
And this is what happens when I enter /get-the-positive-edge
into the browser:
/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/forms/get-the-positive-edge
Experiencing the same issue, but only on one redirect in thousands.
So we ditched this module and wrote our own.
In server middleware we have
module.exports = function (req, res, next) {
const host = req.headers.host
const env = process.env.NODE_ENV
const notWww = host.slice(0, 4) !== 'www.'
const isDomain = host.includes('domain.com')
const redirect = redirects.find(r => r.from === req.url)
if (env === 'production' && isDomain && notWww) {
const newHost = 'www.' + host
if (redirect) {
const newLocation = redirect.to
res.writeHead(parseInt(redirect.statusCode), {
Location: 'https://' + newHost + newLocation
})
res.end()
} else {
res.writeHead(301, {
Location: 'https://' + newHost + req.url
})
res.end()
}
} else if (redirect) {
const newLocation = redirect.to
res.writeHead(parseInt(redirect.statusCode), {
Location: newLocation
})
res.end()
} else {
next()
}
}
This works for all redirect objects passed to it, extensively tested on over 4k varying redirects. This also handles redirects for non-www to www and HTTP to HTTPS.
Fantastic. thank you @Webbist-dev . So do you query and store your redirects on build in the same way as the redirect-module? We're currently doing a GQL query to get all our redirects in nuxt.config
@Webbist-dev could you explain what the methods inside if (env === 'production' && isDomain && notWww)
are for? Trying to work it out so I can adapt for our own needs. I am wondering if we can ditch that whole conditional considering we have some redirects that go to other sites and occasional some that do not have www
.
Also presumably this does not accept regex redirects?
Inspired by the code supplied by @Webbist-dev , I've found an adjusted working solution for our setup to meet the following requirements:
- query redirects from an endpoint on our CMS
- Support RegEx when matching redirects
- Allow redirects to include URLs that are not on the current domain – eg
/example
=>
https://someotherdomain.com/example
My solution to replace the requirement for the Nuxt Redirect-Module:
OPTIONAL – for those who need to query an endpoint for redirects array, In /store/index.js
I am fetching all redirects from retour plugin in Craft CMS, in nuxtServerInit
– this only occurs once during the initial build. I am then formatting them using map
to prepare them for use:
import Vuex from 'vuex';
import fetch from 'node-fetch';
import fs from 'fs';
const createStore = () => {
return new Vuex.Store({
actions: {
async nuxtServerInit({commit}, {app, $config}) {
if (process.env.NODE_ENV == 'dev') {
// GET AND STORE REDIRECTS
const baseUrl = process.env.API_BASE_URL; // get API url
const endpoint = '/actions/retour/api/get-redirects'; // get endpoint path
const api = baseUrl+endpoint;
fetch(api, {
method: 'GET',
headers: { 'Content-Type': 'application/json' }
})
.then(result => result.json())
.then(result => {
console.info('Redirects generated');
if (result) {
const formattedRedirects = result.map(redirect => { // map redirect array and reformat it for redirect module requirements
let formattedRedirect = {};
formattedRedirect.from = redirect.redirectSrcUrl
formattedRedirect.to = redirect.redirectDestUrl
formattedRedirect.statusCode = redirect.redirectHttpCode
return formattedRedirect
})
fs.writeFile('./server-middleware/assets/redirects.json', JSON.stringify(formattedRedirects), err => {
if (err) {
console.error('Error writing redirect file', err);
}
});
} else {
console.log('No redirects in result');
}
});
}
},
}
});
};
export default createStore
REQUIRED – in /server-middleware/redirects.js
I am importing the file I created in nuxtServerInit
(but this can just be an array of redirects you generate however you like) and then querying it for redirects:
import redirects from './assets/redirects.json'; // import redirects file generated in build via /store/index.js
module.exports = function (req, res, next) {
const url = req.url;
const redirect = redirects.find(obj => new RegExp(`^${obj.from}`).test(url)); // RegEx check to find url in redirect array
if (redirect) { // if redirect exists, redirect it
const newLocation = redirect.to
res.writeHead(parseInt(redirect.statusCode), { // apply status code eg 301
Location: newLocation
})
res.end()
} else {
next()
}
}
And lastly, in nuxt.config.js
, include the server middleware file
serverMiddleware:['~/server-middleware/redirects.js'],
Hi,
I've been struggling with this issue too since days. I figured out with a solution that works for me
Before : { from: "/get-the-positive-edge", to: "/forms/get-the-positive-edge", statusCode: 301 }
After : { from: '^/get-the-positive-edge$', to: '/forms/get-the-positive-edge', statusCode: 301 }
I don't know if there is some issue with the spelling between "simple quote / double quote", regex mode in the from attribute but it works like this, no need for a middleware.
Regards,