Skip to content
Tip by Tab
← Home

Frontend

21 tips across 4 technologies · newest first

The stale closure, your debounced callback saves old state

REACT

Stabilizing a debounce with useMemo(() => debounce(fn, 300), []) fixes one bug and creates a worse one: the callback is…

react19debounce
@DevDhaif

Push 'use client' to leaf components and pass server data down as props

NEXT

Everything in the App Router is a Server Component until you add 'use client', and that directive taints the whole subt…

nextjs15server-components
@hnooz

Remember GET route handlers are uncached by default since Next.js 15

NEXT

Next.js 15 flipped the default: GET route handlers and the client router cache are no longer cached unless you opt in.…

nextjs15caching
@hnooz

Invalidate exactly what changed with revalidateTag/revalidatePath after writes

NEXT

After a mutation, invalidate the specific cache entries it affected rather than forcing a broad refresh or client reloa…

nextjs15caching
@hnooz

Use Server Actions for internal mutations instead of hand-rolled API routes

NEXT

Server Actions run mutation logic on the server and can be called directly from a <form action> or a client handler — n…

nextjs15server-actions
@hnooz

Stream slow sections with loading.tsx and Suspense instead of blocking the route

NEXT

A route-level loading.tsx wraps the page in a Suspense boundary so the shell streams immediately while data loads. Wrap…

nextjs15streaming
@hnooz

Cache expensive server routes at the edge with defineCachedEventHandler

NUXT

Nitro's defineCachedEventHandler wraps a server route with stale-while-revalidate caching backed by your configured sto…

nuxt4nitro
@hnooz

Set per-route rendering strategy with routeRules instead of restructuring code

NUXT

routeRules applies a rendering mode per URL pattern in config, so marketing pages prerender, content pages use ISR, and…

nuxt4rendering
@hnooz

Give useAsyncData an explicit key to control dedup and caching

NUXT

useAsyncData dedups and caches by key. Without an explicit key Nuxt derives one from the call site, which can collide w…

nuxt4data-fetching
@hnooz

Share state across components with useState, never a module-level ref, on SSR

NUXT

On the server a module-level ref is created once and shared by every request, so one user's cart can leak into another'…

nuxt4state
@hnooz

Use useFetch in setup and $fetch in handlers to avoid double-fetching

NUXT

useFetch is the SSR-aware wrapper: it runs during server render, serializes the result into the payload, and hydrates o…

nuxt4data-fetching
@hnooz

Let the React Compiler memoize instead of hand-writing useMemo/useCallback

REACT

The React Compiler analyzes your components and automatically memoizes values and callbacks at build time, following th…

react19react-compiler
@hnooz

Drop forwardRef in React 19 and accept ref as a normal prop

REACT

React 19 lets function components receive ref as a regular prop, so forwardRef is no longer required for the common cas…

react19refs
@hnooz

Handle form mutations with built-in pending and error state via useActionState

REACT

useActionState wraps an async action and returns the last result, the action to bind to a <form action>, and a pending…

react19forms
@hnooz

Read promises and context conditionally with the use() hook

REACT

React 19's use() unwraps a promise or reads context, and unlike the Rules of Hooks it can be called conditionally or in…

react19suspense
@hnooz

Show instant UI with useOptimistic and auto-revert on failure

REACT

useOptimistic renders an expected next state immediately while the real async action runs, then reconciles to the true…

react19optimistic-ui
@hnooz

Replace modelValue/update boilerplate with defineModel() for v-model

VUE

defineModel() returns a writable ref wired to the parent's v-model, collapsing the modelValue prop plus update:modelVal…

v-modelcomponents
@hnooz

Cancel stale async work in watchers with onWatcherCleanup()

VUE

Registered inside the watcher callback, onWatcherCleanup runs before the next invocation and on stop. It removes the ma…

watchersasync
@hnooz

Destructure props with native defaults in Vue 3.5, but pass a getter to watch

VUE

Stabilized in 3.5: destructured variables from defineProps compile to props.count on access, so they stay reactive and…

propsreactivity
@hnooz

Generate hydration-safe unique IDs with useId() for accessibility

VUE

useId() produces IDs that are stable and identical across server render and client hydration, so label/for and aria-des…

ssraccessibility
@hnooz

Use useTemplateRef() for typed template refs instead of string-matched refs

VUE

Vue 3.5 resolves template refs by key at runtime, so the type is inferred and you drop the ref(null) declaration that h…

composition-apirefs
@hnooz