Quick Summary
In Next.js, requests made from Server Components, route handlers, server actions and middleware run on the server, so they never appear in the Network tab of your browser. To see them, you need to look in the terminal where Next.js is running, turn on fetch logging in next.config.js, wrap fetch in a small logger, and use middleware, route handler logs, instrumentation and the Node.js inspector when you need more detail. This guide explains what these requests are, why they are hidden, who needs to debug them, which tools to use, where the logs appear, and how to set everything up step by step.
Key takeaways
- Server side
console.log output goes to your terminal, not the browser console. - The
logging.fetches option in next.config.js prints every server fetch with its status and timing. - A small fetch wrapper gives you control over what gets logged, including duration and status.
- Middleware shows you every incoming request before it reaches a page or route.
- The Node.js inspector lets you pause execution and inspect real request data.
- Always remove secrets and personal data from logs.
Table of Contents
- What Are Server Side Requests in Next.js?
- Why Can’t You See Them in the Browser?
- Who Needs This Guide?
- Which Requests Can You Inspect?
- Where Do Server Logs Appear?
- How to Debug Server Side Requests in Next.js
- Common Problems and How to Fix Them
- Best Practices for Request Logging
- Frequently Asked Questions
- Conclusion
What Are Server Side Requests in Next.js?
A server side request is any HTTP call that your Next.js application makes from the server instead of from the visitor’s browser. In the App Router, this happens in several places:
- Server Components that call
fetch to load data before rendering - Route handlers (files such as
app/api/products/route.ts) that call databases or third party APIs - Server actions that submit data or trigger back end work
- Middleware that reads, rewrites or redirects incoming requests
- Build time data fetching for statically generated pages
The visitor only receives the finished HTML and any client side JavaScript. The calls that produced that HTML happened earlier, on your server or at build time.
Why Can’t You See Them in the Browser?
Browser developer tools only record network activity that starts inside the browser. When a Server Component fetches data, the request leaves your server and goes to the API or database. The browser never sees it, so the Network tab stays empty for those calls.
This is a design benefit. It keeps API keys, internal URLs and database queries away from the client. It also means you need different tools to debug the server side of your application.
The most common reasons developers feel their requests are invisible:
- They are looking in the browser console instead of the terminal.
- The request ran at build time, not at request time.
- The response came from a cache, so no new request was sent.
- The code runs in the Edge runtime, which has different logging behavior.
- Logs are filtered or hidden by the hosting platform in production.
Who Needs This Guide?
This guide is useful for anyone who builds, tests or maintains a Next.js application:
- Front end developers moving from the Pages Router to the App Router
- Full stack developers who work with Server Components and route handlers
- Technical SEO specialists who need to confirm that pages render the right data for crawlers
- QA engineers who verify API behavior
- Team leads who want consistent logging across a project
Basic knowledge of React and JavaScript or TypeScript is enough to follow the steps below.
Which Requests Can You Inspect?
Different parts of a Next.js app need different logging approaches. This overview shows which tool fits which request type.
- Server Component fetch calls: use the
logging.fetches setting or a fetch wrapper. - Route handler calls: use
console.log inside the handler and log the incoming request details. - Server actions: log the inputs and outcome inside the action function.
- Incoming page and API requests: use middleware.
- Third party SDK calls that do not use
fetch: use the Node.js inspector or the SDK’s own debug option. - Cache behavior: use fetch logging and Next.js cache debug options.
Where Do Server Logs Appear?
The answer depends on where your app is running.
Local development. Logs appear in the terminal window where you ran npm run dev. In some versions, Next.js also replays certain server logs in the browser console during development, but the terminal remains the reliable source.
Production on your own server. Logs go to standard output and standard error. Use your process manager, container logs or a log service to read them.
Production on a hosting platform. Logs appear in the platform’s dashboard or log viewer. Retention time and filtering rules vary by provider, so check your platform’s documentation.
Build time. Logs from static page generation appear in the output of npm run build.
How to Debug Server Side Requests in Next.js
Step 1: Check the Terminal First
Add a simple log to a Server Component and reload the page:
export default async function ProductsPage() {
console.log('ProductsPage rendering on the server');
const res = await fetch('https://api.example.com/products');
const products = await res.json();
console.log('Products received:', products.length);
return <pre>{JSON.stringify(products, null, 2)}</pre>;
}
If the messages show up in the terminal, your code is running and logging works. If nothing appears, the page may be statically generated or served from cache. Restart the dev server and try again.
Step 2: Turn On Built In Fetch Logging
Next.js can print every server side fetch call for you. Add this to next.config.js:
module.exports = {
logging: {
fetches: {
fullUrl: true,
},
},
};
After restarting the dev server, the terminal shows the method, URL, status code and duration of each fetch. It also indicates whether the response came from the cache. The fullUrl option prints the complete URL instead of a shortened version, which helps when query strings matter.
This setting is meant for development. It does not replace production monitoring.
Step 3: Create a Fetch Wrapper for Full Control
A wrapper function gives you a single place to log requests, measure time and handle errors:
// lib/logged-fetch.ts
export async function loggedFetch(url: string, init?: RequestInit) {
const method = init?.method ?? 'GET';
const start = Date.now();
try {
const res = await fetch(url, init);
console.log(`[fetch] ${method} ${url} ${res.status} ${Date.now() - start}ms`);
return res;
} catch (error) {
console.error(`[fetch failed] ${method} ${url}`, error);
throw error;
}
}
Use loggedFetch in place of fetch in your Server Components and route handlers. You get a consistent format that is easy to search in terminal output or a log service.
Step 4: Log Incoming Requests With Middleware
Middleware runs before a request reaches your page or route, so it is a good place to see everything that arrives:
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
console.log(`[middleware] ${request.method} ${request.nextUrl.pathname}`);
return NextResponse.next();
}
export const config = {
matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
};
The matcher skips static assets so your terminal stays readable. In newer Next.js versions, the middleware file convention has been renamed, so check the documentation for the current file name in your version.
Step 5: Log Inside Route Handlers
Route handlers are regular server functions, so you can log the method, path, query and body:
// app/api/orders/route.ts
export async function POST(request: Request) {
const body = await request.json();
console.log('[api] POST /api/orders', { itemCount: body.items?.length });
return Response.json({ ok: true });
}
Log only the fields you need. Avoid printing full request bodies that may contain passwords, tokens or personal details.
Step 6: Use the Instrumentation File for Global Visibility
Next.js supports an instrumentation.ts file that runs once when the server starts. You can use it to set up monitoring tools or, for short diagnostic sessions, to wrap the global fetch:
// instrumentation.ts
export async function register() {
if (process.env.NEXT_RUNTIME === 'nodejs') {
const originalFetch = globalThis.fetch;
globalThis.fetch = async (input, init) => {
const url = typeof input === 'string' ? input : input instanceof URL ? input.href : input.url;
console.log('[global fetch]', url);
return originalFetch(input, init);
};
}
}
Treat this as a temporary diagnostic tool. Next.js extends fetch itself for caching, so patching it permanently can cause unexpected behavior. For long term tracing, consider OpenTelemetry, which Next.js supports through the same instrumentation file.
Step 7: Attach the Node.js Inspector
When logs are not enough, pause the code and look at real values. Start the dev server with the inspector enabled:
NODE_OPTIONS='--inspect' npm run dev
Then open chrome://inspect in Chrome, or attach the debugger in VS Code. You can set breakpoints in Server Components, route handlers and server actions, then inspect variables, headers and responses step by step.
Step 8: Understand Caching Before You Blame the Network
Many missing requests are really cache hits. Behavior differs between Next.js versions. Some versions cache fetch results by default and some do not, so confirm the default for your version. Useful checks:
- Look at the fetch log output for cache status such as hit, miss or skip.
- Set
cache: 'no-store' on a fetch call to confirm that a fresh request is sent. - Check
revalidate values to see how long cached data stays valid. - Run a production build locally with
npm run build and npm run start, since development and production caching can differ.
Common Problems and How to Fix Them
Problem: No logs appear at all. The page may be statically rendered. Force dynamic rendering for testing, check the build output, or confirm that you are reading the correct terminal.
Problem: Logs appear only once. The result is likely cached. Use cache: 'no-store', revalidate the path, or restart the server.
Problem: Logs work locally but not in production. Check your hosting platform’s log viewer, its log retention rules and whether your code runs in the Edge runtime.
Problem: The request fails with no clear error. Wrap the call in a try and catch block and log the error object. Check environment variables, since a missing API key on the server is a frequent cause.
Problem: Logs are too noisy. Filter by route in middleware, use a log prefix such as [api] or [fetch], and limit logging to development with a check on process.env.NODE_ENV.
Problem: A request works in the browser but fails on the server. The server may be missing cookies, headers or authentication that the browser sends automatically. Forward the needed headers explicitly.
Best Practices for Request Logging
Good logging helps you solve problems quickly without creating security or performance issues.
- Use a consistent format with a clear prefix, method, URL, status and duration.
- Never log passwords, tokens, API keys, session cookies or personal data.
- Add a request identifier so you can follow one request across several log lines.
- Use log levels such as info, warn and error instead of only
console.log. - Turn off verbose logging in production unless you have a specific reason to keep it.
- Send production logs to a central log service so your team can search them.
- Measure duration, since slow requests often point to the real cause of a bug.
- Remove temporary diagnostic code, such as global fetch patches, after the investigation.
Frequently Asked Questions
Why don’t my server side fetch requests show in the browser Network tab?
They run on the server, not in the browser. Only requests started by client side code appear in the Network tab. Check your terminal or server logs instead.
Where does console.log output go in a Next.js Server Component?
It goes to the terminal that runs your Next.js server. In production, it goes to your server or hosting platform logs.
How do I log all fetch requests in Next.js?
Set logging.fetches in next.config.js for development, or use a fetch wrapper or the instrumentation file for more control.
Can I see Server Component requests in Chrome DevTools?
Not in the Network tab. You can attach Chrome DevTools to the Node.js process with the --inspect flag and debug server code with breakpoints.
How do I know if a request was served from the cache?
Enable fetch logging and read the cache status in the terminal output. You can also use cache: 'no-store' to confirm that a fresh request works.
Does middleware log requests made by Server Components?
No. Middleware logs the incoming request to your app. Outgoing requests made by your Server Components need fetch logging or a wrapper.
Is it safe to log request data in production?
It is safe only when you remove sensitive values and follow your privacy obligations. Log identifiers, status codes and timing instead of full request bodies.
What is the best way to monitor requests in a production Next.js app?
Use structured logging sent to a central service, and add OpenTelemetry tracing through the instrumentation file if you need a full view of request flow.
Conclusion
Server side requests in Next.js are not missing. They simply run in a different place from your browser. Start with the terminal, turn on fetch logging, add a small wrapper for the calls you care about, and use middleware and the Node.js inspector when you need deeper visibility. Check caching early, because it explains many cases where a request seems to disappear. Keep your logs clean, consistent and free of sensitive data, and your team will find and fix server side problems much faster.
For the most accurate and current details, review the official Next.js documentation on logging, instrumentation and caching for the version your project uses.
Source: Next.js Request Logger
Join the conversation! Your thoughts help the community grow.