Jugendra
All articles
UI implementation13 min read

How I convert a Figma design into a responsive Next.js website

My practical process for turning visual direction into reusable components, responsive rules and a polished implementation—not just a desktop screenshot in code.

Design canvas flowing into responsive browser layouts across desktop, tablet and mobile

I read the design before I write components

A Figma file shows a result, but the code needs the rules behind that result. Before opening the editor, I inspect the page hierarchy, repeated patterns, spacing rhythm, type scale and image behavior. I look for decisions that are consistent and places where two screens contradict each other. Those contradictions are useful questions, not details to quietly guess around.

I also identify what the design does not show: long titles, missing images, keyboard focus, loading states, validation errors and widths between the supplied frames. A reliable frontend has to handle those conditions. Writing them down early prevents the desktop frame from becoming an accidental specification for every screen.

  • Identify the primary user action and content order
  • List repeated visual patterns before naming components
  • Check assets, font licenses and image focal points
  • Record missing states that need a design decision

Turn visual repetition into a small system

I translate recurring values into a compact set of tokens: colors, type roles, spacing steps, radii, borders and container widths. The goal is not to create a full design system for a four-page website. It is to prevent almost-identical values from spreading through the codebase and making later changes inconsistent.

Typography deserves special attention because matching font size alone rarely matches the composition. Line height, letter spacing, measure and font weight decide how a heading occupies space. I build the broad hierarchy first, then adjust details using real content. This produces a closer and more resilient result than tuning every element against one screenshot.

Choose component boundaries around responsibility

I create a component when a block repeats, owns meaningful behavior, or becomes easier to understand in isolation. I do not extract every wrapper into a named file. A section can stay local while a project card, navigation menu or form field becomes reusable because its content and states change independently.

Data that repeats—projects, experience entries or navigation links—lives in typed arrays and is mapped into components. TypeScript makes missing fields visible during development and gives each component a clear contract. The data shape remains specific to the product instead of becoming a generic configuration system that nobody enjoys editing.

Responsive behavior is designed, not patched

I start with the narrow layout because it forces the content priority to be clear. The DOM order follows the reading order, then grid and flexbox enhance the composition as space increases. Breakpoints are added where the content becomes uncomfortable, not simply because a popular device width exists.

Some layouts should stack; others need a different crop, alignment or control. I use fluid type and spacing where the change should be gradual, then discrete breakpoints for structural changes. I test the awkward widths between mobile, tablet and desktop because that is where fixed assumptions usually create overflow.

  • Keep tap targets comfortable and links permanently available
  • Use min-width: 0 where grid content can overflow
  • Define image aspect ratio and object position intentionally
  • Test 320px, intermediate widths and large text zoom

Use Next.js features where they solve a real need

The App Router gives the implementation a useful default structure: layouts for shared UI, server components for content, and client components only for interaction. I use next/image for responsive media, next/font for predictable typography, and route metadata for pages that should be shared or indexed.

I keep semantic HTML visible inside the component design. Navigation remains navigation, cards are articles when they stand alone, and buttons are not replaced by clickable divs. Focus states are designed alongside hover states. If animation is included, the content still works without it and reduced-motion preferences are respected.

Refine in passes, not random pixel adjustments

My first comparison checks structure: container width, section rhythm, type hierarchy and major image proportions. The second checks component spacing and alignment. Only then do I refine small details such as border tone or icon position. Fixing the largest mismatch first avoids repeatedly adjusting children inside the wrong parent layout.

The final review uses real content, keyboard navigation, narrow screens and a production build. I also check what happens when a title wraps one line earlier than the design. The goal is not a single perfect screenshot; it is a page that preserves the design's intent across content and devices.