16 Jun 2026, 12:00 AM 45 min read

React Interview Questions and Answers 2026

React Interview Questions and Answers 2026

1 Core Concepts

Q: What is React and why use it over vanilla JavaScript?

Answer: React is a JavaScript library for building user interfaces, developed by Meta. It uses a component-based architecture and a virtual DOM for efficient rendering.

Why React over vanilla JS:

  • Declarative UI makes code predictable
  • Component reusability reduces duplication
  • Virtual DOM optimizes real DOM updates
  • Rich ecosystem (routing, state management, testing)
  • Strong TypeScript support
  • Large community and Meta backing

Q: Explain the Virtual DOM and reconciliation.

Answer: The Virtual DOM is a lightweight JavaScript representation of the actual DOM. When state changes, React creates a new Virtual DOM tree, compares it with the previous snapshot (diffing algorithm), calculates minimal DOM operations needed, and batches these updates efficiently.

Reconciliation is this entire process. React 18+ uses a priority-based reconciler (Fiber architecture) enabling concurrent features.

Q: What's the difference between Real DOM and Virtual DOM?

Real DOM Virtual DOM
Direct HTML element manipulation JavaScript object representation
Slow updates Fast updates
Re-renders entire tree on change Only updates changed elements
High memory usage Lower memory footprint
No direct control over batching Efficient diffing and batching
1736

2 Components & JSX

Q: Explain Class vs Functional Components (2026 perspective)

Answer: Functional components are now the standard. Class components are legacy.

Functional components are defined as functions, while class components are defined as classes that extend the React.Component class.

Here is an example of a functional component:

function UserProfile({ name, role }) { const [isOnline, setIsOnline] = useState(false); useEffect(() => { subscribeToStatus(role); return () => unsubscribeFromStatus(role); }, [role]); return
{name} is {isOnline ? 'online' : 'offline'}
; }

And here is an example of a class component:

class UserProfile extends React.Component { state = { isOnline: false }; componentDidMount() { } componentDidUpdate(prevProps) { } componentWillUnmount() { } render() { return
{this.props.name}
; } } ✅ Key advantages of functional components:
  • Simpler syntax, less boilerplate
  • Hooks enable state and lifecycle features
  • Better performance (no this binding, smaller bundle)
  • Easier to test and tree-shake

Q: What are Pure Components and React.memo?

Answer: Both prevent unnecessary re-renders through shallow comparison.

Pure components are components that do not have any side effects and always return the same output given the same props.

React.memo is a higher-order component that memoizes a component so that it is not re-rendered unless its props change.

Here is an example of using React.memo:

const ExpensiveList = React.memo(({ items }) => { return items.map(item => ); }); const UserCard = React.memo( ({ user }) =>
{user.name}
, (prevProps, nextProps) => prevProps.user.id === nextProps.user.id );

3 Hooks Mastery

Q: Explain useState and its nuances

useState is a hook that allows you to add state to functional components.

Here is an example of using useState:

const [count, setCount] = useState(0);

You can update the state by calling the setCount function:

setCount(prev => prev + 1);

Or:

setCount(c => c + 1); setCount(c => c + 1); 💡 Important: State updates in React 18 are automatically batched, even in promises and timeouts.

Q: Deep dive into useEffect

useEffect is a hook that allows you to run side effects after rendering a component.

Here is an example of using useEffect:

useEffect(() => { const subscription = api.subscribe(id); return () => { subscription.unsubscribe(); }; }, [id]);

useEffect Variations:

  • No dependency array: runs after every render
  • Empty []: runs once (mount only)
  • With dependencies: runs when dependencies change
⚠️ React 18 Strict Mode: Intentionally double-invokes effects in development to catch cleanup issues.

Q: useCallback vs useMemo — when to use which?

useCallback and useMemo are both hooks that allow you to memoize values, but they serve different purposes.

useCallback is used to memoize functions, while useMemo is used to memoize values.

Here is an example of using useMemo:

const sortedList = useMemo(() => { return items.sort((a, b) => a.name.localeCompare(b.name)); }, [items]);

And here is an example of using useCallback:

const handleClick = useCallback((id) => { setSelected(prev => prev === id ? null : id); }, []); 💡 Rule of thumb: Only use when passing to memoized child components or as dependency to other hooks. Premature optimization hurts readability.

Q: Explain useRef and its use cases

useRef is a hook that allows you to create a reference to a DOM element or a value that persists between renders.

Here is an example of using useRef:

function Timer() { const intervalRef = useRef(null); const countRef = useRef(0); const startTimer = () => { intervalRef.current = setInterval(() => { countRef.current += 1; console.log(countRef.current); }, 1000); }; useEffect(() => { return () => clearInterval(intervalRef.current); }, []); return ; }

Use cases for useRef:

  • DOM element references
  • Storing mutable values without re-rendering
  • Keeping previous values
  • Holding timer/timeout IDs

Q: What are custom hooks? Give an example.

Custom hooks are functions that use other hooks to provide a specific functionality.

Here is an example of a custom hook:

function useDebounce(value, delay = 500) { const [debouncedValue, setDebouncedValue] = useState(value); useEffect(() => { const timer = setTimeout(() => setDebouncedValue(value), delay); return () => clearTimeout(timer); }, [value, delay]); return debouncedValue; }

And here is an example of using the custom hook:

function SearchComponent() { const [query, setQuery] = useState(''); const debouncedQuery = useDebounce(query, 300); useEffect(() => { if (debouncedQuery) fetchResults(debouncedQuery); }, [debouncedQuery]); } 7103

4 React 18 & 19 Features

Q: What's new in React 18?

Answer:

  1. Concurrent rendering — interruptible rendering for better UX
  2. Automatic batching — groups state updates from anywhere
  3. Transitions — mark updates as non-urgent
  4. Suspense on server — streaming SSR
  5. New hooks: useId, useTransition, useDeferredValue, useSyncExternalStore

Here is an example of using the useTransition hook:

const [isPending, startTransition] = useTransition(); function handleSearch(input) { setInputValue(input); startTransition(() => { setSearchResults(filterData(input)); }); }

And here is an example of using the useDeferredValue hook:

const deferredQuery = useDeferredValue(query); const results = useMemo(() => filterData(deferredQuery), [deferredQuery]);

Q: What's expected in React 19?

Answer: New in 2026

  • React Server Components (RSC) stable — zero client JS for server-only components
  • Actions
    for mutations
  • useOptimistic — instant UI updates
  • useFormStatus — form pending states
  • Document metadata, <meta> tags directly in components</li> <li><strong>Asset loading</strong> — preload, preinit APIs</li> <li><strong>Ref as a prop</strong> — no more forwardRef</li> </ul> <p>Here is an example of using React Server Components:</p> async function BlogPost({ slug }) { const post = await db.posts.findBySlug(slug); return <article><h1>{post.title}</h1></article>; } <p>And here is an example of using the useOptimistic hook:</p> function LikeButton({ postId, initialLikes }) { const [optimisticLikes, addOptimisticLike] = useOptimistic( initialLikes, (state, newLike) => state + 1 ); async function handleLike() { addOptimisticLike(1); await likePost(postId); } return <button onClick={handleLike}>{optimisticLikes} likes</button>; } <h3>Q: Explain React Server Components (RSC)</h3> <p><strong>Answer:</strong> RSC allows components to run exclusively on the server. <strong>Server Components</strong> can access databases/files directly with zero bundle size. <strong>Client Components</strong> ('use client') are traditional interactive components.</p> <h2>5 State Management</h2> <h3>Q: Compare state management solutions in 2026</h3> <table> <thead> <tr> <th>Solution</th> <th>Use Case</th> <th>When to Use</th> </tr> </thead> <tbody> <tr> <td>useState/useReducer</td> <td>Component-level state</td> <td>Simple local state</td> </tr> <tr> <td>Context API</td> <td>Low-frequency updates</td> <td>Theme, auth, localization</td> </tr> <tr> <td><strong>Zustand</strong></td> <td>Medium complexity</td> <td>Simple global state, no boilerplate</td> </tr> <tr> <td>Jotai/Recoil</td> <td>Atomic state</td> <td>Fine-grained reactivity</td> </tr> <tr> <td>Redux Toolkit</td> <td>Complex state logic</td> <td>Large apps with middleware needs</td> </tr> <tr> <td><strong>TanStack Query</strong></td> <td>Server state</td> <td>API caching, synchronization</td> </tr> <tr> <td>XState</td> <td>State machines</td> <td>Complex workflows, visualizations</td> </tr> </tbody> </table> <h4>Zustand Example (Popular in 2026):</h4> <p>The following example demonstrates how to create a simple store using Zustand:</p> <p>store.js</p> <p>const useStore = create((set) => ({</p> <p> count: 0,</p> <p> increment: () => set((state) => ({ count: state.count + 1 })),</p> <p> reset: () => set({ count: 0 }),</p> <p>}));</p> <h2>6 Performance Optimization</h2> <h3>Q: How do you optimize React app performance?</h3> <ol> <li><strong>Code splitting</strong> with React.lazy and dynamic imports</li> <li><strong>Memoization</strong> — React.memo, useMemo, useCallback (judiciously)</li> <li><strong>Virtualization</strong> — react-window or @tanstack/virtual for long lists</li> <li><strong>Image optimization</strong> — lazy loading, WebP, responsive sizes</li> <li><strong>Bundle analysis</strong> — monitor with bundle analyzer</li> <li><strong>Avoid anonymous functions</strong> as props when possible</li> <li><strong>Use useTransition</strong> for expensive updates</li> <li><strong>Proper key usage</strong> in lists</li> <li><strong>RSC</strong> for reducing client JS</li> <li><strong>Tree shaking</strong> — ensure imports are tree-shakeable</li> </ol> <p>For example, you can use code splitting to load components only when they are needed:</p> <p>CodeSplitting.jsx</p> <p>const <a href="/dashboard-ui-design" style="color:#EE483D;font-weight:600;text-decoration:underline;text-underline-offset:3px;">Dashboard</a> = lazy(() => import('./Dashboard'));</p> <p><Suspense fallback=<Spinner />></p> <p> <Dashboard /></p> <p></Suspense></p> <h3>Q: What causes infinite re-renders and how to fix them?</h3> <p><strong>Problem 1:</strong> Setting state in render creates an infinite loop.</p> <p><strong>Problem 2:</strong> Object/array dependency in useEffect creates new reference every render.</p> <p><strong>Problem 3:</strong> Inline function causing child re-render on every parent render.</p> <p><strong>Fixes:</strong> Move references outside or memoize them with useMemo and useCallback.</p> <h2>7 Testing</h2> <h3>Q: How do you test React components?</h3> <p>For example, you can use the following test to verify that a login form submits with the correct user data:</p> <p>LoginForm.test.jsx</p> <p>import { render, screen, waitFor } from '@testing-library/react';</p> <p>import userEvent from '@testing-library/user-event';</p> <p>test('submits form with user data', async () => {</p> <p> const user = userEvent.setup();</p> <p> const handleSubmit = vi.fn();</p> <p> render(<LoginForm onSubmit={handleSubmit} />);</p> <p> await user.type(screen.getByLabelText(/email/i), 'test@example.com');</p> <p> await user.type(screen.getByLabelText(/password/i), 'password123');</p> <p> await user.click(screen.getByRole('button', { name: /submit/i }));</p> <p> await waitFor(() => {</p> <p> expect(handleSubmit).toHaveBeenCalledWith({</p> <p> email: 'test@example.com',</p> <p> password: 'password123',</p> <p> });</p> <p> });</p> <p>});</p> <h2>8 Advanced Patterns</h2> <h3>Q: Explain compound components pattern</h3> <p>The compound components pattern allows you to create a set of components that share state and work together to achieve a common goal. This is used in libraries like @headlessui/react and @radix-ui/react-tabs.</p> <p>For example, you can create a tab component that uses the compound components pattern:</p> <p>Tabs.jsx</p> <p>function Tabs({ children, defaultTab }) {</p> <p> const [activeTab, setActiveTab] = useState(defaultTab);</p> <p> return (</p> <p> <TabsContext.Provider value={{ activeTab, setActiveTab }}></p> <p> <div className="tabs">{children}</div></p> <p> </TabsContext.Provider></p> <p> );</p> <p>}</p> <p>Tabs.Tab = function Tab({ id, children }) {</p> <p> const { activeTab, setActiveTab } = useContext(TabsContext);</p> <p> return (</p> <p> <button role="tab" aria-selected={activeTab === id}</p> <p> onClick={() => setActiveTab(id)}></p> <p> {children}</p> <p> </button></p> <p> );</p> <p>};</p> <p><Tabs defaultTab="tab1"></p> <p> <Tabs.Tab id="tab1">First</Tabs.Tab></p> <p> <Tabs.Tab id="tab2">Second</Tabs.Tab></p> <p></Tabs></p> <h3>Q: What are Higher-Order Components? Are they still relevant?</h3> <p>These patterns are largely replaced by hooks but still appear in legacy codebases. A <strong>HOC</strong> is a function taking a component and returning an enhanced component.</p> <p><strong>Modern approach:</strong> Instead of HOCs, simply use the hook directly in your component. This is cleaner and avoids "wrapper hell."</p> <h2>9 Error Handling</h2> <h3>Q: How do you handle errors in React?</h3> <p>For example, you can use an error boundary to catch and handle errors:</p> <p>ErrorBoundary.jsx</p> <p>class ErrorBoundary extends React.Component {</p> <p> state = { hasError: false, error: null };</p> <p> static getDerivedStateFromError(error) {</p> <p> return { hasError: true, error };</p> <p> }</p> <p> componentDidCatch(error, errorInfo) {</p> <p> logErrorToService(error, errorInfo);</p> <p> }</p> <p> render() {</p> <p> if (this.state.hasError) {</p> <p> return this.props.fallback || <h1>Something went wrong</h1>;</p> <p> }</p> <p> return this.props.children;</p> <p> }</p> <p>}</p> <p>For async errors, use <strong>TanStack Query's</strong> built-in error handling or <strong>React Error Boundaries</strong> with react-error-boundary library.</p> <h2>10 System Design / Architecture</h2> <h3>Q: How would you architect a large-scale React application?</h3> <h4>Recommended Folder Structure:</h4> <p>Project Structure</p> <p>src/</p> <p>├── app/</p> <p>│ ├── providers.tsx</p> <p>│ └── router.tsx</p> <p>├── features/</p> <p>│ ├── auth/</p> <p>│ ├── dashboard/</p> <p>│ └── settings/</p> <p>├── shared/</p> <p>│ ├── components/</p> <p>│ ├── hooks/</p> <p>│ └── utils/</p> <p>├── entities/</p> <p>├── styles/</p> <p>└── instrumentation/</p> <h4>Key Architectural Principles:</h4> <ol> <li><strong>Feature-based folder structure</strong> for scalability</li> <li><strong>Shared UI kit</strong> (design system) for consistency</li> <li><strong>TypeScript throughout</strong> for type safety</li> <li><strong>API layer abstracted</strong> (TanStack Query or similar)</li> <li><strong>Code splitting at route level</strong> for performance</li> <li><strong>Feature flags</strong> for gradual rollout</li> <li><strong>Comprehensive error boundaries</strong> at strategic levels</li> <li><strong>Monitoring and observability</strong> (OpenTelemetry, Sentry)</li> <li><strong>Testing strategy:</strong> unit (vitest), integration (RTL), e2e (Playwright)</li> </ol> <h2>Quick Tips for 2026 Interviews</h2> <ol> <li><strong>Know the React 19 changes well</strong> — RSC, Actions, useOptimistic are hot topics</li> <li><strong>Understand Server Components vs Client Components</strong> — this is the new paradigm</li> <li><strong>Be practical about optimization</strong> — don't memoize everything, profile first</li> <li><strong>TypeScript proficiency</strong> is expected</li> <li><strong>Accessibility</strong> (ARIA attributes, keyboard navigation) is increasingly important</li> <li><strong>Testing philosophy</strong> — know what to test (behavior, not implementation)</li> <li><strong>Frameworks</strong> — understand Next.js, Remix, or TanStack Start (full-stack React frameworks)</li> <li><strong>Edge runtimes</strong> — understand streaming, partial prerendering</li> </ol> <p>For expert-level guidance on React development, consider consulting the professionals at Chulbul Design.</p> <h2>Frequently Asked Questions</h2> <h3>Question?</h3> <p>What is the most efficient way to handle state management in a React application?</p> <h3>Question?</h3> <p>How can I optimize the performance of my React application?</p> <h3>Question?</h3> <p>What are some best practices for testing React components?</p> <h3>Question?</h3> <p>How can I ensure that my React application is accessible to all users?</p> </div> <!-- Tags / Share Row --> <div class="mt-10 pt-6 border-t border-gray-100 flex flex-wrap items-center justify-between gap-4"> <div class="flex flex-wrap items-center gap-1.5"> <a href="/blog?tag=technologies" class="inline-flex items-center gap-1 text-xs font-semibold px-2.5 py-1 rounded-full bg-[#f0f0ff] text-[#49499A] border border-[#49499A]/20 hover:bg-[#49499A] hover:text-white transition"> <i class="bi bi-hash" style="font-size:9px"></i>Technologies </a> <a href="/blog?tag=ui-ux-design" class="inline-flex items-center gap-1 text-xs font-semibold px-2.5 py-1 rounded-full bg-[#f0f0ff] text-[#49499A] border border-[#49499A]/20 hover:bg-[#49499A] hover:text-white transition"> <i class="bi bi-hash" style="font-size:9px"></i>UI/UX Design </a> <a href="/blog?tag=web-development" class="inline-flex items-center gap-1 text-xs font-semibold px-2.5 py-1 rounded-full bg-[#f0f0ff] text-[#49499A] border border-[#49499A]/20 hover:bg-[#49499A] hover:text-white transition"> <i class="bi bi-hash" style="font-size:9px"></i>Web Development </a> </div> <div class="flex items-center gap-3 text-gray-400 text-lg"> <span class="text-sm text-gray-500 mr-1">Share:</span> <a href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fwww.chulbuldesign.com%2Fblog%2Freact-interview-questions-2026" target="_blank" rel="noopener noreferrer" aria-label="Share on Facebook" class="hover:text-blue-600 transition"><i class="bi bi-facebook"></i></a> <a href="https://twitter.com/intent/tweet?url=https%3A%2F%2Fwww.chulbuldesign.com%2Fblog%2Freact-interview-questions-2026&text=React+Interview+Questions+and+Answers+2026" target="_blank" rel="noopener noreferrer" aria-label="Share on Twitter" class="hover:text-sky-500 transition"><i class="bi bi-twitter-x"></i></a> <a href="https://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Fwww.chulbuldesign.com%2Fblog%2Freact-interview-questions-2026&title=React+Interview+Questions+and+Answers+2026" target="_blank" rel="noopener noreferrer" aria-label="Share on LinkedIn" class="hover:text-blue-700 transition"><i class="bi bi-linkedin"></i></a> <a href="https://wa.me/?text=React+Interview+Questions+and+Answers+2026+https%3A%2F%2Fwww.chulbuldesign.com%2Fblog%2Freact-interview-questions-2026" target="_blank" rel="noopener noreferrer" aria-label="Share on WhatsApp" class="hover:text-green-500 transition"><i class="bi bi-whatsapp"></i></a> </div> </div> </article> <!-- Sidebar --> <aside class="w-full lg:w-80 xl:w-96 flex-shrink-0 blog-sidebar"> <!-- CTA Card --> <div class="blog-sidebar-cta rounded-2xl p-6"> <i class="blog-sidebar-cta-icon bi bi-rocket-takeoff-fill text-3xl block mb-3"></i> <h3 class="text-lg font-extrabold mb-2">Need Expert Help?</h3> <p class="text-sm mb-5 leading-relaxed"> From web design to SEO and digital marketing — Chulbul Design can help your business grow online. </p> <a href="/contact-us" class="blog-cta-btn-primary block text-center py-2.5 rounded-xl font-bold text-sm transition mb-3"> Get a Free Quote </a> <a href="https://wa.me/919990548795" target="_blank" rel="noopener noreferrer" class="blog-cta-btn-wa block text-center py-2.5 rounded-xl font-bold text-sm transition"> <i class="bi bi-whatsapp mr-1"></i> Chat on WhatsApp </a> </div> <!-- Related Posts --> <div> <h3 class="text-lg font-extrabold text-[#1e1e5c] mb-4 flex items-center gap-2"> <i class="bi bi-layout-text-window-reverse text-[#EE483D]"></i> Related Posts </h3> <div class="space-y-4"> <a href="/blog/how-to-create-call-to-action" class="block bg-gray-50 hover:bg-[#F4F4FF] border border-gray-100 hover:border-[#49499A]/20 rounded-xl p-4 transition"> <span class="text-xs font-bold px-2 py-0.5 rounded-full bg-[#f0f0ff] text-[#49499A]"> #Ai </span> <span class="text-xs font-bold px-2 py-0.5 rounded-full bg-[#f0f0ff] text-[#49499A]"> #Digital Marketing </span> <p class="text-sm font-semibold text-[#1e1e5c] mt-2 mb-1 leading-snug hover:text-[#EE483D] transition"> Improve CTA Clickthrough Rate: B2B Lead Gen Guide </p> <span class="text-xs text-gray-400"><i class="bi bi-calendar3 mr-1"></i>15 Jun 2026</span> </a> <a href="/blog/laravel-vs-codeigniter" class="block bg-gray-50 hover:bg-[#F4F4FF] border border-gray-100 hover:border-[#49499A]/20 rounded-xl p-4 transition"> <span class="text-xs font-bold px-2 py-0.5 rounded-full bg-[#f0f0ff] text-[#49499A]"> #Comparisons </span> <span class="text-xs font-bold px-2 py-0.5 rounded-full bg-[#f0f0ff] text-[#49499A]"> #Technologies </span> <p class="text-sm font-semibold text-[#1e1e5c] mt-2 mb-1 leading-snug hover:text-[#EE483D] transition"> Laravel Vs CodeIgniter: Which PHP Framework is Best? </p> <span class="text-xs text-gray-400"><i class="bi bi-calendar3 mr-1"></i>15 Jun 2026</span> </a> <a href="/blog/ui-ux-design-importance" class="block bg-gray-50 hover:bg-[#F4F4FF] border border-gray-100 hover:border-[#49499A]/20 rounded-xl p-4 transition"> <span class="text-xs font-bold px-2 py-0.5 rounded-full bg-[#f0f0ff] text-[#49499A]"> #Digital Marketing </span> <span class="text-xs font-bold px-2 py-0.5 rounded-full bg-[#f0f0ff] text-[#49499A]"> #UI/UX Design </span> <p class="text-sm font-semibold text-[#1e1e5c] mt-2 mb-1 leading-snug hover:text-[#EE483D] transition"> The Importance of UI UX Design for Business Success </p> <span class="text-xs text-gray-400"><i class="bi bi-calendar3 mr-1"></i>12 Jun 2026</span> </a> </div> </div> <!-- Services Quick Links --> <div class="bg-[#F4F4FF] rounded-2xl p-6"> <h3 class="text-base font-extrabold text-[#1e1e5c] mb-4">Our Services</h3> <ul class="space-y-2 text-sm"> <li><a href="/web-design" class="flex items-center gap-2 text-gray-700 hover:text-[#EE483D] transition"><i class="bi bi-palette text-[#49499A]"></i> Web Design</a></li> <li><a href="/web-design-development" class="flex items-center gap-2 text-gray-700 hover:text-[#EE483D] transition"><i class="bi bi-code-slash text-[#49499A]"></i> Web Development</a></li> <li><a href="/ecommerce-website-design" class="flex items-center gap-2 text-gray-700 hover:text-[#EE483D] transition"><i class="bi bi-bag text-[#49499A]"></i> E-Commerce Website</a></li> <li><a href="/cms-development" class="flex items-center gap-2 text-gray-700 hover:text-[#EE483D] transition"><i class="bi bi-wordpress text-[#49499A]"></i> WordPress Development</a></li> <li><a href="/android-app-development" class="flex items-center gap-2 text-gray-700 hover:text-[#EE483D] transition"><i class="bi bi-phone text-[#49499A]"></i> Mobile App Development</a></li> <li><a href="/local-seo-services" class="flex items-center gap-2 text-gray-700 hover:text-[#EE483D] transition"><i class="bi bi-graph-up-arrow text-[#49499A]"></i> Online Marketing</a></li> </ul> </div> </aside> </div> </div> <section class="city-cta-section"> <div class="city-cta-deco-1" aria-hidden="true"></div> <div class="city-cta-deco-2" aria-hidden="true"></div> <div class="city-cta-deco-3" aria-hidden="true"></div> <div class="city-cta-deco-4" aria-hidden="true"></div> <div class="max-w-5xl mx-auto px-4 sm:px-6 city-cta-inner"> <div class="city-cta-heading-wrap"> <span class="city-cta-badge"><i class="bi bi-lightning-charge-fill"></i> Let's Work Together</span> </div> <h2 class="city-cta-title">Ready to Grow Your <br><span class="city-cta-title-highlight">Business With Us?</span></h2> <p class="city-cta-desc">Free consultation — tell us about your project and we'll get back within 1 hour.</p> <div class="city-cta-stats"> <div class="city-cta-stat"><i class="bi bi-patch-check-fill city-cta-stat-icon-green"></i> 500+ Projects Delivered</div> <div class="city-cta-stat"><i class="bi bi-star-fill city-cta-stat-icon-yellow"></i> 5★ Google Rating</div> <div class="city-cta-stat"><i class="bi bi-clock-fill city-cta-stat-icon-pink"></i> Reply within 1 Hour</div> <div class="city-cta-stat"><i class="bi bi-shield-fill-check city-cta-stat-icon-blue"></i> 10+ Years Experience</div> </div> <div class="city-cta-btns"> <a href="/contact-us" class="city-cta-btn-primary"><i class="bi bi-envelope-fill"></i> Get a Free Quote</a> <a href="https://wa.me/919990548795" target="_blank" rel="noopener noreferrer" class="city-cta-btn-wa"><i class="bi bi-whatsapp"></i> WhatsApp Us</a> </div> </div> </section> <script> (function(){ var prose = document.querySelector('.prose-custom'); if (!prose) return; // ── Auto Table of Contents (only for long articles: 4+ H2 sections) ────── (function(){ var h2s = prose.querySelectorAll('h2'); if (h2s.length < 4) return; // short article — no TOC var items = []; for (var i = 0; i < h2s.length; i++) { var text = (h2s[i].textContent || '').trim(); if (!text) continue; if (!h2s[i].id) { h2s[i].id = 'sec-' + (i + 1) + '-' + text.toLowerCase() .replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 40); } items.push({ id: h2s[i].id, text: text }); } if (items.length < 4) return; var links = items.map(function (it) { return '<li><a href="#' + it.id + '">' + it.text + '</a></li>'; }).join(''); var toc = document.createElement('div'); toc.className = 'blog-toc'; toc.innerHTML = '<button type="button" class="blog-toc-head" aria-expanded="true">' + '<span><i class="bi bi-list-ul"></i> Table of Contents</span>' + '<i class="bi bi-chevron-up blog-toc-arrow"></i></button>' + '<ul class="blog-toc-list">' + links + '</ul>'; prose.insertBefore(toc, h2s[0]); // place before the first section var head = toc.querySelector('.blog-toc-head'); var list = toc.querySelector('.blog-toc-list'); var arrow = toc.querySelector('.blog-toc-arrow'); head.addEventListener('click', function () { var open = list.style.display !== 'none'; list.style.display = open ? 'none' : 'block'; arrow.className = 'bi blog-toc-arrow ' + (open ? 'bi-chevron-down' : 'bi-chevron-up'); head.setAttribute('aria-expanded', open ? 'false' : 'true'); }); var as = toc.querySelectorAll('a'); for (var j = 0; j < as.length; j++) { as[j].addEventListener('click', function (e) { e.preventDefault(); var t = document.getElementById(this.getAttribute('href').slice(1)); if (t) window.scrollTo({ top: t.getBoundingClientRect().top + window.pageYOffset - 90, behavior: 'smooth' }); }); } })(); // Find the FAQ H2 var faqH2 = null; var headings = prose.querySelectorAll('h2'); for (var hi = 0; hi < headings.length; hi++) { if (/frequently asked questions/i.test(headings[hi].textContent)) { faqH2 = headings[hi]; break; } } if (!faqH2) return; // Build accordion wrapper, insert right after H2 var accordion = document.createElement('div'); accordion.className = 'faq-accordion'; faqH2.parentNode.insertBefore(accordion, faqH2.nextSibling); // Walk siblings after H2, consume H3+P pairs into accordion items var sibling = accordion.nextSibling; while (sibling) { var next = sibling.nextSibling; if (sibling.nodeType === 1) { var tag = sibling.tagName.toUpperCase(); // Stop if we hit another H1/H2 if (tag === 'H1' || tag === 'H2') break; if (tag === 'H3' && sibling.textContent.trim().endsWith('?')) { var qEl = sibling; var aEl = null; // Find the next element sibling (skip text nodes) var ns = next; while (ns && ns.nodeType !== 1) ns = ns.nextSibling; if (ns && ns.tagName.toUpperCase() === 'P') { aEl = ns; next = aEl.nextSibling; // skip past the P } var item = document.createElement('div'); item.className = 'faq-item'; var btn = document.createElement('button'); btn.type = 'button'; btn.className = 'faq-btn'; btn.setAttribute('aria-expanded', 'false'); btn.innerHTML = '<span>' + qEl.innerHTML + '</span><i class="bi bi-chevron-down faq-chevron" aria-hidden="true"></i>'; var answerDiv = document.createElement('div'); answerDiv.className = 'faq-answer'; if (aEl) answerDiv.innerHTML = aEl.outerHTML; btn.addEventListener('click', (function(b, a) { return function() { var open = b.getAttribute('aria-expanded') === 'true'; b.setAttribute('aria-expanded', open ? 'false' : 'true'); a.classList.toggle('open', !open); }; })(btn, answerDiv)); item.appendChild(btn); item.appendChild(answerDiv); accordion.appendChild(item); qEl.parentNode.removeChild(qEl); if (aEl) aEl.parentNode.removeChild(aEl); sibling = next; continue; } } sibling = next; } })(); </script> </main> <!-- ============================================================ FOOTER — Light & Clean ============================================================ --> <footer aria-label="Site footer" class="bg-gray-50 border-t border-gray-100 mt-20"> <!-- Main footer grid --> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-14"> <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-10"> <!-- Col 1: Brand --> <div class="lg:col-span-1"> <a href="/"> <img src="/assets/images/logo/chulbuldesign.svg" alt="Chulbul Design" class="h-7 mb-4" width="160" height="28"> </a> <p class="text-gray-500 text-sm leading-relaxed mb-5"> Web design & development company based in <strong class="text-gray-700">Gurugram, Delhi NCR</strong>. Serving businesses across India, USA, UK & UAE since 2013. </p> <!-- Social icons --> <div class="flex gap-3"> <a href="https://wa.me/919990548795" target="_blank" rel="noopener noreferrer" aria-label="WhatsApp" class="w-10 h-10 rounded-full bg-white border border-gray-200 flex items-center justify-center text-gray-500 hover:text-green-500 hover:border-green-300 hover:bg-green-50 transition"> <i class="bi bi-whatsapp text-base"></i> </a> <a href="https://www.facebook.com/chulbuldesign/" target="_blank" rel="noopener noreferrer" aria-label="Facebook" class="w-10 h-10 rounded-full bg-white border border-gray-200 flex items-center justify-center text-gray-500 hover:text-blue-600 hover:border-blue-300 hover:bg-blue-50 transition"> <i class="bi bi-facebook text-base"></i> </a> <a href="https://www.instagram.com/chulbuldesign/" target="_blank" rel="noopener noreferrer" aria-label="Instagram" class="w-10 h-10 rounded-full bg-white border border-gray-200 flex items-center justify-center text-gray-500 hover:text-pink-500 hover:border-pink-300 hover:bg-pink-50 transition"> <i class="bi bi-instagram text-base"></i> </a> <a href="https://twitter.com/ChulbulDesign/" target="_blank" rel="noopener noreferrer" aria-label="Twitter/X" class="w-10 h-10 rounded-full bg-white border border-gray-200 flex items-center justify-center text-gray-500 hover:text-gray-900 hover:border-gray-400 hover:bg-gray-50 transition"> <i class="bi bi-twitter-x text-base"></i> </a> <a href="https://www.linkedin.com/company/chulbuldesign/" target="_blank" rel="noopener noreferrer" aria-label="LinkedIn" class="w-10 h-10 rounded-full bg-white border border-gray-200 flex items-center justify-center text-gray-500 hover:text-blue-700 hover:border-blue-300 hover:bg-blue-50 transition"> <i class="bi bi-linkedin text-base"></i> </a> </div> </div> <!-- Col 2: Services --> <div> <h3 class="text-xs font-extrabold uppercase tracking-widest text-gray-400 mb-4">Services</h3> <ul class="space-y-2.5"> <li><a href="/web-design-development" class="text-gray-600 hover:text-[#EE483D] text-sm transition">Web Design & Development</a></li> <li><a href="/ecommerce-solutions" class="text-gray-600 hover:text-[#EE483D] text-sm transition">Ecommerce Development</a></li> <li><a href="/mobile-software-development" class="text-gray-600 hover:text-[#EE483D] text-sm transition">Mobile App Development</a></li> <li><a href="/ui-ux-branding" class="text-gray-600 hover:text-[#EE483D] text-sm transition">UI/UX Design & Branding</a></li> <li><a href="/seo-digital-marketing" class="text-gray-600 hover:text-[#EE483D] text-sm transition">SEO & Digital Marketing</a></li> <li><a href="/ai-automation" class="text-gray-600 hover:text-[#EE483D] text-sm transition">AI & Automation</a></li> <li><a href="/website-support" class="text-gray-600 hover:text-[#EE483D] text-sm transition">Website Support</a></li> </ul> </div> <!-- Col 3: Cities --> <div> <h3 class="text-xs font-extrabold uppercase tracking-widest text-gray-400 mb-4">Cities We Serve</h3> <div class="grid grid-cols-2 gap-x-2 gap-y-2"> <a href="/city/gurgaon" class="text-gray-600 hover:text-[#EE483D] text-sm transition">Gurgaon</a> <a href="/city/delhi" class="text-gray-600 hover:text-[#EE483D] text-sm transition">Delhi</a> <a href="/city/noida" class="text-gray-600 hover:text-[#EE483D] text-sm transition">Noida</a> <a href="/city/mumbai" class="text-gray-600 hover:text-[#EE483D] text-sm transition">Mumbai</a> <a href="/city/bangalore" class="text-gray-600 hover:text-[#EE483D] text-sm transition">Bangalore</a> <a href="/city/hyderabad" class="text-gray-600 hover:text-[#EE483D] text-sm transition">Hyderabad</a> <a href="/city/pune" class="text-gray-600 hover:text-[#EE483D] text-sm transition">Pune</a> <a href="/city/chennai" class="text-gray-600 hover:text-[#EE483D] text-sm transition">Chennai</a> <a href="/city/new-york" class="text-gray-600 hover:text-[#EE483D] text-sm transition">New York</a> <a href="/city/london" class="text-gray-600 hover:text-[#EE483D] text-sm transition">London</a> <a href="/city/dubai" class="text-gray-600 hover:text-[#EE483D] text-sm transition">Dubai</a> <a href="/city/toronto" class="text-gray-600 hover:text-[#EE483D] text-sm transition">Toronto</a> </div> <a href="/cities" class="inline-block mt-3 text-xs text-[#EE483D] hover:underline font-semibold">View all 52 cities →</a> </div> <!-- Col 4: Contact --> <div> <h3 class="text-xs font-extrabold uppercase tracking-widest text-gray-400 mb-4">Get In Touch</h3> <ul class="space-y-3"> <li class="flex items-start gap-2.5"> <i class="bi bi-geo-alt text-[#EE483D] text-base mt-0.5 flex-shrink-0"></i> <span class="text-gray-600 text-sm">Sector 15, Flat No. 1277,<br>Gurugram, Haryana — 122001</span> </li> <li> <a href="tel:+919990548795" class="flex items-center gap-2.5 text-gray-600 hover:text-[#EE483D] transition text-sm"> <i class="bi bi-telephone text-[#EE483D] text-base flex-shrink-0"></i> +91 9990 548 795 </a> </li> <li> <a href="mailto:info@chulbuldesign.com" class="flex items-center gap-2.5 text-gray-600 hover:text-[#EE483D] transition text-sm"> <i class="bi bi-envelope text-[#EE483D] text-base flex-shrink-0"></i> info@chulbuldesign.com </a> </li> </ul> <!-- CTA --> <a href="/contact-us" class="inline-flex items-center gap-2 mt-5 bg-[#EE483D] hover:bg-[#d43c31] text-white text-sm font-bold px-5 py-2.5 rounded-xl transition"> <i class="bi bi-chat-dots-fill text-xs"></i> Free Consultation </a> </div> </div> </div> <!-- Bottom bar --> <div class="border-t border-gray-200 bg-white"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4 flex flex-col sm:flex-row items-center justify-between gap-3"> <p class="text-gray-400 text-xs"> © 2013–2026 Chulbul Design LLP. All rights reserved. </p> <div class="flex gap-4"> <a href="/about" class="text-gray-400 hover:text-[#EE483D] text-xs transition">About</a> <a href="/blog" class="text-gray-400 hover:text-[#EE483D] text-xs transition">Blog</a> <a href="/contact-us" class="text-gray-400 hover:text-[#EE483D] text-xs transition">Contact</a> <a href="/cities" class="text-gray-400 hover:text-[#EE483D] text-xs transition">Cities</a> </div> </div> </div> </footer> <script src="/assets/js/main.js" defer></script> <!-- Back to Top --> <button id="back-to-top" onclick="window.scrollTo({top:0,behavior:'smooth'})" aria-label="Back to top"> <i class="bi bi-arrow-up"></i> </button> <script> (function(){ var btn = document.getElementById('back-to-top'); window.addEventListener('scroll', function(){ if (window.scrollY > 300) { btn.style.opacity = '1'; btn.style.transform = 'translateY(0)'; btn.style.pointerEvents = 'auto'; } else { btn.style.opacity = '0'; btn.style.transform = 'translateY(12px)'; btn.style.pointerEvents = 'none'; } }, {passive:true}); })(); </script> </body> </html>