How I Built a Offline Tracking System Using Next.js & Google Analytics API

Hassan Ahmed
5 min readApr 13, 2024


Note: This case study demonstrates my ability to build products as in this case, I was tasked to be a developer not a product owner!

The most significant disadvantage of a retail space compared to an online store is the ability to track a customer, especially one who is interested in the product yet has not purchased it. As an online store, it is straightforward to install a pixel or cookie to track the customer’s behaviour and, if they have provided an email, send an abandoned cart email or a series of drip campaigns to get them to purchase. However, with the offline space, this is next to impossible.

Thus, the XP agency, working directly with Bose, asked me to develop a digital solution to track visitors in Bose’s vendor stores in the USA’s airports. Although this system is simple in theory, this is my first time building this kind of system.

Website Demo Video


Before I started, I asked the agency project manager to give me a full context of how the visitors and the Bose team would utilize the digital solution to develop a robust, scalable solution.

As mentioned previously, the vendor stores are currently located in the airports, which means they utilize airport wifi (which is not the best, unfortunately). Customers would have access to the digital solution via a QR code. In addition, the digital solution was an accessory to the product because the purpose of the solution was to guide the customer through a series of steps while trying out the product. As a result, a clean pair of Bose earbuds is provided to customers to try on by the sales representative. Finally, this process must be tracked and displayed in a reporting dashboard.

The Bose team aimed to understand which airport stores are performing well. Keeping context in mind, I was the sole developer on the project with a project manager who spoke to the client directly. I chose my familiar tech stack, Next.js and Tailwind, with Google Analytics API for tracking events.


Once the project began, the system was simple to set up, but the moving parts were always challenging but minimal; for instance, the designs for the website’s screens consistently changed, although they were reasonable in terms of scope. However, the biggest challenge was implementing the digital solution offline.

Trying to place a QR code in an airport store not owned by Bose, which is the client, was a challenge unforeseen by the agency, and promoting the QR code was also frowned upon; hence, the customers had to discover the QR code themselves. In addition, there must also be an incentive for a customer to scan the QR code, another challenge the agency recognized midway through the project.


Even though my role on the project was as a developer to build a solution, I quickly had to provide ad-hoc solutions to the agency on best utilizing the demo solution without scraping it all together. One of the solutions was to help with the discoverability of the QR code — make the QR code visible and add sweepstakes in the demo solution, incentivizing the customer with a $200 gift card if they were to win the contest. This solution slightly increased the scope of the project; however, I was able to mitigate it by utilizing AirTable as the lead-capturing database. As a bonus, we also got customers’ emails, which we could use further to target via email marketing.

As mentioned previously, the designs kept changing throughout the process, so I introduced Zeplin to the project manager, who would then upload the new designs to Zeplin. Designs on Zeplin helped streamline the process, allowing me to promptly inspect the changes and implement the designs on the Next.js app correctly.

Ultimately, the technical architecture of the system looked like the following:

Bose Technical Architecture

While considering the airport wifi challenge, I need the site to be blazing fast and the resources to load super quickly. I opted into Cloudinary, cloud-based asset storage, to store videos and audio files. In addition, I utilized Netlify to host the website.

Site Dashboard Built using Next.js & Tailwind with Tremor UI Components

With events being tracked in Google Analytics, the next step was to build a separate admin dashboard to showcase some metrics to provide answers for the Bose team. I utilized the Next.js app with Tailwind and Netlify to host the website. However, unlike last time, I used a few third-party package libraries, most notably:

  • NextAuth — To add basic authentication to the admin dashboard
  • Tremor — To build charts and dashboards
  • Google Analytics Data — To retrieve data from Google Analytics
  • SWR — To fetch and cache data from Next.js API routes
import useSWR from "swr";

// Custom fetch function that appends the query parameters
export const fetchAnalytics = async (
url: string,
query: string,
from: string,
to: string
) => {
const queryParams = `?query=${encodeURIComponent(query)}&from=${from}&to=${to}`;
const response = await fetch(`${url}${queryParams}`, {
method: "GET",
return response.json();

export function useAnalyticsData<T>(
query: string,
fromDate: string,
toDate: string
) {
const url = "<api url>";
const { data, error, isLoading } = useSWR<T>(
[url, query, fromDate, toDate],
// Destructure the parameters directly in the fetcher function
() => fetchAnalytics(url, query, fromDate, toDate)

return { data, error, isLoading };


Here is a screenshot of the performance of the solution from Dr. Google.

Bose Demo Site Performance

I am incredibly proud that my simple solution scores almost perfectly on Google. The stakeholders were generally happy with the digital end solution. There was no downtime, and users could always access the site at any time.

Lessons Learned

Although the project was quite simple, here are the key takeaways:

  • Always be ready for a change and make your solution flexible.
  • Refrain from over-engineering; utilize the available tools for quick and easy solutions.
  • Meet the goals of the client without complicating the solution.
  • Poor execution leads to poorer results, even if the digital solution is magnificent.
  • Tech Stack experience that I acquired: Next.js (Pages & App Router), Cloudinary, Netlify, Airtable API, Google Analytics API and Tailwind CSS.

Although I never spoke to the Bose client directly, I would have loved to have worked with them on the execution strategy. I did my part to the best of my ability, and I wish the client had utilized the solution better.

TL;DR Section

In partnership with XP agency and Bose, I developed a digital tracking system for Bose’s airport store visitors using QR codes. Despite challenges like QR code placement restrictions and poor airport Wi-Fi, we improved QR code visibility and incentivized scans with a sweepstakes contest, capturing customer emails for further marketing. I utilized Next.js, Tailwind, and AirTable, enhancing the project with Cloudinary for fast-loading media and Netlify for hosting. The solution performed excellently, scoring near-perfect in Google’s assessments. My flexible and straightforward approach ensured the project met Bose’s needs effectively, demonstrating the power of leveraging robust tech tools to solve complex problems in retail environments.



Hassan Ahmed

Product Owner / Full Stack Developer | I Build Web Apps & E-commerce Sites | Founder @ Space In Bio