How can I use getInitialProps only during the NextJS site build?

后端 未结 2 1098
礼貌的吻别
礼貌的吻别 2021-02-09 03:41

When using NextJS to build a static site, I would like the getInitialProps method to fire only during the build step and not on the client.

In the build ste

相关标签:
2条回答
  • 2021-02-09 03:47

    I found the workaround with NextJs 9.0.3 (other versions may also work, I didn't test that)

    // XXXPage is your page
    
    XXXPage.getInitialProps = async (req) => {
      if (process.browser) {
        return __NEXT_DATA__.props.pageProps;
      }
      // original logic
    }

    0 讨论(0)
  • 2021-02-09 04:01

    Go with the answer by @dkms, which is the best solution for static site builds.


    Old answer

    There are two ways is one way that I've found to prevent code in getInitialProps from running on a page component load.

    1. Use a regular anchor tag without next/link to that page.

    getInitialProps only runs when the page is linked from a next/link component. If a regular JSX anchor <a href="/my-page">click me</a> is used instead, the component's getInitialProps will not be invoked. Direct page loads to NextJS static site pages will not invoke getInitialProps.

    Note that using a standard anchor instead of the next/link component will cause a full page refresh.

    Because this is a poor solution, I've submitted a feature request.


    2. Use req in the context argument to conditionally make the API call in getInitialProps.

    I believe what @evgenifotia wanted to convey is that req is undefined in a site that's been exported.

    // example usage of API call in getInitialProps
    import fetch from 'isomorphic-unfetch'
    
    function Page({ stars }) {
      return <div>Next stars: {stars}</div>
    }
    
    Page.getInitialProps = async (ctx) => {
      const { req } = ctx // context object: { req, res, pathname, query, asPath }
      if (req) { // will only run during the build (next export)
        const res = await fetch('https://api.github.com/repos/zeit/next.js')
        const json = await res.json()
        return { stars: json.stargazers_count }
      }
    
      return {}
    }
    
    export default Page
    

    For more information about getInitialProps, see the documentation. One example there confirms that req is expected to only be defined on the server (or during the exporting build):

    const userAgent = req ? req.headers['user-agent'] : navigator.userAgent`
    

    This second option may work for some scenarios, but not mine where returning an empty result from getInitialProps will affect the component's this.props.


    Note:

    Shallow routing is not the answer. According to the documentation (see under "Notes" section):

    Shallow routing works only for same page URL changes.

    0 讨论(0)
提交回复
热议问题