Beginner

Add Logging to a Next.js App

Set up LogFlow in a Next.js 14/15/16 project — capture server errors, API route logs, frontend exceptions, and view everything in your LogFlow dashboard.

LogFlow TeamJun 4, 202615 minNext.jsTypeScript

This tutorial walks through adding LogFlow to a Next.js application using the App Router. By the end, you'll have:

  • Server-side logging in API routes and Server Components
  • Automatic browser error capture via the Browser SDK
  • All logs visible in your LogFlow dashboard with search and filtering

Prerequisites: A Next.js app (v14, v15, or v16), Node.js 18+, and a free LogFlow account.

Step 1: Install the SDK

npm install @getlogflow/js @getlogflow/browser

Step 2: Create a Shared Logger

Create lib/logger.ts — a singleton that's imported everywhere in your server code:

import { createLogger } from '@getlogflow/js'

const logger = createLogger({
  apiKey: process.env.LOGFLOW_API_KEY!,
  service: 'web',
  environment: process.env.NODE_ENV,
})

export default logger

Add LOGFLOW_API_KEY to your .env.local:

LOGFLOW_API_KEY=lf_your_api_key_here

Get your API key from your LogFlow project settings.

Note: Set service to something meaningful — like 'web', 'api', or 'frontend'. This field is how you filter logs by service in the Logs Explorer. Each microservice or logical component should have its own service name.

Step 3: Log in API Routes

In the App Router, API routes are in app/api/. Import your logger and add structured logging:

// app/api/orders/route.ts
import { NextRequest, NextResponse } from 'next/server'
import logger from '@/lib/logger'

export async function POST(request: NextRequest) {
  const start = Date.now()

  try {
    const body = await request.json()
    
    logger.info('order.create.start', {
      userId: body.userId,
      items: body.items.length,
    })

    // ... your order logic here ...

    logger.info('order.create.success', {
      orderId: newOrder.id,
      userId: body.userId,
      duration: Date.now() - start,
    })

    return NextResponse.json({ orderId: newOrder.id })

  } catch (error) {
    logger.error('order.create.failed', {
      error: error instanceof Error ? error.message : String(error),
      duration: Date.now() - start,
    })
    return NextResponse.json({ error: 'Order creation failed' }, { status: 500 })
  }
}

Step 4: Capture Server-Side Errors Globally

Next.js doesn't have a global error handler for API routes, but you can wrap individual routes or use a middleware helper:

// lib/withLogging.ts
import logger from './logger'
import { NextRequest, NextResponse } from 'next/server'

type Handler = (req: NextRequest) => Promise<NextResponse>

export function withLogging(handler: Handler, routeName: string) {
  return async (req: NextRequest) => {
    const start = Date.now()
    try {
      const res = await handler(req)
      logger.info(`${routeName}.complete`, {
        status: res.status,
        method: req.method,
        duration: Date.now() - start,
      })
      return res
    } catch (error) {
      logger.error(`${routeName}.error`, {
        error: error instanceof Error ? error.message : String(error),
        method: req.method,
        duration: Date.now() - start,
      })
      return NextResponse.json({ error: 'Internal server error' }, { status: 500 })
    }
  }
}

Usage:

// app/api/payments/route.ts
import { withLogging } from '@/lib/withLogging'

export const POST = withLogging(async (req) => {
  // ... your handler
}, 'payments.charge')

Step 5: Log in Server Components

Server Components run on the server, so you can use the same logger import directly:

// app/dashboard/page.tsx
import logger from '@/lib/logger'
import { auth } from '@clerk/nextjs/server'

export default async function DashboardPage() {
  const { userId } = await auth()

  logger.info('dashboard.view', { userId })

  const data = await fetchDashboardData(userId)
  
  return <Dashboard data={data} />
}

Step 6: Capture Frontend Errors with the Browser SDK

The @getlogflow/browser SDK automatically captures:

  • window.onerror — uncaught JavaScript errors
  • unhandledrejection — unhandled Promise rejections
  • Manual logger.error() calls from your components

Create components/LogFlowProvider.tsx:

'use client'

import { useEffect } from 'react'
import { initBrowser } from '@getlogflow/browser'

export function LogFlowProvider({ children }: { children: React.ReactNode }) {
  useEffect(() => {
    initBrowser({
      apiKey: process.env.NEXT_PUBLIC_LOGFLOW_API_KEY!,
      service: 'web-browser',
      environment: process.env.NODE_ENV,
    })
  }, [])

  return <>{children}</>
}

Add NEXT_PUBLIC_LOGFLOW_API_KEY to .env.local (same value as LOGFLOW_API_KEY).

Wrap your app in the root layout:

// app/layout.tsx
import { LogFlowProvider } from '@/components/LogFlowProvider'

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html>
      <body>
        <LogFlowProvider>
          {children}
        </LogFlowProvider>
      </body>
    </html>
  )
}

Step 7: View Logs in Your Dashboard

Navigate to your LogFlow dashboard and you'll see logs arriving in real time.

Useful searches in the Logs Explorer:

  • service:web — all server-side logs
  • service:web-browser — all browser errors
  • level:error — only errors
  • service:web level:error — server errors only

Set up an alert (Alerts page → Create alert) to get notified on Slack or email when your error rate exceeds a threshold.

Troubleshooting

Logs not appearing?

  • Check that LOGFLOW_API_KEY is set in .env.local
  • Verify the API key starts with lf_
  • In development, logs may be batched — they appear within a few seconds

Edge Runtime errors? The @getlogflow/js SDK uses Node.js built-ins and doesn't work in Edge Runtime. For Edge middleware, use the HTTP API directly with fetch.

Build errors about fs module? The content.ts file uses fs — ensure it's only imported in Server Components or getStaticProps, never in Client Components.

Next Steps

Start monitoring your logs today

Free plan available. No credit card required. Up and running in 2 minutes.

Get started free