You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// frontend/apps/web/src/lib/hey-api.tsimport{isServer}from'@/utils/runtime';import{PROCESS_ENV}from'@/config/process-env';// import { waitMs } from '@/utils/wait';importtype{CreateClientConfig}from'@/client/client.gen';const{NEXT_PUBLIC_API_URL}=PROCESS_ENV;/** Runtime config. Runs and imported both on server and in browser. */exportconstcreateClientConfig: CreateClientConfig=(config)=>({
...config,baseUrl: NEXT_PUBLIC_API_URL,credentials: 'include',
...(isServer() ? {fetch: serverFetch} : {}),});constserverFetch: typeoffetch=async(input,init={})=>{// Note: Dynamic import to avoid bundling 'next/headers' on clientconst{ cookies }=awaitimport('next/headers');constcookieStore=awaitcookies();constcookieHeader=cookieStore.getAll().map((c)=>`${c.name}=${c.value}`).join('; ');// Note: must append auth_cookie like this or content-type header will break in server actionsconstheaders=newHeaders(init.headers);headers.append('Cookie',cookieHeader);// test skeletons styling// await waitMs(3000);constresponse=fetch(input,{ ...init, headers });returnresponse;};
Here I have custom fetch function serverFetch to forward cookies. That is mostly irrelevant for this topic, but it's one example how to have async code in configuration, which is relevant for this thread. I see that export const createClientConfig: CreateClientConfig = (config) => ({...}) cannot be async.
Main idea:
I want to have reusable Docker image with runtime environment variables. Having dynamic baseUrl: NEXT_PUBLIC_API_URL applied on both server and client @hey-api/client-next is part of that requirement.
For runtime environment variables i would have to read them in import 'server-only' file, that will fork for server client but is unavailable for client that runs in browser.
import'server-only';import{processEnvSchema}from'@/schemas/config';import{validateData}from'@/utils/validation';import{ProcessEnvType}from'@/types/config';// Note: maybe function for runtime varsconstprocessEnvData: ProcessEnvType={NODE_ENV: process.env.NODE_ENV,NEXT_PUBLIC_SITE_URL: process.env.NEXT_PUBLIC_SITE_URL,NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL,};exportconstPROCESS_ENV=validateData(processEnvData,processEnvSchema);
For browser i would need to inject window.__ENV in some script tag in server component and use that to set baseUrl for client. Or make API endpoint and fetch env, but it would make it async. createClientConfig() isnt async to set async baseUrl, but fetch override is async function, I could set baseUrl via the first argument in fetch(input, { ...init, headers }).
These are all options and possible directions, more or less hacky, but is there already standard way to accomplish main goal? To set baseUrl at runtime for both server and client in a frontend/apps/web/src/lib/hey-api.ts file. I would want to avoid passing custom client instance for each specific call, or use client.setConfig() since runtimeConfigPathis already stated as proffered method, and I already use it for cookies.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
As stated in docs:
https://heyapi.dev/openapi-ts/clients/next-js#runtime-api
for
@hey-api/client-nextrecommended way to configure client is to set path to external fileruntimeConfigPath: './src/hey-api.ts', this is my file:https://github.com/nemanjam/full-stack-fastapi-template-nextjs/blob/main/frontend/apps/web/src/lib/hey-api.ts
Here I have custom fetch function
serverFetchto forward cookies. That is mostly irrelevant for this topic, but it's one example how to have async code in configuration, which is relevant for this thread. I see thatexport const createClientConfig: CreateClientConfig = (config) => ({...})cannot be async.Main idea:
I want to have reusable Docker image with runtime environment variables. Having dynamic
baseUrl: NEXT_PUBLIC_API_URLapplied on both server and client@hey-api/client-nextis part of that requirement.For runtime environment variables i would have to read them in
import 'server-only'file, that will fork for server client but is unavailable for client that runs in browser.For browser i would need to inject
window.__ENVin some script tag in server component and use that to set baseUrl for client. Or make API endpoint and fetch env, but it would make it async.createClientConfig()isnt async to set async baseUrl, butfetchoverride is async function, I could set baseUrl via the first argument infetch(input, { ...init, headers }).These are all options and possible directions, more or less hacky, but is there already standard way to accomplish main goal? To set baseUrl at runtime for both server and client in a
frontend/apps/web/src/lib/hey-api.tsfile. I would want to avoid passing custom client instance for each specific call, or useclient.setConfig()sinceruntimeConfigPathis already stated as proffered method, and I already use it for cookies.Beta Was this translation helpful? Give feedback.
All reactions