Back to Blog
Web Development

Practical getStaticProps Patterns for the Next.js Pages Router

Use getStaticProps for public build-time data, dynamic Pages Router routes, preview content, and incremental static regeneration without exposing secrets.

Terry Hunt
June 2, 2026
4 min read

getStaticProps still works in the Next.js Pages Router. It pre-renders a page at build time and serializes the returned props for the browser. That makes it a good fit for public data that can be known before a request, such as documentation, catalog pages, and CMS articles.

It is not an App Router API. New App Router work uses server components, fetch caching, and route-level revalidation instead. Keep that boundary clear when you maintain a mixed Next.js application.

Fetch public data at build time

export async function getStaticProps() {
  const response = await fetch("https://example.com/api/articles")
  if (!response.ok) throw new Error(`Article request failed: ${response.status}`)

  return {
    props: { articles: await response.json() },
    revalidate: 300,
  }
}

The function runs on the server. Its returned props do not stay private, though. Next.js includes them in the rendered page data, so never return tokens, private customer fields, or unrestricted database records.

Read local files directly

Build-time code can read a repository file or call a server-only library directly. Avoid calling your own API route from getStaticProps; importing the shared data function removes an extra network hop and keeps one implementation.

import { loadArticles } from "../lib/articles"

export async function getStaticProps() {
  return { props: { articles: await loadArticles() } }
}

Generate dynamic routes with getStaticPaths

A dynamic Pages Router file such as pages/articles/[slug].tsx pairs getStaticProps with getStaticPaths. The path function chooses which pages build ahead of time. The props function loads one record and should return notFound: true when the slug does not exist.

Use ISR for public data that changes

The revalidate value enables Incremental Static Regeneration. After that interval, the next eligible request can trigger regeneration while the existing page remains available. Treat the interval as a freshness decision, not a guarantee that a page changes at an exact second.

Handle failures deliberately

A failed required build-time request should usually fail the build so stale or incomplete content does not deploy unnoticed. For optional data, return an explicit empty state and monitor the failure. Catching every error and returning null can turn a broken integration into a successful deployment.

Check these boundaries

  • The page lives in the Pages Router.
  • The data is public and safe to serialize.
  • Missing records return notFound.
  • Dynamic paths have an intentional fallback policy.
  • ISR freshness matches the publishing workflow.

See the current Next.js getStaticProps documentation for the supported return values. If you are planning a broader application change, review Next.js development services or share the route and data requirements.

Related Articles

More articles in Web Development

Enjoyed This Article?

Get more tutorials and insights delivered to your inbox. No spam, just valuable content for web developers.