├── .gitignore ├── index.js ├── package.json ├── readme.md └── test ├── .babelrc ├── package.json └── pages ├── _error.js └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | yarn.lock 2 | dist.js 3 | 4 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import Router from 'next/router' 2 | import ErrorComponent from 'next/error' 3 | import React from 'react' 4 | 5 | export default (redirects) => (Component) => class extends React.Component { 6 | static async getInitialProps (ctx) { 7 | const { req, res, xhr, pathname } = ctx 8 | 9 | if(redirects.has(pathname)) { 10 | const rewrite = redirects.get(pathname) 11 | 12 | if(req) { 13 | res.writeHead(301, { 14 | Location: rewrite 15 | }) 16 | res.end() 17 | return {} 18 | } 19 | 20 | Router.push(rewrite) 21 | return {} 22 | } 23 | 24 | let initialProps = {} 25 | if(Component.getInitialProps) { 26 | initialProps = await Component.getInitialProps(ctx) 27 | } 28 | 29 | return initialProps 30 | } 31 | 32 | render () { 33 | return 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "next-universal-redirect", 3 | "version": "0.1.1", 4 | "description": "Higher order component to handle both client and server side redirecting with Next.js", 5 | "main": "dist.js", 6 | "repository": "timneutkens/next-universal-redirect", 7 | "author": "Tim Neutkens", 8 | "license": "MIT", 9 | "keywords": [ 10 | "nextjs", 11 | "next" 12 | ], 13 | "devDependencies": { 14 | "babel-cli": "^6.22.2", 15 | "babel-core": "^6.23.1", 16 | "babel-plugin-transform-runtime": "^6.23.0", 17 | "babel-preset-latest": "^6.22.0", 18 | "babel-preset-react": "^6.23.0" 19 | }, 20 | "babel": { 21 | "presets": [ 22 | "latest", 23 | "react" 24 | ], 25 | "plugins": ["transform-runtime"] 26 | }, 27 | "scripts": { 28 | "build": "babel index.js > dist.js", 29 | "prepublish": "npm run build" 30 | }, 31 | "files": [ 32 | "dist.js" 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Next.js universal redirect 2 | 3 | Higher order component to handle both client and server side redirecting with [Next.js](https://github.com/zeit/next.js) 4 | 5 | Note: this package is made for Next.js 2.0+ 6 | 7 | Example: [with-universal-redirect.now.sh](https://with-universal-redirect.now.sh/) 8 | 9 | ## Installation 10 | 11 | `npm install --save next-universal-redirect` 12 | 13 | ## Usage 14 | 15 | Create a `_error.js` file in the `pages` directory of your project 16 | 17 | `pages/_error.js`: 18 | 19 | ```js 20 | import ErrorComponent from 'next/error' 21 | import redirect from 'next-universal-redirect' 22 | 23 | // This renders the default Next.js error/404 component 24 | class Error extends React.Component { 25 | static getInitialProps ({ req, res, xhr, pathname }) { 26 | const statusCode = res ? res.statusCode : (xhr ? xhr.status : null) 27 | return { statusCode } 28 | } 29 | 30 | render () { 31 | return 32 | } 33 | } 34 | 35 | // Create a map of redirects 36 | const list = new Map() 37 | list.set('/example', '/example2') 38 | 39 | // Calling `rewrite(list)()` will return a HOC that will match the provided list against incoming page requests and will redirect accordingly. 40 | export default redirect(list)(Error) 41 | ``` 42 | -------------------------------------------------------------------------------- /test/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "babelrc": false 3 | } 4 | -------------------------------------------------------------------------------- /test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "next": "^2.0.0-beta.31", 4 | "react": "^15.4.2", 5 | "react-dom": "^15.4.2" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/pages/_error.js: -------------------------------------------------------------------------------- 1 | import ErrorComponent from 'next/error' 2 | import redirect from 'next-universal-redirect' 3 | 4 | class Error extends React.Component { 5 | static getInitialProps ({ req, res, xhr, pathname }) { 6 | const statusCode = res ? res.statusCode : (xhr ? xhr.status : null) 7 | return { statusCode } 8 | } 9 | 10 | render () { 11 | return 12 | } 13 | } 14 | 15 | const list = new Map() 16 | list.set('/example', '/example2') 17 | 18 | export default redirect(list)(Error) 19 | -------------------------------------------------------------------------------- /test/pages/index.js: -------------------------------------------------------------------------------- 1 | import Link from 'next/link' 2 | 3 | export default () =>
4 | Go to example 5 |
6 | --------------------------------------------------------------------------------