Explore snippets
Discover reusable code snippets, examples, fixes, and ideas shared by developers, students, and teams.
Web Worker for CPU-Heavy Calculations
Move expensive calculations off the main thread and return the result with postMessage.
// statistics.worker.js
self.addEventListener('message', (event) => {
const numbers = event.data;
const total = numbers.reduce(
(sum, value) => sum + value,
0,
);
self.postMessage({
total,
average: numbers.length
Infinite Scroll with IntersectionObserver
Load the next page when a sentinel approaches the viewport and prevent duplicate requests.
const sentinel = document.querySelector('[data-load-more]');
let page = 1;
let isLoading = false;
let hasMore = true;
const observer = new IntersectionObserver(
async (entries) => {
const entry = entries[0];
TypeScript Discriminated Union Reducer
Model reducer actions safely with exhaustive TypeScript checking.
type State = {
count: number;
label: string;
};
type Action =
| {
type: 'increment';
amount: number;
}
| {
type: 'rename';
label: string;
}
| {
type: 'reset';
};
export function reducer(
state: State,
Typed JSON Fetch Helper
Wrap fetch with JSON parsing, typed responses, and useful HTTP error messages.
type ApiErrorBody = {
message?: string;
};
export async function fetchJson<T>(
input: RequestInfo | URL,
init?: RequestInit,
): Promise<T> {
const response = await fetch(input, {
...init,
headers: {
Accept: 'application/json',
Async Generator for Paginated API Data
Iterate through paginated API responses without loading every page into memory.
type Page<T> = {
items: T[];
nextCursor: string | null;
};
export async function* paginate<T>(
buildUrl: (cursor: string | null) => string,
): AsyncGenerator<T, void, void> {
let cursor: string | null = null;
do {
Process Mixed Results with Promise.allSettled
Run independent asynchronous tasks and keep both successful and failed outcomes.
async function loadDashboardResources() {
const requests = [
fetch('/api/profile').then((response) => response.json()),
fetch('/api/projects').then((response) => response.json()),
fetch('/api/notifications').then((response) => response.json()),
URLSearchParams Filter State
Read, update, and remove page filters without manually concatenating query strings.
function updateFilters(changes) {
const url = new URL(window.location.href);
Object.entries(changes).forEach(([key, value]) => {
const normalizedValue = String(value ?? '').trim();
if (normalizedValue === '') {
url.searchParams.delete(key);
Abortable Fetch with Timeout
Cancel a slow fetch request with AbortController while preserving the caller signal.
type FetchWithTimeoutOptions = RequestInit & {
timeoutMs?: number;
};
export async function fetchWithTimeout(
input: RequestInfo | URL,
options: FetchWithTimeoutOptions = {},
): Promise<Response> {
const {
timeoutMs = 8000,
Parallel Data Fetching in a Server Component
Start independent server requests together to reduce total rendering time.
// app/dashboard/page.tsx
async function getUser() {
return db.user.findFirst();
}
async function getRecentOrders() {
return db.order.findMany({
orderBy: {
createdAt: 'desc',
},
take: 5,
});
}
Next.js Route Error Boundary
Handle uncaught route segment errors and let the user retry without a full reload.
// app/dashboard/error.tsx
'use client';
import { useEffect } from 'react';
type ErrorPageProps = {
error: Error & {
digest?: string;
};
reset: () => void;
};
export default function DashboardError({
error,
reset,
}: ErrorPageProps) {
Next.js Loading Skeleton
Provide instant loading UI for an App Router segment with loading.tsx.
// app/dashboard/loading.tsx
export default function DashboardLoading() {
return (
<main aria-busy="true" aria-label="Loading dashboard">
<div className="skeleton skeleton-title" />
<div className="skeleton-grid">
Dynamic Metadata with generateMetadata
Generate page-specific SEO metadata from a dynamic App Router route.
// app/blog/[slug]/page.tsx
import type { Metadata } from 'next';
type PageProps = {
params: Promise<{
slug: string;
}>;
};
async function getPost(slug: string) {
return db.post.findUnique({
where: { slug },
select: {
title: true,
Next.js Route Handler with JSON Validation
Validate a JSON request body and return typed responses from an App Router Route Handler.
// app/api/tasks/route.ts
import { NextResponse } from 'next/server';
type CreateTaskBody = {
title?: unknown;
};
export async function POST(request: Request) {
let body: CreateTaskBody;
try {
body = await request.json();
} catch {
Revalidate a Next.js Cache Tag after Mutation
Mark tagged data stale after a Server Action changes the underlying records.
// app/actions/posts.ts
'use server';
import { revalidateTag } from 'next/cache';
export async function publishPost(postId: string) {
const post = await db.post.update({
where: {
id: postId,
},
data: {
published: true,
},
});
Next.js Cached Data with use cache
Cache a server data function and attach a reusable invalidation tag.
// app/lib/posts.ts
import {
cacheLife,
cacheTag,
} from 'next/cache';
export async function getPublishedPosts() {
'use cache';
cacheLife('hours');
cacheTag('posts');
return db.post.findMany({
where: {
published: true,
},
Next.js Proxy Authentication Guard
Redirect unauthenticated requests from protected routes with the Next.js proxy convention.
// proxy.ts
import type { NextRequest } from 'next/server';
import { NextResponse } from 'next/server';
export function proxy(request: NextRequest) {
const sessionId = request.cookies.get('session')?.value;
if (!sessionId) {
Next.js Server Action Form with useActionState
Connect a Next.js Server Action to a client form with validation and pending state.
// app/actions.ts
'use server';
export type CreateUserState = {
message: string;
errors: {
email?: string;
};
};
export async function createUser(
previousState: CreateUserState,
formData: FormData,
): Promise<CreateUserState> {
React Error Boundary Component
Catch rendering errors in a subtree and provide a retryable fallback UI.
import {
Component,
type ErrorInfo,
type ReactNode,
} from 'react';
type Props = {
children: ReactNode;
fallback?: ReactNode;
};
type State = {
hasError: boolean;
};
export class ErrorBoundary extends Component<Props, State> {
state: State = {
Typed Context Reducer Pattern
Combine React context and useReducer with typed actions and a safe custom hook.
'use client';
import {
createContext,
type ReactNode,
useContext,
useReducer,
} from 'react';
type CartState = {
itemCount: number;
};
type CartAction =
| { type: 'add'; quantity: number }
| { type: 'clear' };
Online Status with useSyncExternalStore
Subscribe to the browser online state through React useSyncExternalStore.
'use client';
import { useSyncExternalStore } from 'react';
function subscribe(callback: () => void) {
window.addEventListener('online', callback);
window.addEventListener('offline', callback);
return () => {
Reusable useDebouncedValue Hook
Delay a rapidly changing value before triggering searches, validation, or API requests.
'use client';
import { useEffect, useState } from 'react';
export function useDebouncedValue<T>(
value: T,
delay = 300,
): T {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
Dynamic Page with notFound
Render the nearest not-found UI when a requested App Router record does not exist.
// app/products/[id]/page.tsx
import { notFound } from 'next/navigation';
type PageProps = {
params: Promise<{
id: string;
}>;
};
export default async function ProductPage({
params,
}: PageProps) {
const { id } = await params;
Lazy Component Loading with Suspense
Load a large component only when it is rendered and show a fallback during download.
'use client';
import { lazy, Suspense, useState } from 'react';
const AnalyticsChart = lazy(
() => import('./analytics-chart'),
);
export function AnalyticsPanel() {
const [isOpen, setIsOpen] = useState(false);
return (
<section>
<button
Accessible Form Fields with useId
Generate stable IDs for reusable form controls and accessible help text.
import { useId } from 'react';
type TextFieldProps = {
label: string;
name: string;
helpText?: string;
};
export function TextField({
label,
name,
helpText,
}: TextFieldProps) {
const inputId = useId();
const helpId = `${inputId}-help`;