Next.js Application Logging Integration
Send structured logs from Next.js applications to LogTide with instrumentation hooks, error boundaries, and navigation tracking.
LogTide’s Next.js SDK (@logtide/nextjs) provides server-side instrumentation, client-side error boundaries, and navigation tracking for Next.js App Router applications.
Why use LogTide with Next.js?
- Instrumentation hook: Initialize once in
instrumentation.ts, capture all server errors - Error boundaries: Client-side React error capture with
LogtideErrorBoundary - Navigation tracking: Track client-side route changes as breadcrumbs
- Server + client: Separate DSNs for server and client-side logging
- Self-hosted option: Keep logs in your infrastructure
Prerequisites
- Next.js 14+ (App Router)
- Node.js 18+
- LogTide instance with a DSN
Installation
npm install @logtide/nextjs
Server-Side Setup
Initialize LogTide via the instrumentation hook:
// instrumentation.ts
import { registerLogtide } from '@logtide/nextjs/server';
export async function register() {
registerLogtide({
dsn: process.env.LOGTIDE_DSN!,
service: 'nextjs-app',
environment: process.env.NODE_ENV,
release: process.env.NEXT_PUBLIC_APP_VERSION,
});
}
Enable the hook in next.config.ts:
const nextConfig = {
experimental: {
instrumentationHook: true,
},
};
export default nextConfig;
Client-Side Setup
Initialize LogTide on the client:
// app/layout.tsx
import { initLogtide } from '@logtide/nextjs/client';
initLogtide({
dsn: process.env.NEXT_PUBLIC_LOGTIDE_DSN!,
environment: process.env.NODE_ENV,
});
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}
Environment Variables
# .env.local
LOGTIDE_DSN=https://[email protected]
NEXT_PUBLIC_LOGTIDE_DSN=https://[email protected]
NEXT_PUBLIC_APP_VERSION=1.0.0
Error Capture
Server-side errors in API routes, Server Components, and Server Actions are captured automatically via captureRequestError.
Error Boundary
Use LogtideErrorBoundary for client-side React error capture:
LogtideErrorBoundary wraps your component tree and reports any rendering
error it catches to LogTide. It accepts an optional fallback (a node, or a
(error) => node function) to render in place of the crashed subtree:
// app/providers.tsx
'use client';
import { LogtideErrorBoundary } from '@logtide/nextjs/client';
export function Providers({ children }: { children: React.ReactNode }) {
return (
<LogtideErrorBoundary fallback={<div>Something went wrong</div>}>
{children}
</LogtideErrorBoundary>
);
}
Then wrap your app with it in app/layout.tsx:
// app/layout.tsx
import { Providers } from './providers';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<Providers>{children}</Providers>
</body>
</html>
);
}
Navigation Tracking
Track client-side navigation as breadcrumbs:
// app/providers.tsx
'use client';
import { trackNavigation } from '@logtide/nextjs/client';
import { usePathname } from 'next/navigation';
import { useEffect } from 'react';
export function LogtideNavigationTracker() {
const pathname = usePathname();
useEffect(() => {
trackNavigation(pathname);
}, [pathname]);
return null;
}
API Route Logging
// app/api/users/[id]/route.ts
import { hub } from '@logtide/core';
export async function GET(
request: Request,
{ params }: { params: { id: string } }
) {
hub.captureLog('info', 'Fetching user', { userId: params.id });
try {
const user = await getUser(params.id);
return Response.json(user);
} catch (error) {
hub.captureError(error, {
extra: { userId: params.id },
});
return Response.json({ error: 'Internal error' }, { status: 500 });
}
}
Server Actions
// app/actions/user.ts
'use server';
import { hub } from '@logtide/core';
export async function updateUser(formData: FormData) {
const userId = formData.get('userId') as string;
hub.addBreadcrumb({
type: 'custom',
category: 'action',
message: 'Update user action triggered',
timestamp: Date.now(),
});
try {
await db.user.update({ where: { id: userId }, data: { name: formData.get('name') } });
hub.captureLog('info', 'User updated', { userId });
return { success: true };
} catch (error) {
hub.captureError(error, { extra: { userId } });
return { success: false };
}
}
Docker Deployment
FROM node:20-alpine AS base
FROM base AS deps
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable pnpm && pnpm install --frozen-lockfile
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN corepack enable pnpm && pnpm build
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
EXPOSE 3000
CMD ["node", "server.js"]
Next Steps
- JavaScript SDK - Core SDK reference
- Next.js SDK Reference - Full API documentation
- Docker Integration - Container deployment
- GDPR Compliance - Privacy-compliant logging
Frequently Asked Questions
How do I add LogTide logging to my Next.js application?
Install @logtide/nextjs, create an instrumentation.ts file that calls registerLogtide with your DSN, and enable the instrumentationHook in next.config.ts. Server-side errors in API routes, Server Components, and Server Actions are then captured automatically.
Does @logtide/nextjs support both server-side and client-side logging?
Yes. You initialize the server side in instrumentation.ts using registerLogtide from @logtide/nextjs/server, and the client side in app/layout.tsx using initLogtide from @logtide/nextjs/client. You can use separate DSNs for each via LOGTIDE_DSN and NEXT_PUBLIC_LOGTIDE_DSN environment variables.
How do I capture client-side React errors in Next.js with LogTide?
Wrap your component tree with the LogtideErrorBoundary component from @logtide/nextjs/client (for example in a client component rendered from app/layout.tsx). It automatically captures and forwards React rendering errors to LogTide, and accepts an optional fallback to render in place of the crashed subtree.
Can I track page navigation as breadcrumbs in a Next.js App Router application?
Yes. Import trackNavigation from @logtide/nextjs/client and call it inside a useEffect that watches the pathname from usePathname. Place this LogtideNavigationTracker component in your providers or layout to record every client-side route change.