Answer
The serverless function must expose a stable, version‑agnostic HTTP endpoint that is reachable both during the SSG build step and at runtime. The build process can fetch that endpoint (or a mock) to embed data in the generated HTML, and the same URL is used by client‑side JavaScript for live updates.
Confirmed facts
- Static site generators (e.g., Next.js
getStaticProps, Hugo data templates, Jekyll data files) can perform HTTP requests during the build step.
- Serverless functions on platforms such as Vercel, Netlify, or AWS Lambda return a fixed URL that serves JSON and can be called from any client at runtime.
- During a build, the SSG may call the function’s URL (or a local mock), embed the returned JSON in the static output, and also ship client‑side code that later calls the same URL for runtime data.
Likely explanation
The contract is therefore:
- The function URL must be known to the build process (via an environment variable, a configuration file, or a service‑discovery mechanism).
- The same URL must be available to the browser after deployment; no transformation of the URL should occur between build and runtime.
- If the SSG needs the URL only to fetch data at build time, the variable can be treated as build‑only. If the URL is also used by client‑side code, it must be exposed as a runtime‑exposed variable (but never contain secrets).
Distinguishing build‑time vs runtime scopes without provider‑specific prefixes
Use a clear separation of configuration files rather than relying on naming conventions:
- Build‑only file (e.g.,
.env.build) – loaded by the SSG during npm run build or the equivalent build command. This file is not bundled into the client output.
- Runtime file (e.g.,
.env.runtime) – injected into the deployment environment (platform UI, secret store, or CI/CD) and made available to the browser only if the SSG explicitly includes it (e.g., via process.env replacement that strips non‑public keys).
By keeping these files separate, you avoid leaking build‑time secrets to the client and you do not need to rely on provider‑specific prefixes like NEXT_PUBLIC_. The SSG’s build step reads from the build‑only file; any value that must be accessed by client‑side code is copied into the runtime file (or passed through a safe‑exposure step).
Steps to implement for this case
- Deploy the serverless function and record its invariant URL (e.g.,
https://example.com/api/data).
- Add a build‑only environment variable, e.g.,
FUNCTION_URL=https://example.com/api/data, to .env.build.
- In the SSG build script (or data‑fetching function), read
process.env.FUNCTION_URL and perform the HTTP request to pre‑render pages.
- Ensure the same URL is available to the runtime environment (via the platform’s UI or secret store) and, if client‑side code needs it, expose it through a runtime‑only variable (e.g.,
NEXT_PUBLIC_FUNCTION_URL only if your framework requires a public prefix, otherwise just rely on the runtime env).
- After building, verify that the generated HTML contains the pre‑fetched data and that the client‑side fetch to the same URL returns the expected JSON at runtime.
Missing diagnostic detail
If your SSG does not provide a way to keep build‑only variables out of the client bundle, please confirm whether it supports a mechanism to strip or ignore certain environment variables during the build step. This detail would change the recommendation (e.g., needing a custom webpack/plugin step to filter variables).