How to Hide API Endpoints in Next.js


In Next.js, securing sensitive data and preventing the exposure of API endpoints is critical for building secure web applications. When fetching data, the approach you choose direct or indirect determines whether API endpoints are visible in the browser’s network tab. This article explores how to hide API endpoints in Next.js, using two Proof of Concept (POCs) examples to compare direct and indirect data fetching. We’ll demonstrate how direct fetching keeps endpoints hidden and provide best practices for securing your Next.js app, based on a project using Next.js 15.5.0, React 19.1.0, and Supabase.



Project Structure and Setup

The examples in this article are based on a Next.js project with the following setup,

  • Next.js (v 15.5.0)
  • React (v 19.0.1)
  • Supabase
  • Directory Structure

Directory Structure

This setup uses a Supabase table named post with columns post (string) and keyword (string) to store and query data based on user-selected keywords. The POCs demonstrate fetching posts matching a selected keyword, highlighting the differences in endpoint exposure.



Understanding API Endpoint Exposure

When you fetch data in a Next.js application, the method you use determines whether the data-fetching process is visible in the browser’s network tab,

  • Indirect Fetching – Involves calling an API endpoint (e.g., a Next.js API route or external service) via HTTP requests, which are visible in the network tab, exposing the endpoint URL, request payload, and response data.
  • Direct Fetching – Executes data fetching within the app, typically server-side, without creating a public API endpoint, making it invisible in the network tab.

Hiding API endpoints is critical to prevent attackers from inspecting sensitive data, reverse-engineering your API, or exploiting unprotected endpoints. Let’s examine both approaches using POCs that fetch data from a Supabase database.



Indirect Data Fetching (Exposed API Endpoints)

Indirect fetching involves calling a Next.js API route or external service from the client side, creating visible HTTP requests. Here’s a POC demonstrating this approach.



POC – Indirect Fetching with an API Route

In this POC, a Next.js app fetches posts from a Supabase database by calling an API route (/api/getPost).

repo

Indirect Fetching



Observations

  • Exposed Endpoint – The /api/getPost endpoint is publicly accessible and appears in the browser’s network tab. The request (e.g., POST /api/getPost with payload { keyword: selectedValue }) and response (e.g., { success: true, data: […] }) are visible.
  • Security Risk – Without authentication or rate limiting, anyone can call this endpoint, potentially exposing sensitive data or allowing abuse (e.g., brute-forcing keywords).



Direct Data Fetching (Hiding API Endpoints)

Direct fetching involves retrieving data within the Next.js app, typically server side, without exposing an API endpoint. This approach leverages Next.js’s Server Components or server actions to keep data fetching internal.



POC – Direct Fetching with Server Actions

In this POC, the app fetches posts from Supabase using a server action, with no public API endpoint.

repo

Direct Fetching



Observations

  • No Endpoint Exposure – The getPost function is a server action, executed server-side via Next.js’s App Router. No public API endpoint is created, so nothing appears in the network tab related to the data fetch.
  • Security Benefit – Sensitive operations (e.g., Supabase queries with API keys) remain server side, hidden from the client, reducing the risk of exposing implementation details.



Why Direct Fetching Hides API Endpoints

In the direct fetching POC, the “use server” directive ensures that the getPost function runs on the server, not the client. When the client-side component calls callGetPostData, Next.js handles the request internally as a server action, serializing the response into the JavaScript bundle or rendered HTML. This process,

  • Eliminates the need for a public API endpoint.
  • Prevents network requests from appearing in the browser’s network tab.
  • Keeps sensitive data (e.g., Supabase credentials) secure on the server.

In contrast, the indirect fetching POC’s /api/getPost endpoint is a standard HTTP API, accessible to anyone unless secured, and its requests are visible in the network tab.



Best Practices for Hiding API Endpoints

  • Prioritize Server-Side Fetching – Use Server Components or server actions for sensitive data operations to avoid exposing endpoints.
  • Secure API Routes – If using indirect fetching, implement authentication, rate-limiting, and input validation.
  • Hide Sensitive Data – Store Supabase credentials and other secrets in .env.local files, as done in the POCs.
  • Monitor Network Exposure – Test your app’s network tab to ensure no sensitive endpoints or data are visible.
  • Use Incremental Static Regeneration (ISR) – For static sites, fetch data at build time or during revalidation to avoid runtime API calls.



Conclusion

Hiding API endpoints in Next.js is achievable by favoring direct data fetching with server actions or Server Components, as demonstrated in the direct fetching POC using Next.js 15.5.0, React 19.1.0, and Supabase. This approach keeps data retrieval internal, preventing endpoint exposure in the browser’s network tab and enhancing security. In contrast, indirect fetching, as shown in the API route POC, exposes endpoints, requiring additional security measures like authentication or middleware. By leveraging direct fetching for sensitive operations and securing any necessary API routes, you can build secure, performant Next.js applications that protect your data and implementation details.



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *