Next.js Discord

Discord Forum

API Keys in Server Components

Answered
MooKorea posted this in #help-forum
Open in Discord
Hello,
I have the following server component which fetches data from a Google Spreadsheet, and it seems to work fine (if anything is wrong with the code please let me know)
export default async function FetchAnnouncements() {
  const spreadsheet_id = process.env.SPREADSHEET_ID;
  const tab_name = "Announcements";
  const api_key = process.env.SPREADSHEET_KEY;
  const url = `https://sheets.googleapis.com/v4/spreadsheets/${spreadsheet_id}/values/${tab_name}?alt=json&key=${api_key}`;

  try {
    const res = await fetch(url);
    const result = await res.json();
    const { values } = result;
    return values
      ?.slice(1)
      .reverse()
      .map((e: string[], i: number) => {
        return <Item name={e[1]} date={e[2]} text={e[0]} key={i} />;
      });
  } catch (err) {
    console.error(err);
    return <div className="p-5">An error occurred when fetching announcements</div>;
  }
}

This is actually a rewrite of a React application where it had the API keys exposed on the client. Now that it's rewritten as a server component in Next.js 14, should I have to worry about the keys being exposed to the client? Also, I read that server components are statically rendered—does that mean if I update the database (spreadsheet), I'll have to rebuild and redeploy the application to show the latest data?
Answered by ᴉuɐpɹɐɐ
Now that it's rewritten as a server component in Next.js 14, should I have to worry about the keys being exposed to the client?
If your api key is not intentionally getting passed to the client, it should be safe.
Also that you dont prefix your ENv name with NEXT_PUBLIC_ then your api key also can't be directly referenced in the client. (it will return undefined).

You can also import server-only so that the component that consumes your API key doesnt accidentally get imported to Client Components (via develoepr mistake).

These preventions should be enough when using API key in the server component. You can further protect it by implementing th react (experimental) taint API. To protect developers from accidentally passing the api key values to the client component xD

https://react.dev/reference/react/experimental_taintObjectReference
View full answer

6 Replies

https://tigerabrodi.blog/nuances-of-server-actions-in-nextjs
https://joulev.dev/blogs/throwing-expected-errors-in-react-server-actions

Multiple questions here I think these two articles will provide most of your answers. Thats correct that the only thing exposed to the Client when using server actions is whatever you 'return' so ensure you only return data thats relevant to the client. Throwing does not automatically return an error object, as a server action cannot throw. You must 'return' something.
In dev it will throw properly to the client, but in build it will not.
Its a security feature.
I'm talking about server components, not server actions @Jboncz
Now that it's rewritten as a server component in Next.js 14, should I have to worry about the keys being exposed to the client?
If your api key is not intentionally getting passed to the client, it should be safe.
Also that you dont prefix your ENv name with NEXT_PUBLIC_ then your api key also can't be directly referenced in the client. (it will return undefined).

You can also import server-only so that the component that consumes your API key doesnt accidentally get imported to Client Components (via develoepr mistake).

These preventions should be enough when using API key in the server component. You can further protect it by implementing th react (experimental) taint API. To protect developers from accidentally passing the api key values to the client component xD

https://react.dev/reference/react/experimental_taintObjectReference
Answer
regarding my other question about server components, I figured out that the cache can be revalidated on-demand with the revalidateTag function