question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Different getStaticPaths behavior with _app.js in development vs. production

See original GitHub issue

Bug report

Describe the bug

In _app.js, I have Amplify.configure(...) that stores a configuration for internal use with other Amplify features (e.g. API):

// pages/_app.js
import { Amplify, API } from "aws-amplify"

Amplify.configure({ ... })

export default function MyApp({ Component, pageProps }) {
// pages/index.js
import { API } from "aws-amplify"

export default function Home() {
  useEffect(() => {
	// API internally references the configuration in `Amplify`
    API.graphql(...).then(console.log)
  })
...

However, when using getStaticProps for a page, I found that the instance of Amplify isn’t configured when running next build. It’s as if _app.js isn’t imported or executed at all during the build!

To Reproduce

Simple reproduction here: https://github.com/ericclemmons/next.js-issues-16977/commit/bf9f827b937f74d44f6ae6224fc03250d27e6f80!

Notice how my static page pages/[isConfigured].js receives a value of true in development (due to _app.js setting the configuration) while false in production (because _app.js is presumably not called prior to executing getStaticPaths).

gsp-bug

👇 This is my “real-world” code from when I discovered this behavior. It shouldn’t differ from the simpler reproduction above.

// pages/_app.js
console.log('🕵️‍♀️', 'pages/_app.js', 'imported')

import '../styles/globals.css'
import { Amplify } from 'aws-amplify'
import awsExports from '../src/aws-exports'

console.log('🕵️‍♀️', 'pages/_app.js', 'Amplify.configure')
Amplify.configure({ ...awsExports, ssr: true })
console.log('🕵️‍♀️', 'pages/_app.js', 'Amplify configuration', Amplify.configure())

export default function MyApp({ Component, pageProps }) {
  console.log('🕵️‍♀️', 'pages/_app.js', 'MyApp')

  return <Component {...pageProps} />
}
// pages/posts/[id].js
console.log('🕵️‍♀️', 'pages/[id].js', 'imported')

import { Amplify, API, withSSRContext } from 'aws-amplify'
import Head from 'next/head'
import { useRouter } from 'next/router'
import styles from '../../styles/Home.module.css'
import { getPost, listPosts } from '../../src/graphql/queries'
import { deletePost } from '../../src/graphql/mutations'

console.log('🕵️‍♀️', 'pages/[id].js', 'Amplify configuration', Amplify.configure())

export async function getStaticPaths() {
  console.log('🕵️‍♀️', 'pages/[id].js', 'getStaticPaths')

  const SSR = withSSRContext()
  const response = await SSR.API.graphql({ query: listPosts })
  const paths = response.data.listPosts.items.map((post) => ({
    params: { id: post.id },
  }))

  return {
    // Statically build pages at run-time, but SSR any new ones after
    // See: https://nextjs.org/docs/basic-features/data-fetching#fallback-pages
    fallback: false,
    paths,
  }
}

// `/pages/posts/[id].js` => `params.id`
export async function getStaticProps({ params }) {
  console.log('🕵️‍♀️', 'pages/[id].js', 'getStaticProps')

  const SSR = withSSRContext()
  const response = await SSR.API.graphql({
    query: getPost,
    variables: { id: params.id },
  })

  return {
    props: {
      post: response.data.getPost,
    },
  }
}

export default function Post({ post }) {
  console.log('🕵️‍♀️', 'pages/[id].js', 'Post')

  const router = useRouter()

  if (router.isFallback) {
    return <div>Loading post...</div>
  }

  async function handleDelete() {
    await API.graphql({
      authMode: 'AMAZON_COGNITO_USER_POOLS',
      query: deletePost,
      variables: { input: { id: post.id } },
    })

    window.location.href = '/'
  }

  return (
    <div className={styles.container}>
      <Head>
        <title>{post.title} – Amplify + Next.js Blog</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main className={styles.main}>
        <h1 className={styles.title}>
          <small className={styles.description}>
            <a href="/">Home</a> &raquo;
          </small>

          {post.title}
        </h1>
        <p className={styles.description}>{post.content}</p>
      </main>

      <footer className={styles.footer}>
        <button onClick={handleDelete}>🗑 Delete Post</button>
      </footer>
    </div>
  )
}

Expected behavior

I expected that, if a page extends _app.js, any effects that may have occurred within that file to persist in other pages during the build process.

System information

  • OS: macOS
  • Version of Next.js: 9.5.3
  • Version of Node.js: 12.16.3

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:13
  • Comments:14 (3 by maintainers)

github_iconTop GitHub Comments

5reactions
koenoecommented, Oct 13, 2021

Still relevant for me, I’m on 11.1.2 with webpack 5

1reaction
ijjkcommented, Feb 24, 2022

Hi, this appears to be working consistently in the latest version of Next.js v12.1.0, please update and give it a try!

https://user-images.githubusercontent.com/22380829/155596037-aecc3521-5d36-44b8-9b6f-5f0d3f7433db.mp4

Read more comments on GitHub >

github_iconTop Results From Across the Web

Data Fetching: getStaticPaths - Next.js
Fetch data and generate static pages with `getStaticProps`. Learn more about this API for data fetching in Next.js.
Read more >
What is the difference between fallback false vs true vs ...
Notably, in development, getStaticPaths gets called on every render , so everything always gets rendered to their latest version, which is ...
Read more >
Next.js: Server-side Rendering vs. Static Generation - Vercel
To demonstrate, let's use a hypothetical e-commerce Next.js app as ... By creating a file called products/[id].js and having getStaticPaths ...
Read more >
Next.js: The Good, Bad and Ugly - An Idiosyncratic Blog
js gives you the best developer experience with all the features you need for production: hybrid static & server rendering, TypeScript support, ...
Read more >
What is getStaticPaths() in Nextjs? - DEV Community ‍ ‍
js app, please follow this article. Let's add a directory named blog under the pages folder. And add another route [blogId].js under the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found