Static Site Generator ↔ Serverless Function: build-time reference to runtime endpoint
0 reputation · 09 Aug 2021, 07:43 UTC
0 reputation · 09 Aug 2021, 07:43 UTC
A JAMstack configuration is being designed where a static site generator pre-renders pages at build time and the site relies on serverless functions for request-time data. The integration boundary is between the SSG build process and the serverless function runtime.
Local builds commonly use .env.local for configuration, while production hosts require environment variables to be supplied via platform UI or secret stores. Public versus secret variable naming, such as NEXT_PUBLIC_ prefixes, is platform-specific. The SSG may need a function URL or API base during build for static generation, while the function itself only exists after deployment.
Dynamic routes that depend on runtime data can be generated locally with mock data, but the availability of the function and the correct variable scope at build versus runtime is not consistently defined across providers.
What is the expected contract for resolving a serverless function URL when the SSG builds pages before the function is deployed? Should public environment variables be required at build time or only at runtime for client-side calls? How should build-time versus runtime variable scopes be distinguished without relying on provider-specific naming conventions?
31775 reputation · 09 Aug 2021, 09:07 UTC
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.
getStaticProps, Hugo data templates, Jekyll data files) can perform HTTP requests during the build step.The contract is therefore:
Use a clear separation of configuration files rather than relying on naming conventions:
.env.build) – loaded by the SSG during npm run build or the equivalent build command. This file is not bundled into the client output..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).
https://example.com/api/data).FUNCTION_URL=https://example.com/api/data, to .env.build.process.env.FUNCTION_URL and perform the HTTP request to pre‑render pages.NEXT_PUBLIC_FUNCTION_URL only if your framework requires a public prefix, otherwise just rely on the runtime env).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).
Use comments to ask for clarification. Post a solution as an answer.
31,775 reputation · 09 Aug 2021, 14:47 UTC
During the SSG build, treat the function URL as a build‑only constant that is injected into the build process but stripped from the final client bundle. For example, in Next.js you can define a variable like NEXT_BUILD_FUNCTION_URL (without the NEXT_PUBLIC_ prefix) and reference it only in getStaticProps or getServerSideProps. After deployment, a small post‑deploy script writes the live invoke URL to a file such as public/function-manifest.json. The SSG then reads that manifest at runtime via a client‑side fetch or a serverless wrapper, so the static HTML never contains a hard‑coded URL. This keeps the build‑time dependency explicit while avoiding accidental exposure of the URL to the browser.