Frontend

Tab Switcher with State Persistence (Atlassian Frontend Interview) | UI Coding Round

A practical UI coding problem asked in interviews at Atlassian focuses on building a tab switcher component. Users can switch between multiple tabs, each displaying different content. As a follow-up, the selected tab should persist using query parameters so the same state is restored on refresh or when sharing the URL.

ByteAndBites·Jul 06, 2026
Tab Switcher with State Persistence (Atlassian Frontend Interview) | UI Coding Round

In a recent Atlassian frontend interview, candidates faced a two-part challenge that involved building a tab switcher component. This exercise aims to evaluate a candidate's ability to implement a basic user interface, manage state, and synchronize that state with the URL. The goal was to create a simple tab switcher, where only one tab can be active at any time, and to ensure the selected tab persists in the URL query parameters when users refresh or directly navigate to a page.


Concepts

  • Tabs UI Pattern: A design pattern enabling users to switch between different sections of content easily.
  • State Management: The process of keeping track of which tab is currently active and displaying the appropriate content.
  • URL Query Parameters (Scale Up): A method to maintain state via the URL, which helps keep the user experience consistent across page reloads.
  • Syncing UI with URL (Scale up): Techniques to ensure that the interface reflects the state specified in the URL.

Problem Breakdown

Part 1: Basic Tab Switcher

The first part of the task is to create a tab switcher where users can click between multiple tabs, activating one at a time. The main requirements are:

To manage the active state, we can use a simple JavaScript variable to track which tab the user has clicked. When a tab is activated, it should render the corresponding content section.


UI for Part 1
UI for Part 1


Part 2 (Scale up): State Persistence using Query Params

The second part of the challenge involves persisting the active tab's state in the URL using query parameters. This persistence is crucial for several reasons:

UI for Scale Up
UI for Scale Up


Handling edge cases is essential here:

  • Invalid Tab: What should happen if an invalid tab number is provided in the URL?
  • Missing Param: We need to define a default behavior when the `tab` parameter is missing.
  • Default Tab: Establishing which tab to show by default when no specific value is given.

Solution


Part 1 Solution

The implementation of the basic tab switcher is straightforward. Below is the code that manages tab interactions:


HTML(index.html)
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Tab Switcher</title>
  <link rel="stylesheet" href="./index.css" />
</head>
<body>

  <div class="container">
    <div class="tabs">
      <button class="tab active" data-tab="1">Tab 1</button>
      <button class="tab" data-tab="2">Tab 2</button>
      <button class="tab" data-tab="3">Tab 3</button>
    </div>

    <div class="content">
      <div class="panel active" data-tab="1">Content for Tab 1</div>
      <div class="panel" data-tab="2">Content for Tab 2</div>
      <div class="panel" data-tab="3">Content for Tab 3</div>
    </div>
  </div>

  <script src="./index.js"></script>
</body>
</html>
CSS(index.css)
body {
    font-family: Arial, sans-serif;
    background: #f5f7fa;
    display: flex;
    justify-content: center;
    margin-top: 60px;
  }
  
  .container {
    width: 400px;
  }
  
  .tabs {
    display: flex;
    border-bottom: 2px solid #ddd;
  }
  
  .tab {
    flex: 1;
    padding: 10px;
    cursor: pointer;
    background: #eee;
    border: none;
  }
  
  .tab.active {
    background: white;
    border-bottom: 2px solid #3b82f6;
    font-weight: bold;
  }
  
  .content {
    padding: 20px;
    background: white;
    border: 1px solid #ddd;
  }
  
  .panel {
    display: none;
  }
  
  .panel.active {
    display: block;
  }
JavaScript(index.js)
const tabs = document.querySelectorAll(".tab");
const panels = document.querySelectorAll(".panel");

tabs.forEach(tab => {
  tab.addEventListener("click", () => {
    const selected = tab.dataset.tab;

    // update tab active state
    tabs.forEach(t => t.classList.remove("active"));
    tab.classList.add("active");

    // update panel
    panels.forEach(panel => {
      panel.classList.toggle("active", panel.dataset.tab === selected);
    });
  });
});

Part 2 (Scale Up) Solution

The next step is to integrate URL management with our tab switcher. Here's how we can achieve that:

JavaScript(index.js)
const tabs = document.querySelectorAll(".tab");
const panels = document.querySelectorAll(".panel");

// Helper: activate tab
function activateTab(tabId) {
  tabs.forEach(tab => {
    tab.classList.toggle("active", tab.dataset.tab === tabId);
  });

  panels.forEach(panel => {
    panel.classList.toggle("active", panel.dataset.tab === tabId);
  });
}

// Helper: update URL
function updateURL(tabId) {
  const url = new URL(window.location);
  url.searchParams.set("tab", tabId);
  window.history.pushState({}, "", url);
}

// Handle tab click
tabs.forEach(tab => {
  tab.addEventListener("click", () => {
    const selected = tab.dataset.tab;

    activateTab(selected);
    updateURL(selected);
  });
});

// On load → read from URL
function initFromURL() {
  const params = new URLSearchParams(window.location.search);
  const tab = params.get("tab");

  if (tab && [...tabs].some(t => t.dataset.tab === tab)) {
    activateTab(tab);
  } else {
    activateTab("1"); // default
  }
}

initFromURL();

This implementation accomplishes two main objectives:

Conclusion

Through this exercise, interviewers assess a candidate's ability to manage component state and synchronize it with URL parameters. Successful candidates will demonstrate a clear understanding of tab management, URL handling, and how to think critically about user experience. The difference between an average and a strong answer lies not only in the correct implementation but also in articulating the rationale behind design decisions and handling edge cases effectively.


Similar Questions

InterviewAtlassianJavascriptHTMLUI
Frontend Interview Playbook 🚀
Series
Frontend Interview Playbook 🚀
View series
A curated series of real frontend interview questions from top companies like Google, Amazon, Uber, Atlassian, Roku, etc. Each blog breaks down problems, thought processes, and optimal solutions to help you master concepts, improve problem-solving, and confidently crack frontend interviews at leading tech companies.