Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding an example for universal custom routing #913

Closed
Closed
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
21 changes: 21 additions & 0 deletions examples/custom-universal-routing/components/link.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react'
import NextLink from 'next/link'
import {customRoutes} from '../next.config'

function matchInternal (route) {
const match = customRoutes.find((element) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this match boolean be memorized for performance?

return route.match(element.test)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about if we written this like this:

element.test(route)

})

return match ? match.routeTo : false
}

export default class Link extends React.Component {
render () {
const internalRoute = matchInternal(this.props.href)

return <NextLink href={internalRoute} as={this.props.href}>
{this.props.children}
</NextLink>
}
}
9 changes: 9 additions & 0 deletions examples/custom-universal-routing/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
customRoutes: [{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like using next.config.js as the place for this. But in this file, we might import a lot of server only modules.
So, when we import this on both environments, that'll be an issue.

So, let's use a different file called routes.json or routes.js

test: /^\/$/,
routeTo: '/foo'
}, {
test: /^\/about(\/?)$/,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use path-to-regexp for express like route URLs.

routeTo: '/bar'
}]
}
10 changes: 10 additions & 0 deletions examples/custom-universal-routing/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"scripts": {
"dev": "node server.js",
"build": "next build",
"start": "NODE_ENV=production node server.js"
},
"dependencies": {
"next": "^2.0.0-beta"
}
}
11 changes: 11 additions & 0 deletions examples/custom-universal-routing/pages/bar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react'
import Link from '../components/link'

export default class Bar extends React.Component {
render () {
return <div>
<h1>About (Bar Template)</h1>
<div>Click <Link href='/'><a>here</a></Link> to go back home.</div>
</div>
}
}
11 changes: 11 additions & 0 deletions examples/custom-universal-routing/pages/foo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react'
import Link from '../components/link'

export default class Foo extends React.Component {
render () {
return <div>
<h1>Home (Foo Template)</h1>
<div>Click <Link href='/about'><a>here</a></Link> to see the about page.</div>
</div>
}
}
30 changes: 30 additions & 0 deletions examples/custom-universal-routing/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const { createServer } = require('http')
const { parse } = require('url')

const next = require('next')
const nextConfig = require('./next.config')

const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

app.prepare()
.then(() => {
createServer((req, res) => {
const { pathname, query } = parse(req.url, true)

const match = nextConfig.customRoutes.find((definition) => {
return pathname.match(definition.test)
})

if (match) {
app.render(req, res, match.routeTo, query)
} else {
handle(req, res)
}
})
.listen(3000, (err) => {
if (err) throw err
console.log('> Ready on http://localhost:3000')
})
})