< Back

January 20th, 2026

From Waitlist to Launch: Building NG Stocks Growth Strategy

{ Engineering }

From Waitlist to Launch: Building NG Stocks Growth Strategy

Idorenyin Udoh
by

Idorenyin Udoh


A few months ago, we launched NG Stocks on Cowrywise. Since then, you could seamlessly buy and sell shares of up to 140 companies/indices listed on the Nigerian Stock Exchange, via Cowrywise. A lot of work has gone into this product — and every team at the company actively contributed to getting us to a decent place before we went live. However, this article focuses on the frontend marketing work that powered the product’s launch.

The Waitlist Page

The growth team aimed to achieve some goals with the waitlist page — to build anticipation and get early testers. To accomplish this, the brand and product design teams collaborated to put something together, and I was in charge of the implementation of the waitlist page’s design.

The Stocks Waitlist page

The design, however fastly put together, came out beautiful. I decided to experiment with a floating effect for the coin and sunflower assets on the foreground, and they even had a subtle bounce after a successful waitlist submission.

A lot of improvements would eventually be implemented on the waitlist page. Some of them were:

  • including a countdown timer,
  • including social share CTAs, and
  • more appropriate copy updates.
The form on the Stocks waitlist page being submitted

Some work was also being done behind the scenes of these subtle interactions. We set up an event on Posthog to capture once the waitlist form was interacted with, before sending the email address off to our customer.io workflow. If the waitlist applicant was a Cowrywise customer, they received an email with a share CTA. If not, they received an email with a signup CTA. Either way, they were added to the waitlist, which we had on Posthog and customer.io.

async handleSubmit() {
  try {
    const processedEmail = this.email.trim().toLowerCase()

    if (!processedEmail) {
      this.errorMessage = 'Enter your email address'
      this.animateErrorMessage()
      return
    }

    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
    if (!emailRegex.test(processedEmail)) {
      this.errorMessage = 'Invalid email address'
      this.animateErrorMessage()
      return
    }

    this.errorMessage = ''
    this.isLoading = true

    try {
      this.captureEvent('STOCK_WAITLIST_SELECTED', {
      email: processedEmail
    })
  } catch (error) {}

  await cioanalytics.reset()
  await cioanalytics.identify(processedEmail, {
    email: processedEmail,
    stock_waitlist: true
  })

  cioanalytics.track('stock_waitlist')

  this.isSuccessful = true
  this.email = ''
  this.errorMessage = ''
  this.isLoading = false
  this.$nextTick(() => {
    this.animateSuccessMessage()
    this.animateCoinsOnSubmit()
  })
} catch (error) {
   this.errorMessage = 'An error occurred. Please try again later.'
   this.isSuccessful = false
   this.email = ''
   this.isLoading = false
   this.animateErrorMessage()
  }
}

The website was still in Nuxt 2 at the time, so that should explain the numerous instances of the this keyword. You can read about how we approached the migration to Nuxt 3 here. Although the article discusses the migration of the Cowrywise web app, we used the same approach for the website’s migration.

The Announcement Snackbar

The growth team had commenced marketing campaigns for the waitlist, and a lot of people were starting to join. It was cool to see the posts on X with the pre-filled messages from the social share button. Around this time, we had already started testing the Stocks product internally. However, the growth team came forward with one additional request — a “pop-up” on the website to lead users to the waitlist page.

The design team came up with a small component that I named <AnnouncementSnackbar /> in the codebase. It appeared whenever users were on any page of the website, except for the waitlist page. We didn’t have any modal on the website at the time, and the design team thought this was the best unobtrusive approach to take.

The Stocks announcement snackbar

Not long after we went live with this snackbar on the website, the growth team had some feedback — they wanted something bigger and more noticeable. Team members from the design, growth, and engineering teams shared their opinions on this request, including me. That particular Slack thread quickly had over 170 replies. The design team mainly cared about not being intrusive with the modal. However, the growth team felt the snackbar could easily go unnoticed — an oversight that was too expensive for what they were gunning for: 100k applicants on the waitlist.

Eventually, we were all able to agree, and the design team handed off an actual modal. I then replaced <AnnouncementSnackbar /> with <StocksWaitlistModal />, where I implemented the modal. This back-and-forth taught us the value of bringing multiple perspectives to the table early. Different teams brought different constraints but that friction led to a better solution.

The Stocks announcement modal

Like with the snackbar, the modal only came up on all pages on the website except the waitlist page. The modal’s visibility was dependent on three more variables:

  • if it hadn’t been dismissed by the user (either by clicking the close button or the overlay),
  • if it had come up less than twice, and
  • if the countdown time on the waitlist page hadn’t elapsed.

We utilized cookies to track the number of times the modal appeared and its dismissal by the user.

isStocksWaitlistPage() {
  return this.$route.path.includes('/stocks/waitlist')
},

isCountdownElapsed() {
  const targetDate = new Date('2025-07-22T00:00:00+01:00')
  const now = new Date()
  
  return now >= targetDate
},

shouldShowModal() {
  const dismissed = this.getCookie(this.dismissedCookieName)
  const showCount = parseInt(this.getCookie(this.countCookieName)) || 0
  
  return !this.isStocksWaitlistPage && dismissed !== 'true' && showCount < 2 && !this.isCountdownElapsed
}

By this time, we were already working on finishing touches on the product, and the waitlist numbers kept going up. The design team had also commenced work on the actual Stocks page on the website, as the time for the waitlist to be closed was near.

By the time we closed the waitlist, the page had gotten up to 150k unique visits, converting over 50% of visitors into waitlist applicants, and we had amassed over 80k waitlist applicants in total. We then reworked the content on the page a little, and a sign-up CTA was introduced.

The Stocks waitlist page after the timer elapsed

The Stocks Page

The development of the Stocks page on the website was pretty smooth. Because I had a lot on my plate at the time, someone else from my team worked on the page while I made a few cointributions.

The Stocks page

This particular page on the website went live together with the Stocks product, and the waitlist page now redirects to the Stocks page. We also implemented individual pages for each company /index listed on NGX, and it has been helpful for our SEO.

GTCO Stock page on Cowrywise website

The Impact

While the NG Stocks product itself represents a significant engineering achievement, the frontend work to introduce it to users was equally crucial. The waitlist page, announcement snackbar-turned-modal, and the landing page weren’t just marketing tools — they were carefully crafted experiences designed to build anticipation, drive engagement, and guide users into the product.

This project showcased the importance of cross-functional collaboration. What started as a simple design concept evolved through feedback from growth, design, and engineering teams into a polished user journey. The iteration from snackbar to modal alone taught us valuable lessons about balancing aesthetic goals with conversion objectives. By the time we hit 80k waitlist applicants, we knew we’d built something that resonated with users.

As we continue to scale the Stocks product, the patterns and components we built during launch have served as a foundation for subsequent features. It’s a reminder that some of the most impactful engineering work happens in the moments that bring users to the door.


Next article

How We Migrated Our Largest App from Nuxt 2 to Nuxt 3
How We Migrated Our Largest App from Nuxt 2 to Nuxt 3
Festus

Festus;

{ Frontend Engineer } Cowrywise