Next.js: Can't get custom routes to work.

Created on 3 Jan 2017  路  8Comments  路  Source: vercel/next.js

Hi, I've a problem with custom routing, my dynamic routes are redirected to the pages handler, but since those pages don't exists it throws a 404 error.

One thing worth mentioning is that it works flawlessly with Javascript disabled.

This is Chrome's console when trying to fetch some category page
GET http://localhost:3000/_next/pages/some-category 404 (Not Found)

same with products

GET http://localhost:3000/_next/pages/some-category/some-product 404 (Not Found)

server.js

const { createServer } = require('http')
const { parse } = require('url')
const next = require('next')

const pathMatch = require('path-match')
const route = pathMatch()

// Routes
const categoryMatch = route('/:categorySlug')
const productMatch = route('/:categorySlug/:productSlug')

const app = next({ dev: true })
const handle = app.getRequestHandler()

app.prepare().then(() => {
  createServer((req, res) => {
    const { pathname } = parse(req.url, true)
    const category = categoryMatch(pathname)
    const product = productMatch(pathname)
    const hasUnderscore = pathname[1] && pathname[1] === '_'
    console.log(hasUnderscore, pathname, category, product)

    if (!hasUnderscore && category) {
      app.render(req, res, '/category', category)
    } else if (!hasUnderscore && product) {
      app.render(req, res, '/product', product)
    } else {
      handle(req, res)
    }
  })
  .listen(3000, (err) => {
    if (err) throw err
    console.log('> Ready on http://localhost:3000')
  })
})

pages/category.js

import React from 'react'
import Link from 'next/link'
import Header from '../components/Header'

import { getCategoryProducts } from '../lib/api'

export default class extends React.Component {
  static async getInitialProps ({ req, query }) {
    return await getCategoryProducts(query.categorySlug)
  }

  render () {
    const { products, category } = this.props
    const getModel = (product) =>
      product.model && product.model.reduce((p, n) => (`${p} ${n} `))
    return (
      <div>
        <Header />
        <ul>
          {products.map(product => (
            <li key={product.slug}>
              <Link href={`/${category.slug}/${product.slug}`}>
                <a>{`${product.name} ${getModel(product) || ''}`}</a>
              </Link>
            </li>
          ))}
        </ul>
      </div>
    )
  }
}

Most helpful comment

What do you guys think about having a function for custom routes?

import React from 'react'
export default class extends React.Component {
  route() { return '/test/:param1` }
  render () {
    return <div>
      Hello World {this.props.userAgent}
    </div>
  }
}

All 8 comments

You need to change your href in the link like this:

<Link href='/product' as={`/${category.slug}/${product.slug}`}>

Here href should be the real URL of the page.
as should be the custom URL.

@arunoda Thank you!

After trying this I was getting undefined in the query parameters on the client side, but in the server was fine; until I figured out that the parameter must be the same.

<Link
  href={`/product?categorySlug=${category.slug}&productSlug=${product.slug}`}
  as={`/${category.slug}/${product.slug}`}>
    <a>{product.name}</a>
</Link>

@arunoda maybe we should warn when you use a custom route w/o as? I got bitten by this as well

@rauchg Yep. That's a good idea.
But, if the user is not using custom routes as is not needed.

So, how do we find out that.
Even if user use custom routes, we probably don't know it's a custom route or not.
If we know a list of all the available pages in his app inside the client side, this is possible.

But It might add complexity to the app.
How about we make it pretty clear in the README.

Need to think about this more.

What do you guys think about having a function for custom routes?

import React from 'react'
export default class extends React.Component {
  route() { return '/test/:param1` }
  render () {
    return <div>
      Hello World {this.props.userAgent}
    </div>
  }
}

@pragmaticivan https://github.com/fridays/next-routes might help 馃憤
For the Next.js core the programmatic api is the way to go

Closing in favor of information provided above ^^^

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Knaackee picture Knaackee  路  122Comments

dunika picture dunika  路  58Comments

rauchg picture rauchg  路  208Comments

poyiding picture poyiding  路  73Comments

baldurh picture baldurh  路  74Comments