Questions
30 of 33
1Explain server-side rendering (SSR) in Next.js.
2List the benefits of Server-Side Rendering in Next.js.
3What are server components?
4How to use server components in next js?
5What is the React Server Component Payload (RSC)?
6Describe how server components are rendered.
7Describe server rendering strategies
8How can you keep Server-only Code out of the Client Environment
9What are the issues of using context provider at the root of the application?
10List dynamic functions available to server components.
11List all Dynamic APIs.
12How do we opt for Static Rendering, Dynamic Rendering and Streaming?
13Explain the difference between SSR, SSG, ISR, and CSR in Next.js. When would you choose each?
14How does getServerSideProps work internally? What is its execution context?
15What are the performance trade-offs of SSR vs SSG in a high-traffic production app?
16How does Next.js handle hydration? What is a hydration mismatch, and how do you debug it?
17What happens when getServerSideProps throws an error? How do you handle it gracefully?
18How would you architect a Next.js app that needs both personalised (SSR) and cacheable (SSG) pages at scale?
19Explain the App Router vs Pages Router SSR model differences. How does React Server Components change the SSR paradigm?
20How do React Server Components (RSC) differ from traditional SSR? Can they be used together?
21How does streaming SSR work in Next.js 13+? What role does Suspense play?
22How would you implement partial hydration or Islands Architecture in Next.js?
23Explain how Next.js handles data fetching waterfall problems in SSR and how you'd mitigate them.
24How would you implement partial hydration or Islands Architecture in Next.js?
25How do you implement caching strategies for SSR responses in Next.js? (CDN, Cache-Control, stale-while-revalidate)
26How would you reduce TTFB (Time to First Byte) in an SSR-heavy Next.js app?
27What's the difference between fetch caching in the App Router vs traditional getServerSideProps?
28How do you avoid redundant database/API calls across multiple server components on the same page?
29How do you securely handle authentication in SSR? What are the risks of passing tokens via cookies vs headers?
30How do you prevent sensitive server-side data from leaking to the client bundle?
31How would you implement role-based rendering on the server without exposing protected routes to the client?
32How do you debug SSR-only issues that don't appear in local development?
33How can we control dynamic rendering behaviour in next js?
30 / 33

How do you prevent sensitive server-side data from leaking to the client bundle?

Prevent sensitive data leaks by using the 'server-only' package, creating a protected Data Access Layer, filtering data into safe DTOs, and leveraging React Taint APIs for defense-in-depth

Preventing sensitive server-side data from leaking to the client is critical in Next.js applications, especially with the App Router where Server Components and Client Components coexist. The main risk occurs when server-only code (database queries, environment variables with secrets) is accidentally imported into Client Components or passed as props across the server-client boundary [citation:4]. Next.js provides multiple layers of protection: the 'server-only' package to enforce module boundaries, a Data Access Layer to centralize and sanitize data, Data Transfer Objects (DTOs) to expose only necessary fields, and experimental React Taint APIs for additional defense-in-depth [citation:1][citation:8].

Key Protection Strategies
  1. 1

    Use the 'server-only' package to mark modules that should never be imported into client components, causing build errors if accidentally imported [citation:1][citation:7].

  2. 2

    Create a dedicated Data Access Layer (DAL) that centralizes all data fetching and authorization logic on the server [citation:8].

  3. 3

    Implement Data Transfer Objects (DTOs) that return only the specific fields needed for rendering, never full database objects [citation:1][citation:8].

  4. 4

    Never pass entire data objects from Server Components to Client Components—always filter to only what's needed [citation:8].

  5. 5

    Use environment variables correctly: never prefix secrets with NEXT_PUBLIC_, which embeds them in the client bundle [citation:1][citation:4].

  6. 6

    Consider enabling experimental React Taint APIs to mark objects or values that should never cross the server-client boundary [citation:2][citation:8].

The most fundamental protection is the 'server-only' package, which causes a build error if a module is accidentally imported into client code [citation:1][citation:10]. This is especially important for modules that access environment variables, databases, or internal APIs. Install it with pnpm add server-only, then add import 'server-only' at the top of any server-only file. If a developer later imports this module into a Client Component, the build will fail with a clear error message, preventing the leak from reaching production [citation:1][citation:7].

Using 'server-only' to Protect Server Modules

The Next.js documentation recommends creating a dedicated Data Access Layer for new projects [citation:8]. This internal library controls how and when data is fetched, performs authorization checks, and returns safe, minimal Data Transfer Objects (DTOs) [citation:8]. The DAL should only run on the server and should never return full database objects. Instead, it projects only the fields needed for rendering. This centralizes all data access logic, making it easier to enforce consistent security and reducing the risk of authorization bugs [citation:8].

Complete DAL and DTO Pattern

A common mistake is fetching a full database object in a Server Component and passing it directly to a Client Component as props [citation:8]. This exposes all fields—including sensitive ones like password hashes, internal notes, or API keys—to the client bundle. Even if you don't render them, they're still present in the serialized props [citation:8]. Always filter your data before passing it across the boundary. The Next.js documentation emphasizes that you should sanitize the data before passing it to the Client Component [citation:8].

What NOT to Do

Environment variables with the NEXT_PUBLIC_ prefix are inlined into the JavaScript bundle at build time and become visible to anyone using browser DevTools [citation:1][citation:4]. Never prefix secrets like database URLs, API keys, or authentication tokens with NEXT_PUBLIC_. Use standard variable names (e.g., DATABASE_URL) for server-only secrets, and only access them in Server Components, API routes, or the Data Access Layer [citation:1]. Create a .env.example file to document required variables without exposing real values [citation:1].

Environment Variable Examples

Next.js supports experimental React Taint APIs that provide an additional layer of defense [citation:2][citation:8]. You can enable them in next.config.js with experimental.taint: true. The APIs include experimental_taintObjectReference to prevent entire objects from crossing the server-client boundary, and experimental_taintUniqueValue to taint specific values like API keys [citation:2]. If a tainted object or value is passed to a Client Component, React throws an error. However, the documentation warns not to rely on tainting as your only mechanism—it's a defensive addition, not a replacement for proper data filtering [citation:2][citation:8].

Taint API Examples
Additional Best Practices
  1. 1

    Use folder conventions: Place all server-only code in a lib/server directory to make boundaries explicit [citation:7].

  2. 2

    Never trust client input: Always validate and sanitize data from forms, URL parameters, and headers—even in Server Actions [citation:8].

  3. 3

    Use parameterized queries: Prevent SQL injection by using database APIs that support safe templating [citation:8].

  4. 4

    Review bundle size: Use @next/bundle-analyzer to periodically check what's included in your client bundles [citation:3][citation:6].

  5. 5

    Implement authorization checks: Always verify permissions in the Data Access Layer, not just in middleware [citation:4][citation:8].