Frontend Developer
Updated for 2026: Frontend Developer interview questions and answers covering core skills, tools, and best practices for roles in the US, Europe & Canada.
Why is semantic HTML important and what are common semantic elements?
Semantic HTML uses elements that describe meaning, not just appearance. **Why it matters:** - Better accessibility (screen readers understand structure) - Better SEO (clear page hierarchy) - More maintainable markup **Common semantic elements:** `header`, `nav`, `main`, `section`, `article`, `aside`, `footer`, `figure`, `time`, and proper heading order (`h1`–`h6`). **Interview tip:** mention that semantics + accessibility often improve SEO indirectly because search engines can better interpret content structure.
What is web accessibility and when should you use ARIA?
Web accessibility (a11y) ensures people with disabilities can use your site. **Start with native HTML first:** buttons, links, form labels, headings, and landmark elements. **Use ARIA when native semantics are not enough**, for example: - Custom components (tabs, combobox, modal) - Dynamic state announcements (`aria-live`) **Rules of thumb:** - Don’t add ARIA to elements that already have correct semantics. - Ensure keyboard support (Tab, Enter/Space, Esc). **Interview tip:** mention testing with keyboard-only navigation and a screen reader.
How does CSS specificity work and how do you avoid specificity problems?
Specificity decides which CSS rule wins when multiple rules match. **General order:** inline styles > IDs > classes/attributes/pseudo-classes > elements/pseudo-elements. **Avoid problems by:** - Keeping selectors simple (prefer classes) - Using a consistent methodology (BEM, utility CSS) - Avoiding `!important` (use it only for utilities/overrides with a clear policy) - Scoping components properly **Interview tip:** explain how order in the stylesheet matters when specificity ties.
When should you use CSS Flexbox vs CSS Grid?
Flexbox is best for **one-dimensional** layouts (row OR column). Grid is best for **two-dimensional** layouts (rows AND columns). **Use Flexbox for:** nav bars, aligning items, small components. **Use Grid for:** page layouts, complex responsive grids, aligning across rows and columns. **Interview tip:** mention that they work well together: Grid for macro layout, Flexbox for component-level alignment.
How do you approach responsive design and choose breakpoints?
Responsive design adapts UI to different viewport sizes and input methods. **Approach:** - Start mobile-first with fluid layouts. - Use content-driven breakpoints (when layout breaks), not device-specific ones. - Prefer flexible units (`%`, `rem`, `vw`) and modern layout tools (Grid/Flex). - Test touch targets, typography, and images. **Interview tip:** mention accessibility (zoom) and performance (serve appropriately sized images).
What is a CSS stacking context and why do z-index bugs happen?
A stacking context is a rendering layer that controls how elements stack. **z-index bugs happen because:** - `z-index` only works on positioned elements (or flex/grid items in some cases). - New stacking contexts are created by properties like `position` + `z-index`, `transform`, `opacity < 1`, `filter`, etc. **Debug tip:** inspect stacking contexts in devtools and minimize unnecessary `z-index` by using layout structure and component layering rules.
Explain the browser rendering process (critical rendering path).
The critical rendering path is how the browser turns HTML/CSS/JS into pixels: 1) Parse HTML → DOM 2) Parse CSS → CSSOM 3) Combine DOM + CSSOM → Render Tree 4) Layout (calculate sizes/positions) 5) Paint and Composite **Performance tips:** minimize render-blocking CSS/JS, reduce layout thrashing, and avoid heavy work on the main thread.
What are Core Web Vitals and how do you improve them?
Core Web Vitals measure real-user page experience: - **LCP:** loading performance - **INP:** responsiveness - **CLS:** visual stability **Improvements:** - LCP: optimize images, server response, critical CSS - INP: reduce long tasks, optimize JS, use web workers - CLS: reserve space for images/ads, avoid late-loading layout shifts They matter for UX and can influence SEO via page experience signals.
How do you reduce JavaScript bundle size in a web app?
Bundle size affects load time and Core Web Vitals. **Common tactics:** - Code splitting (route/component level) - Tree-shaking and ESM imports - Remove unused dependencies - Use smaller alternatives (date libs, UI libs) - Lazy-load heavy features - Analyze bundles (webpack/vite analyzer) **Interview tip:** explain that less JS also reduces CPU time (INP).
What is code splitting and how does lazy loading work?
Code splitting breaks your JS into smaller chunks so users only download what they need. **Lazy loading** loads code or assets on demand (routes, components, images). **Benefits:** faster initial load, better LCP, lower memory usage. **Trade-offs:** extra network requests and potential loading spinners—use prefetch/preload for predicted navigation.
How do you optimize images for web performance?
Images often dominate page weight. **Best practices:** - Serve modern formats (WebP/AVIF) with fallbacks - Use responsive images (`srcset`, `sizes`) - Compress and strip metadata - Lazy-load below-the-fold images - Set explicit `width`/`height` to avoid CLS - Use a CDN for resizing and caching This improves LCP and overall UX.
How do you prevent layout shifts (CLS) on a page?
CLS happens when elements move unexpectedly. **Fixes:** - Always set image/video dimensions - Reserve space for ads/embeds - Avoid injecting content above existing content - Use `font-display: swap` carefully and consider font metrics overrides - Animate with transforms, not layout properties **Interview tip:** mention measuring CLS with Lighthouse and real-user monitoring.
Debounce vs throttle: what’s the difference and when do you use each?
**Debounce** waits until events stop firing (e.g., search input). **Throttle** limits execution to once per interval (e.g., scroll/resize handlers). Both help performance by reducing expensive work and preventing long main-thread tasks.
What is event delegation in JavaScript and why is it useful?
Event delegation attaches one handler to a parent element and relies on event bubbling to handle child interactions. **Benefits:** - Fewer event listeners (better performance) - Works for dynamically added elements Use `event.target` (and `closest`) to identify which child triggered the event.
What is CORS and why do frontend apps hit CORS errors?
CORS (Cross-Origin Resource Sharing) is a browser security policy that restricts cross-origin requests. You see CORS errors when the backend doesn’t return the right headers (like `Access-Control-Allow-Origin`). **Key ideas:** - “Simple” requests vs preflight (OPTIONS) - Credentials (`withCredentials`) require stricter rules Fixes are typically server-side (configure allowed origins/headers/methods).
How do you prevent XSS (cross-site scripting) in frontend applications?
XSS happens when untrusted input is executed as code in the browser. **Prevention:** - Escape/encode output (use framework templating safely) - Avoid dangerous APIs (`innerHTML`) or sanitize HTML - Use Content Security Policy (CSP) - Validate and sanitize on the server too **Interview tip:** mention stored vs reflected XSS and the importance of treating user input as untrusted.
What is CSRF and how do SameSite cookies help?
CSRF tricks a user’s browser into sending authenticated requests to a site. **Mitigations:** - CSRF tokens (synchronizer pattern) - SameSite cookies (`Lax` or `Strict`) - Double-submit cookies (in some architectures) If you use cookies for auth, CSRF protection is essential (especially for state-changing requests).
What is Content Security Policy (CSP) and what does it protect against?
CSP is a security header that restricts what resources a page can load and execute. **It helps prevent:** - XSS (by blocking inline scripts and untrusted sources) - Data exfiltration via untrusted endpoints **Common directives:** `default-src`, `script-src`, `style-src`, `img-src`, `connect-src`. Start with report-only mode, then tighten policies gradually.
How do you choose between local state and a global store (Pinia/Vuex)?
Use **local component state** when data is only needed in one area. Use a **global store** when state is shared across distant components, needs caching, or must persist across routes. **Best practice:** keep stores focused (domain-based), avoid storing derived state when it can be computed, and keep side effects in actions/services.
What is the Vue Composition API and why use it?
The Composition API groups logic by feature instead of by option (data/methods/computed). **Benefits:** - Better code organization for complex components - Reusable composables - Improved TypeScript support **Interview tip:** mention `ref` vs `reactive`, and explain how composables help share logic across components cleanly.
Nuxt SSR vs SPA: what are the trade-offs for performance and SEO?
**SSR** renders HTML on the server, improving first paint and SEO for content-heavy pages. **SPA** renders mostly on the client, which can be simpler but may need extra work for SEO and initial load. **Trade-offs:** - SSR: more server complexity, hydration cost - SPA: potentially slower initial content, but simpler infrastructure In practice, use SSR/SSG for SEO pages and SPA behavior for app-like interactions.
What is hydration in SSR frameworks and what problems can it cause?
Hydration is when client-side JavaScript attaches event handlers and makes SSR HTML interactive. **Problems:** - Hydration mismatches (server HTML differs from client render) - Performance cost on low-end devices **Fixes:** ensure deterministic rendering (avoid random/time-based output), use client-only components when needed, and keep initial HTML stable.
What are best practices for form validation and accessible forms?
Great forms are usable and accessible. **Best practices:** - Use `<label>` correctly and associate with inputs - Validate on blur/submit, not every keystroke (unless needed) - Show clear inline error messages and summary - Use `aria-invalid` and `aria-describedby` - Prevent loss of user input Always validate on the server too—client validation is for UX, not security.
Why use TypeScript in frontend development and what are common pitfalls?
TypeScript improves reliability with static types. **Benefits:** - Catch errors earlier - Better refactoring - Better IDE autocomplete **Pitfalls:** - Overusing `any` - Too-complex generic types - Types drifting from runtime validation Pair TS with runtime validation (Zod/Valibot/etc.) for untrusted API data.
How do you build and maintain a scalable design system?
A design system is reusable UI components + guidelines. **Key parts:** - Tokens (colors, spacing, typography) - Component library (buttons, inputs, modals) - Accessibility standards - Documentation and examples **Maintenance:** version components, avoid breaking changes, ensure visual regression tests, and align with designers via a shared source of truth (Figma + code).
How do you unit test frontend components effectively?
Good component tests focus on behavior. **Principles:** - Test user-visible outcomes (text, ARIA roles, interactions) - Avoid testing internal implementation details - Mock network calls and isolate external dependencies - Keep tests fast and deterministic Use a test runner (Vitest/Jest) and a DOM testing library to simulate real user interactions.
Cypress vs Playwright: how do you choose an E2E testing tool?
Both tools run end-to-end tests in real browsers. **Consider:** - Browser coverage and parallelization - Flake resistance and auto-wait behavior - Debugging experience and CI integration - Team familiarity A practical setup: keep E2E tests for critical user journeys, and rely on unit/integration tests for most logic to keep the suite stable and fast.
Cookies vs localStorage vs sessionStorage: what’s the difference and what should you store?
All store data in the browser, but with different scopes and security. - **Cookies:** sent with requests (good for session cookies) but need CSRF controls. - **localStorage:** persistent; accessible by JS (don’t store secrets). - **sessionStorage:** per-tab session; cleared on tab close. **Security rule:** avoid storing sensitive tokens in localStorage because XSS can steal them. Prefer httpOnly cookies for session tokens when appropriate.
What are i18n best practices for frontend localization?
Internationalization (i18n) prepares your UI for multiple languages. **Best practices:** - Don’t concatenate strings; use message templates - Support pluralization rules - Format dates/numbers/currency via Intl APIs - Handle RTL layouts - Keep translation keys stable Test with long strings and different locales to catch layout issues early.
How do you handle API errors and loading states in the UI?
A good UX clearly communicates state. **Pattern:** - Loading: skeletons/spinners with timeouts - Success: show updated data and confirmation - Error: human-friendly message + retry action Also handle: - Empty states - Partial failures - Offline mode (optional) **Interview tip:** mention consistent error shapes, logging, and not exposing sensitive backend details to users.