Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 53 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ loss or incorrect handling. But this time is over!
modules: [
['@nuxtjs/redirect-module', {
// Redirect option here
rules: [
// redirect rules here
]
}]
]
}
Expand All @@ -40,9 +43,12 @@ loss or incorrect handling. But this time is over!
modules: [
'@nuxtjs/redirect-module'
],
redirect: [
redirect: {
// Redirect options here
]
rules: [
// redirect rules here
]
}
}
```

Expand All @@ -54,11 +60,39 @@ loss or incorrect handling. But this time is over!

Rules of your redirects.

### `decodeFullUrl`

- Default: `false`

If enabled, protocol and host will also be considered for redirecting rules so you can have non-www to www or http to https redirects for example. Note that you likely have to adopt your rules when enabling this, e.g. `{ from: '^/myoldurl', to: '/mynewurl' }` will no longer work because the `from` regex no longer matches when proto and host are prepended.

### `onDecode`

- Default: `(req, res, next) => decodeURI(req.url)`
Default:

```js
// This will trust proxy headers. You can change this behaviour
// by providing your own onDecode function.
(req, options) => {
if (options.decodeFullUrl) {
return decodeURI(req.url)
} else {
let proto = req.headers['x-forwarded-proto']
if (proto === undefined) {
proto = req.connection.encrypted ? 'https' : 'http'
}

let host = req.headers['x-forwarded-host']
if (host === undefined) {
host = req.httpVersionMajor >= 2 ? req.headers[':authority'] : req.headers.host
}

return `${proto}://${host}${decodeURI(req.url)}`
}
}
```

You can set decode.
Allows you to change how the url is decoded.

### `onDecodeError`

Expand Down Expand Up @@ -126,6 +160,21 @@ redirect: async () => {
}
```

For redirecting http to https:

```js
redirect: {
decodeFullUrl: true,
rules: [
{
from: 'http://example.com/(.*)$',
to: 'https://example.com/$1',
statusCode: 301,
}
]
}
```

Now, if you want to customize your redirects, how your decode is done
or when there is some error in the decode, you can also:

Expand Down
2 changes: 1 addition & 1 deletion lib/middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module.exports = function (options) {
let decodedBaseUrl

try {
decodedBaseUrl = options.onDecode(req, res, next)
decodedBaseUrl = options.onDecode(req, options)
} catch (error) {
return options.onDecodeError(error, req, res, next)
}
Expand Down
19 changes: 18 additions & 1 deletion lib/module.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
async function redirectModule (moduleOptions) {
const defaults = {
rules: [],
onDecode: (req, res, next) => decodeURI(req.url),
decodeFullUrl: false,
onDecode: (req, options) => {
if (!options.decodeFullUrl) {
return decodeURI(req.url)
} else {
let proto = req.headers['x-forwarded-proto']
if (proto === undefined) {
proto = req.connection.encrypted ? 'https' : 'http'
}

let host = req.headers['x-forwarded-host']
if (host === undefined) {
host = req.httpVersionMajor >= 2 ? req.headers[':authority'] : req.headers.host
}

return `${proto}://${host}${decodeURI(req.url)}`
}
},
onDecodeError: (error, req, res, next) => next(error),
statusCode: 302
}
Expand Down
32 changes: 32 additions & 0 deletions test/module.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -212,3 +212,35 @@ describe('error', () => {
})
})
})

describe('decodeFullUrl', () => {
beforeAll(async () => {
nuxt = await setupNuxt({
...config,
redirect: {
rules: [{
from: `http://localhost:([0-9]+)/(.*)$`,
to: `https://localhost:$1/$2`,
statusCode: 301
}],
decodeFullUrl: true
}
})
})

afterAll(async () => {
await nuxt.close()
})

test('301 Moved Permanently', async () => {
try {
await request({
uri: url('/'),
resolveWithFullResponse: true,
followRedirect: false
})
} catch (e) {
expect(e.statusCode).toBe(301)
}
})
})