Next.js-express dynamic routing causes page reload

12,362

Replace

<Link 
 href={`/blog/${dynamicPostSlug}`}>

with

<Link 
 href={`/blog/post?postslug=${dynamicPostSlug}`} 
 as={`/blog/${dynamicPostSlug}`}>

The getInitialProps should get query out of paramenters instead of req.

static async getInitialProps({ query }) {
    try {
      const res = await fetch(`http://localhost/api/posts/${query.postslug}`, {
        method: 'GET', // *GET, POST, PUT, DELETE, etc.
        mode: 'cors', // no-cors, cors, *same-origin
      });
      const json = await res.json();
      return { data: json.data };
    } catch (err) {
      console.log('err');
    }
  }
Share:
12,362
Muljayan
Author by

Muljayan

A computer science student interested in Web and AI technologies.

Updated on June 17, 2022

Comments

  • Muljayan
    Muljayan almost 2 years

    I have a blog application created with next js using an express custom browser. When i click on a Link to route to '/blog/article-1' it refreshes the page on arriving at that page. How do i avoid this?

    server.js file

    const express = require('express');
    const next = require('next');
    const port = 80;
    const dev = process.env.NODE_ENV !== 'production';
    const app = next({ dev });
    const handle = app.getRequestHandler();
    const compression = require('compression');
    
    app.prepare()
      .then(() => {
        const server = express();
        server.use(compression());
        server.get('/blog', (req, res) => app.render(req, res, '/blog', req.query));
        server.get('/blog/:postslug', (req, res) => {
          const params = { postslug: req.params.postslug }
          return app.render(req, res, '/blog/post', params)
        });
    
        server.get('*', (req, res) => handle(req, res));
    
        server.listen(port, (err) => {
          if (err) throw err;
          console.log(`> Ready on http://localhost:${port}`);
        });
    });
    

    File which links to articles

    import React, { Fragment } from 'react';
    import Link from 'next/link';
    
    export default (props) => {
    
      return (
        <Fragment>
          <Link href={`/blog/${dynamicPostSlug}`}>
            <a>
              Go to article
            </a>
          </Link>
        </Fragment>
      );
    };
    

    File where post appears

    import React, { Component, Fragment } from 'react';
    import { withRouter } from 'next/router';
    import 'isomorphic-unfetch';
    
    class post extends Component {
    
      static async getInitialProps({ req }) {
        try {
          const res = await fetch(`http://localhost/api/posts/${req.params.postslug}`, {
            method: 'GET', // *GET, POST, PUT, DELETE, etc.
            mode: 'cors', // no-cors, cors, *same-origin
          });
          const json = await res.json();
          return { data: json.data };
        } catch (err) {
          console.log('err');
        }
      }
    
      render() {
        const { data } = this.props;
        return (
          <Fragment>
            <PostContentComesHere data={data}/>
          </Fragment>
        );
      }
    }
    export default withRouter(post);
    

    I have already checked the next.js docs and it has this implementation which uses the node http module. I implemented this code on express by copying some parts from the documentation example. However it still seems to cause a page reload when i go to the article page using a .

  • Muljayan
    Muljayan about 5 years
    Hey. So there seems to be a new issue arising with this answer. In the method static async getInitialProps({ req }) the req parameter is giving undefined.
  • evgeni fotia
    evgeni fotia about 5 years
    @Muljayan use query instead static async getInitialProps({ query })
  • sareek
    sareek almost 4 years
    Did this slove the issue?? Still on my side page is refreshed.
  • John C
    John C over 3 years
    This solution is missing a critical part. The href has to include square brakets [] around the dynamic file. Example: /blog/[post]?postslug=${dynamicPostSlug}