Skip to main content

React & Next.js Example

Logluxe works great in frontend applications with browser-optimized styling.

Browser Setup

import { log } from 'logluxe';

// Logs automatically use CSS styling in browsers
log.success('Hello from the browser!');
log.error('Something went wrong');
log.info('App initialized');
Browser Console
✔ Hello from the browser!
✖ Something went wrong
ℹ App initialized
🎮 Try Browser Logging

React Application

Basic Usage

import { log } from 'logluxe';
import { useEffect, useState } from 'react';

function App() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);

useEffect(() => {
log.group('App Initialize');
log.info('Fetching initial data...');

fetchUsers()
.then(data => {
log.success(`Loaded ${data.length} users`);
setUsers(data);
})
.catch(error => {
log.error('Failed to load users', error);
})
.finally(() => {
setLoading(false);
log.end();
});
}, []);

return (
<div>
{loading ? 'Loading...' : `${users.length} users`}
</div>
);
}
React App Console
┌ App Initialize
│ ℹ Fetching initial data...
│ ✔ Loaded 42 users
🎮 Try React Logging

Custom React Logger Hook

import { createLogger, env } from 'logluxe';
import { useCallback, useMemo } from 'react';

// Create browser-optimized logger
function createBrowserLogger(component: string) {
return createLogger({
prefix: { text: component, color: 'cyan', bold: true },
level: env.isDev ? 'debug' : 'warn',
// Only log in development
enabled: env.isDev || localStorage.getItem('debug') === 'true'
});
}

// Hook for component logging
function useLogger(componentName: string) {
const log = useMemo(
() => createBrowserLogger(componentName),
[componentName]
);

const logMount = useCallback(() => {
log.debug('Mounted');
}, [log]);

const logUnmount = useCallback(() => {
log.debug('Unmounting');
}, [log]);

const logAction = useCallback((action: string, data?: unknown) => {
log.info(action, data);
}, [log]);

return { log, logMount, logUnmount, logAction };
}

// Usage in component
function UserProfile({ userId }: { userId: string }) {
const { log, logMount, logAction } = useLogger('UserProfile');

useEffect(() => {
logMount();
return () => log.debug('Unmounting');
}, []);

const handleUpdate = async (data: UserData) => {
logAction('Updating user', { userId, data });

try {
await updateUser(userId, data);
log.success('User updated');
} catch (error) {
log.error(error.message);
}
};

return <div>...</div>;
}
useLogger Hook Output
[UserProfile]
Mounted
[UserProfile]
Updating user { userId: 'abc123' }
[UserProfile]
User updated
[UserProfile]
Unmounting

Debug Panel Component

Create a visual debug panel:

import { log } from 'logluxe';
import { useEffect, useState } from 'react';

interface LogEntry {
level: string;
message: string;
timestamp: Date;
}

function DebugPanel() {
const [logs, setLogs] = useState<LogEntry[]>([]);
const [isOpen, setIsOpen] = useState(false);

useEffect(() => {
// Intercept console logs
const originalLog = console.log;
const originalError = console.error;
const originalWarn = console.warn;

const addLog = (level: string, ...args: unknown[]) => {
setLogs(prev => [...prev.slice(-99), {
level,
message: args.map(String).join(' '),
timestamp: new Date()
}]);
};

console.log = (...args) => {
addLog('info', ...args);
originalLog(...args);
};

console.error = (...args) => {
addLog('error', ...args);
originalError(...args);
};

return () => {
console.log = originalLog;
console.error = originalError;
};
}, []);

// ... render panel
}
Debug Panel Logs
10:30:45 [INFO] App initialized
10:30:46 [INFO] Fetching users...
10:30:47 [INFO] Loaded 42 users
10:30:52 [WARN] Slow render detected: 250ms
10:30:55 [ERROR] Network request failed

Next.js Application

Server-Side Logging

// lib/logger.ts
import { createLogger, env } from 'logluxe';

export const serverLog = createLogger({
prefix: 'NEXT',
timestamp: true,
level: env.isDev ? 'debug' : 'info',
// JSON format for production (Vercel logs)
format: env.isProd ? 'json' : 'pretty'
});

export const apiLog = serverLog.child({ prefix: 'API' });
export const dbLog = serverLog.child({ prefix: 'DB' });
Next.js Server Logs
12:34:56 [NEXT]
Server starting...
12:34:57 [NEXT]
12:34:58 [API]
GET /api/users
12:34:58 [DB]
Query executed in 45ms

API Routes

// pages/api/users/[id].ts
import { NextApiRequest, NextApiResponse } from 'next';
import { apiLog, dbLog } from '@/lib/logger';

export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const { id } = req.query;

apiLog.info(`${req.method} /api/users/${id}`);
apiLog.perf(`users-${id}`);

try {
switch (req.method) {
case 'GET':
dbLog.debug(`Fetching user ${id}`);
const user = await getUser(id as string);

if (!user) {
apiLog.warn(`User not found: ${id}`);
return res.status(404).json({ error: 'Not found' });
}

apiLog.perfEnd(`users-${id}`);
return res.json(user);

case 'PUT':
apiLog.info(`Updating user ${id}`);
const updated = await updateUser(id as string, req.body);

apiLog.success(`User ${id} updated`);
apiLog.perfEnd(`users-${id}`);
return res.json(updated);

default:
apiLog.warn(`Method not allowed: ${req.method}`);
return res.status(405).json({ error: 'Method not allowed' });
}
} catch (error) {
apiLog.perfEnd(`users-${id}`);
apiLog.error(`Error: ${error.message}`);

return res.status(500).json({ error: 'Internal error' });
}
}
API Route Logs
12:35:00 [API]
GET /api/users/abc123
⏱ Started: users-abc123
12:35:00 [DB]
Fetching user abc123
⏱ users-abc123: 52ms
12:35:05 [API]
PUT /api/users/abc123
12:35:05 [API]
Updating user abc123
12:35:05 [API]
User abc123 updated
🎮 Try API Logging

Server Components (Next.js 13+)

// app/users/page.tsx
import { serverLog } from '@/lib/logger';

export default async function UsersPage() {
serverLog.info('Rendering UsersPage');
serverLog.perf('users-page');

const users = await fetchUsers();

serverLog.perfEnd('users-page');
serverLog.success(`Rendered ${users.length} users`);

return (
<div>
<h1>Users</h1>
{users.map(user => (
<UserCard key={user.id} user={user} />
))}
</div>
);
}
Server Component Logs
12:36:00 [NEXT]
Rendering UsersPage
⏱ Started: users-page
⏱ users-page: 127ms
12:36:00 [NEXT]
Rendered 42 users

Client Components

'use client';

import { log } from 'logluxe';
import { useEffect, useState, useTransition } from 'react';

export function UserSearch() {
const [query, setQuery] = useState('');
const [results, setResults] = useState([]);
const [isPending, startTransition] = useTransition();

useEffect(() => {
if (!query) return;

log.group('Search');
log.info(`Searching: "${query}"`);
log.perf('search');

startTransition(async () => {
try {
const data = await searchUsers(query);
log.perfEnd('search');
log.success(`Found ${data.length} results`);
setResults(data);
} catch (error) {
log.perfEnd('search');
log.error('Search failed', error);
} finally {
log.end();
}
});
}, [query]);

return (
<div>
<input
type="text"
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Search users..."
/>
{isPending && <span>Searching...</span>}
<ul>
{results.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
</div>
);
}
Client Component Search
┌ Search
│ ℹ Searching: "john"
│ ⏱ Started: search
│ ⏱ search: 89ms
│ ✔ Found 5 results
🎮 Try Search Logging

Redux/State Management Logging

import { log } from 'logluxe';
import { configureStore, Middleware } from '@reduxjs/toolkit';

// Logger middleware
const loggerMiddleware: Middleware = (store) => (next) => (action) => {
log.group(`Action: ${action.type}`);
log.debug('Payload:', action.payload);
log.debug('Previous state:', store.getState());

const result = next(action);

log.debug('Next state:', store.getState());
log.end();

return result;
};

// Configure store with logger
export const store = configureStore({
reducer: rootReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(
process.env.NODE_ENV === 'development' ? loggerMiddleware : []
)
});
Redux Logs
┌ Action: users/fetch/pending
│ ● Payload: undefined
│ ● Previous state: { users: [], loading: false }
│ ● Next state: { users: [], loading: true }
┌ Action: users/fetch/fulfilled
│ ● Payload: [{ id: 1, name: 'John' }...]
│ ● Previous state: { users: [], loading: true }
│ ● Next state: { users: [...], loading: false }

React Query Logging

import { log } from 'logluxe';
import { QueryClient } from '@tanstack/react-query';

export const queryClient = new QueryClient({
defaultOptions: {
queries: {
onError: (error) => {
log.error('Query error:', error);
}
},
mutations: {
onError: (error) => {
log.error('Mutation error:', error);
},
onSuccess: (data, variables) => {
log.success('Mutation success');
log.debug('Data:', data);
}
}
},
logger: {
log: (...args) => log.info(...args),
warn: (...args) => log.warn(...args),
error: (...args) => log.error(...args)
}
});
React Query Logs
ℹ Query: users - fetching
✔ Query: users - success (42 items)
ℹ Mutation: updateUser - pending
✔ Mutation success
● Data: { id: 'abc123', name: 'John Updated' }
✖ Query error: Network request failed

Development Tools

Performance Monitoring

import { log } from 'logluxe';
import { useEffect, useRef } from 'react';

function useRenderCount(componentName: string) {
const renderCount = useRef(0);

useEffect(() => {
renderCount.current++;
log.dev(`${componentName} rendered ${renderCount.current} times`);
});
}

function usePerformance(name: string) {
useEffect(() => {
log.perf(name);
return () => {
log.perfEnd(name);
};
}, [name]);
}

// Usage
function ExpensiveComponent() {
useRenderCount('ExpensiveComponent');
usePerformance('expensive-component-render');

return <div>...</div>;
}
Performance Monitoring
● ExpensiveComponent rendered 1 times
⏱ Started: expensive-component-render
⏱ expensive-component-render: 12ms
● ExpensiveComponent rendered 2 times
⏱ Started: expensive-component-render
⏱ expensive-component-render: 3ms
⚠ ExpensiveComponent rendered 15 times
🎮 Try Performance Logging

Next: Debugging Tips