Funneler is a simple gem developed to: group different pages from one or more apps into a cohesive flow.
At Doximity we want to ensure our users get the most out of the medical network they're joining. In order to make that happen, we provide a personalized onboarding experience for each user. Our customization spans the device the user is on (web, mobile web, and our mobile applications) as well as other variations such as taking into account how or when a user is registered. Of course accounting for all these variations is easier said than done.
Funneler provides us the simple tool we need to make that happen:
- It groups pages together via a
funnel_token
parameter - It is light weight - meaning there is very little overhead to modifying a controller to use that parameter when present, or fallback to a default behavior otherwise
- The
funnel_token
is not dependent on any datastore - And thus it can link pages across different applications
- It is simply a link, and therefore can easily be used in emails
Let's take a look at how to use funneler
. For a moment, pretend your application has two pages you want your user to see /welcome
, and /setup
before landing at their final destination /home
.
Naturally the simple solution would be to setup each controller/action to link to the next page. However, as you know that is brittle, and certainly can't be customized per user without a lot of code. This is exactly what funneler
now provides:
funnel = Funneler.build(routes: ['/welcome', '/setup', '/home'])
redirect_to funnel.first_page
This will redirect to a route like /welcome?funnel_token=.....
. The funnel_token
is a JWT token encoded with a few simple pieces of data:
routes
- the array of routes to funnel a user throughcurrent_page_index
- the current index into the routes array
On subsequent requests, any controller can read the funnel_token
and redirect to the next_page
such as:
funnel = Funneler.from_token(token: params[:funnel_token])
redirect_to funnel.next_page
The funnel
simply builds a new token which has an updated current_page_index
, and returns the route at that index with the new funnel_token
in the query string.
Of course this is a simple example with a static set of routes. However it shouldn't be hard to imagine customizing the behavior by dynamically generating the routes given different inputs and parameters. The best part about using funneler is that creates a clear separation between controller behavior, and the business logic determining which pages should be included in the funnel.
Funneler has been open sourced on GitHub - feel free to contribute!