Coder Social home page Coder Social logo

gvergnaud / nextjs-dynamic-routes Goto Github PK

View Code? Open in Web Editor NEW
140.0 6.0 7.0 508 KB

[Deprecated] Super simple way to create dynamic routes with Next.js

License: MIT License

JavaScript 100.00%
nextjs isomorphic routing url-parameters dynamic-routes router next

nextjs-dynamic-routes's People

Contributors

0xch4z avatar gabver2 avatar gvergnaud avatar lydell avatar tychovbh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

nextjs-dynamic-routes's Issues

What is the correct way to use query params?

Thank you for the library. I'm trying to add an optional query param to handle pagination:

/search/keywords/foo?page=2

and my route looks like this:

router.add({ name: 'search-keywords', pattern: '/search/keywords/:keywords'})

[Feature request] Path param prop checking

Currently, the Link component does not check that you have correctly passed any expected path params:

import React from 'react'
import { Link } from '../routes'

export default () => (
  <>
    <Link route="character" id="1"><a>Luke Skywalker</a></Link>
    <Link route="character"><a>C-3PO</a></Link> {/* Missing 'id' prop won't throw an error */}
  </>
)

I think that an error should be thrown to if the developer forgets to pass in the correct prop to save time debugging later down the track. In the above example, the id prop should be checked, and if it isn't passed into the Link component, an error should be thrown.

Question: Serverless NextJS ?

I'm sorry if this isn't related to an issue. It's one question about serverless environment.
How to use this library on serverless with interface:

function handler = async (req, res) => {
...
}

?

ReplaceRoute bug

 replaceRoute = (name, params = {}, options) => {
    const { page, pattern } = this.getRoute(name)
    const { href, as } = createLinkProps(page, pattern, params)
    return Router.replace(href, as, options)
  }

  prefetchRoute = (name, params = {}) => {
    const { page, pattern } = this.getRoute(name)
    const { href } = createLinkProps(page, pattern, params)
    return Router.prefetch(href)
  }

Should be NextRouter

Optional param, slash in address

router.add({
    name: 'register',
    pattern: '/register/:barcode?',
    page: '/register',
})

doing

router.replaceRoute('register', {}, { shallow: true })

resulting in an address:

http://localhost:3000/register/

Is it intentional ?
Though it is working, I would like the address to not include the slash: http://localhost:3000/register
How to achieve this? Need change in the package source?

Missing router events

It would be nice to be able to use router events like in nextjs.

see:
https://github.com/zeit/next.js/#router-events

so in this repo something like this:

import Router from ../routes'

const handleRouteChange = url => {
  console.log('App is changing to: ', url)
}

Router.events.on('routeChangeStart', handleRouteChange)

Add at least partial support for query parameters

I know there's been a previous issue about query parameters: #2. However, that issue only talks about how to link to a page with query parameters.

The bigger issue is that adding query parameters to any URL (in the address bar of the browser, for example) causes no routes to match! All 404s.

This is because req.url contains not only the pathname, but also the query string.

const { page, params } = this.getMatchingRoute(req.url)

The query string needs to be stripped out before trying to match routes. https://github.com/pillarjs/path-to-regexp#usage

Please note: The RegExp returned by path-to-regexp is intended for ordered data (e.g. pathnames, hostnames). It does not handle arbitrary data (e.g. query strings, URL fragments, JSON, etc).

Then, the query string needs to be parsed and be passed on to the page.

I monkey-patched the router in my routes.js to fix the above problems:

const _ = require("lodash");
const Router = require("nextjs-dynamic-routes");

const router = new Router();

// Workaround missing query string support in nextjs-dynamic-routes. Query
// parameters caused routes not to match (404) and weren't passed on.
const { getMatchingRoute } = router;
router.getMatchingRoute = urlString => {
  // https://stackoverflow.com/a/51525433/2010616
  const url = new URL(urlString, "https://host/");
  const urlParams = _.fromPairs(Array.from(url.searchParams));
  // `.getMatchingRoute` is bound so it can be called directly.
  const { page, params } = getMatchingRoute(url.pathname);
  return { page, params: Object.assign({}, urlParams, params) };
};

router.add({ name: "home", pattern: "/" });

I haven't found a nice way to link with query parameters, but I still think that fixing the above issues alone is a good thing. I was very surprised when I started getting 404s. After triple-checking my route patterns I finally figured out it was because of a query parameter...

Not working with name different from page

I want: the route to be named 'home' but file to be named 'index'
I write

router.add({
	name: 'home',
	pattern: '/',
	page: 'index',
})

But the loading is stuck

If I change to:

router.add({
	name: 'index',
	pattern: '/',
})

It works.

Am I doing something wrong?
Last version of the lib, last stable next, react@next

		"@emotion/core": "^10.0.6",
		"@emotion/styled": "^10.0.6",
		"@zeit/next-sass": "^1.0.1",
		"express": "^4.16.4",
		"formik": "^1.4.2",
		"isomorphic-unfetch": "^3.0.0",
		"js-cookie": "^2.2.0",
		"next": "latest",
		"next-compose-plugins": "^2.1.1",
		"next-cookies": "^1.0.4",
		"next-redux-wrapper": "^2.1.0",
		"nextjs-dynamic-routes": "^2.3.0",
		"node-sass": "^4.11.0",
		"react": "^16.7.0-alpha.2",
		"react-dom": "^16.7.0-alpha.2",
		"react-easy-state": "^6.1.0",
		"react-modal": "^3.8.1",
		"react-progress-button": "^5.1.0",
		"react-reim": "^1.14.1",
		"reim": "^1.13.0",
		"yup": "^0.26.6"

Route doesn't work when page is index

Hi! I've faced this issue a couple of times,

.add({ name: "admin_index", pattern: "/admin", page: "/admin/index" })

That page doesn't work since it points to an index file.
Changing the file name to a different thing solves the issue

Why when I refresh the page, it shows that the page was not found?

I used nextjs-dynamic-routes in my router. all links is worked, but before refresh page , Shows me not found.

--pages
   |
   |- -index
   | --blogs
   |     |     
   |     |--index
   |     |--[post]

[post].js

class Post extends React.Component{
    state={
        data:null,
        post:'',
        title:'',
        content:'',
        imageUid:'',
        status:0,
        loading:true
    }
    componentDidMount(){
        console.log(this.props);
        this.setState({loading:true});
        const post = Router.router.query.post;
        if(post != undefined){
            if(this.state.data == null){
                this.getPost(post);
            }
        }
        
    }
    getPost = async (post)=>{
        const res = await this.props.setPostDetalis(post);
        this.setState({loading:false}),1000;
        this.setState({
            title: res.data.data.object.title,
            content: res.data.data.object.content,
            imageUid: res.data.data.object.attachments[0].uid,
            data: res.data.data,
            status:res.data.status
        });
        

    }
    componentDidUpdate(){
        const post = Router.router.query.post;
        if(post != undefined){
            if(this.state.data == null){
                this.state.loading=true;
                this.getPost(post);
            }
            
        }
        
        
    }
    Keywords = () => {
        const data = this.state.data.tags.map((item) => item.title);
        return data.toString();
    }
    render(){
        return (

            <div>
                  {this.state.title}
          </div >

        )
    }
}

const pagePost = withRouter(Post);

const mapStateToProps = (state)=>{
    return state
}
const mapDispatchToProps = {
    setPostDetalis : setPostDetalis
}
const pagePostIndex = pagePost;

export default connect(mapStateToProps,mapDispatchToProps)(pagePostIndex);

router.js

const Router = require('nextjs-dynamic-routes')
 
const router = new Router()
 
 
router.add({ name: 'post', pattern: '/blogs/:post' })

 
module.exports = router

server.js

const express = require('express');
const next = require('next');
const { parse } = require('url');

const DEV = process.env.ENVIRONMENT !== 'production';
const PORT = 9000;

const app = next({dir: '.', dev: DEV});
const handle = app.getRequestHandler();

const getRoutes = require('./routes');

const routes = getRoutes();
  app.prepare().then(() => {
    const server = express();
    //server.get('/blog/:id', (req, res) => ssrCache({ req, res }))
    server.get('*', (req, res) => {
      const parsedUrl = parse(req.url, true);
      const { pathname, query } = parsedUrl;
      const route = routes[pathname];
      if (route) {
        return app.render(req, res, route.page, route.query);
      }
      return handle(req, res);
    });

    server.listen(PORT, (err) => {
      if (err) throw err;
      console.log(`> READY FOR LIFOTFF http://localhost:${PORT}`);
    });
  });

Support query parameters with the same name as url params?

Context: #15 (comment)

Currently, you can’t have query parameters with the same name as a URL param. The URL param takes precedence and the query param is discarded. For example, with the pattern /test/:id, the URL /test/1?id=a always gives you { id: "1" } and you can’t see that the user passed id=a.

In Next.js, if you pass the same query parameter multiple times, such as ?x=a&x=b you get a query object like this: { x: ["a", "b"] }

In other words, you get an array of all the values for the param.

Now to the question: Should we do something similar to support query params with the same name as URL params? For example, /test/1?id=a could result in { id: ["1", "a"] }. Or maybe the URL param should go at the end, since one might be used to take the last query param value when the user has given multiple but only one is supported? { id: ["a", "1"] }.

So – why should we do this? It makes the library a little bit more flexible and "complete", I guess. But maybe it would just make things easier to screw up. It’s easy to forget that you might get an array and forget to handle that, or you might take the wrong value from the array. And I guess it’s easier to just rename the URL param or query param to not conflict, anyway. Probably makes your code easier to understand, too.

What do you think?

Question: Choose the pattern to display in the URL with Link

Hi. I don't know if i'm doing something wrong, but i have the following issue:
I have the route router.add({ name: 'index', pattern: '/(|index)', page: '/home' }) and this works for both url / and /index, which is what i want. But, when i have a Link that goes to the route index, the url changes to /(%7Cindex), and i wanted to go to / . My question is: there is a way to choose what pattern i would like to show on the url when i click on a Link?

I found a way to make it work by using two differents routes: router.add({ name: 'home', pattern: '/', page: '/home' }) and router.add({ name: 'index', pattern: '/index', page: '/home' }), but i wanted to know if there was a way to make the same without duplicating the route.

Optional path segments almost working

I'm trying to use this with a path that has an optional path segment like this...

router.add({ name: 'company', pattern: '/company/:slug/:view?' })

The route works but generating routes with Link or Router doesn't quite work as expected. Currently, this is what happens...

Not including optional param:
Router.pushRoute('company', { slug='google' } results in /company/google/:view?

Including optional param as an empty string:
Router.pushRoute('company', { slug='google', view='' } results in /company/google/?`

Fortunately, the latter works well enough for me, but I would expect both to simply return /company/google

I'm not sure if you were intending support for this. It looks like the regex at the end of replaceWithParams is trying to do something like this, but doesn't quite match :view? as in my example above.

export const replaceWithParams = (pattern, params) =>
  Object.keys(params)
    .reduce((acc, param) => acc.replace(`:${param}`, params[param]), pattern)
    .replace(/:[^\/&\?]*(\/|$)/g, '')

I wanted to find out if you have any interest in supporting this before submitting a PR. Also, before doing so I wanted to make sure I fully understand what that regex is supposed to do.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.