
Our Blog
Explore our blog posts on web design, development, and digital marketing to stay up-to-date with the latest trends and strategies.
Found 101 blog posts
Dark Mode Without the Flash in Next.js 16: How We Ship a Blocking Theme Script, color-scheme, and a Hydration-Safe Toggle
Dark mode that flashes white on reload is a timing bug: the server cannot read localStorage. We explain the blocking theme script we use in Next.js 16, why we keep the theme out of cookies to preserve static rendering, and how we build a toggle that hydrates without mismatches.
Dynamic Open Graph Images in Next.js 16: How We Build opengraph-image.tsx, Check the Satori Version next/og Ships, and Keep Link Previews Correct
Our generated share cards hit three surprises: a WOFF2 font the renderer could not parse, a Satori README describing a newer engine than the one Next.js bundles, and a page that kept showing its layout's image. These are our field notes on opengraph-image.tsx in Next.js 16, metadata precedence, and checking og:image before a link goes out.
Self-Hosting Next.js 16 in Docker: Standalone Output, Shared Cache Handlers and Multi-Replica Gotchas
One Next.js container works out of the box; the second replica breaks Server Actions, revalidateTag() and health checks. This is the standalone Dockerfile we build for Next.js 16, plus the shared encryption key, deploymentId and Redis-backed cache handlers that make several replicas behave like one app.
Visual Regression Testing with Playwright toHaveScreenshot: How We Pin Baselines in Docker, Mask Dynamic Content, and Use Aria Snapshots
Our Playwright screenshot baselines generated on a Mac failed on Linux CI without a single code change. Here is how we run toHaveScreenshot() reliably: baselines generated in a pinned Docker image, frozen clocks and masks for dynamic content, near-zero diff tolerance, and aria snapshots for structural checks.
Claude Code Skills in Practice: How We Use SKILL.md, Invocation Control, and a Leaner CLAUDE.md
Our CLAUDE.md files had grown into runbooks that loaded into every session. Claude Code skills fixed that: a SKILL.md whose description is always available but whose body loads only on demand. Here is how we write descriptions that trigger, keep deploy skills manual, inject live data, and handle the compaction limits that make long skills fade.
Explicit Resource Management in TypeScript and Node.js 24: How We Use using, await using and DisposableStack
Connection leaks usually come from one error path that skipped a release() call. Node.js 24 runs using and await using natively, and TypeScript has compiled them since 5.2. Here is how our team makes database clients, transactions, temp directories and test fixtures disposable, when we use DisposableStack, and the two traps to avoid: SuppressedError and streams that outlive their scope.
Building a Remote MCP Server in Next.js with mcp-handler 2: Tools, OAuth and the Stateless 2026-07-28 Spec
We now ship remote MCP servers as a single Next.js Route Handler on mcp-handler 2 and the stateless 2026-07-28 MCP spec. This is how we mount them, design tools that models call correctly, secure them with OAuth and RFC 9728 metadata, and test them before a real client connects.
sitemap.ts and robots.ts in Next.js 16: How We Control Google and AI Search Crawlers
How we generate robots.txt and sitemap.xml with robots.ts and sitemap.ts in Next.js 16, which AI crawlers we allow for search versus training, the user-agent group rule that silently drops Disallow lines, and how we set lastModified so crawlers trust it.
Reading PostgreSQL EXPLAIN ANALYZE: How We Find the Missing Index Behind a Slow Node.js Endpoint
We stopped adding PostgreSQL indexes by guesswork. Our process: find the costliest query in pg_stat_statements, read its EXPLAIN (ANALYZE, BUFFERS) plan for rows that are read and thrown away, and add the one composite, partial or covering index the plan asks for, built with CREATE INDEX CONCURRENTLY.
Integration Tests Against Real PostgreSQL with Testcontainers: How We Run One Container per Run and a Database per Test File
Mocked repositories kept tests green while the SQL underneath was wrong. We moved our Node.js integration tests onto real PostgreSQL with Testcontainers: one container per Vitest run, migrations applied once to a template database, a cloned database per test file, the settings that keep it fast, and how it runs in GitHub Actions.
N+1 Queries in Node.js APIs: How We Detect Them, Batch with DataLoader, and Enforce a Query Budget — Field Notes
An N+1 query hides in local development and multiplies database round trips in production. Here is how our team detects N+1 queries with per-request counting and pg_stat_statements, when we pick a JOIN, a batched IN query, or DataLoader, and the CI test that keeps the query count flat as page size grows.
noUncheckedIndexedAccess and exactOptionalPropertyTypes: How We Turn On TypeScript's Strict-Plus Flags in Real Codebases
"strict": true still lets TypeScript assume items[0] always exists and that an optional property never holds an explicit undefined. We cover what noUncheckedIndexedAccess and exactOptionalPropertyTypes catch, the fix patterns that avoid non-null-assertion spam, and the per-file CI ratchet we use to adopt both flags without one giant pull request.
Stay Updated
Subscribe to our newsletter for the latest insights on web design, development, and digital marketing.