7

I'm using next.js and the import { useRouter } from 'next/router'.

However on initial load, router.query.id is undefined. It quickly fills in, but that initial load is a killer.

I'm trying to figure out how to do it, and tried:

export async function getStaticProps({ params }) {
  // params contains the post `id`.
  // If the route is like /posts/1, then params.id is 1
  // const res = await fetch(`https://.../posts/${params.id}`)
  // const post = await res.json()
  console.log(params)
  // Pass post data to the page via props
  return { props: { params } }
}

but this returns an error:

Error: getStaticPaths is required for dynamic SSG pages and is missing for '/app/d/[id]'.

I can't use getStaticPaths, since [id] is variable and can be any number of things.

So what's the best way to handle this?

5
  • What do you mean by "I can't use getStaticPaths, since [id] is variable and can be any number of things."? If you mean that you don't know all the id ahead of time and you want the pages to be static, you can use incremental static generation by specifying fallback: true in the returned value of getStaticPaths. Commented Jul 3, 2020 at 14:41
  • For dynamic routes, if you want to use getStaticProps for data-fetching, you have to provide an array of paths using getStaticPaths for pre-rendering the pages otherwise you will always get an error at build time. Commented Jul 3, 2020 at 14:45
  • I don't know all the ids. That's correct. I don't actually care about data-fetching during build time. I just want to ensure that the router.query.id is always there when the page loads. Commented Jul 3, 2020 at 14:50
  • Pages that are statically optimized will be hydrated without their route params provided, which means before the hydration query will be an empty object. caveats section in dynamic routes. That's the intended behaviour. Commented Jul 3, 2020 at 14:56
  • 1
    You can go for getServerSideProps with some sort of caching strategy with a custom server so pages will be generated on a per-request basis. Commented Jul 3, 2020 at 14:59

1 Answer 1

9

I would do smt like this(without staticProps):

function Page(props) {
  const router = useRouter();
  const { query = {} } = router || {};
  const { id = 0 } = query || {};
  
  useEffect(()=> {
    if(id) {
      (async ()=> {
        const res = await fetch(`https://.../posts/${id}`)
        const post = await res.json();
      })();
    }
  }, [id]);

}

And this is what official doc. says:

// You also have to define a Post component in the same file (pages/posts/[id].js)
function Post({ post }) {
  const router = useRouter()

  // If the page is not yet generated, this will be displayed
  // initially until getStaticProps() finishes running
  if (router.isFallback) {
    return <div>Loading...</div>
  }

  return <h1>Posts are here</h1>;
}

// This also gets called at build time
export async function getStaticProps({ params }) {
  // params contains the post `id`.
  // If the route is like /posts/1, then params.id is 1
  const res = await fetch(`https://.../posts/${params.id}`)
  const post = await res.json()

  // Pass post data to the page via props
  return { props: { post } }
}

UPDATE:

After a bit research, have figure out this solution with staticProps:

export default function Post({ post }) {
  return <h1>Post is here</h1>;
}


export async function getStaticPaths() {
  return {
    paths: [
      { params: { id: '*' } }
    ],
    fallback: true
  };
}
    
export async function getStaticProps(context) {

  const res = await fetch(`https://api.icndb.com/jokes/random/${context.params.id}`);
  const post = await res.json()
  return { props: { post } }
}
Sign up to request clarification or add additional context in comments.

2 Comments

@Shamoon Something is missing from the answer?
@VinceSanchezTañan for me it represents a dynamic id, what can be any value.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.