How Spinwheel Implements Drop-In Module Widgets
Spinwheel, a debt management API solution, provides pre-built templates that enable the client to quickly and easily embed data into their existing app or service. Our UI templates consist of 3 parts:
- A JS initialization script which loads the use case (React based UI) passing certain parameters to the page to configure which use case to use, which elements to show and how the navigation should work. It is embedded as an iframe in the partner’s page.
- The React based UI uses the URL parameters passed to it to render specific JS libraries – for example, Drop-In Modules (known as DIM).
- Each DIM is designed for a specific use case such as creating a user in the Spinwheel Platform, showing a dashboard of existing liabilities, scheduling one time or recurring payments for a specific loan, and showing the transaction history of payments made via the Spinwheel Platform.
Previously, we implemented the entire use case at once into the partner page. The new requirement was to load smaller sections of the DIM to display information or accept user input and reflect the information based on that. For example, accepting the additional payment and showing graphs indicating how they impact the overall loan or showing a form to create an allocation of additional payment amounts towards the user’s loan.
This resulted in unique challenges when loading more than one DIM in a single page including:
- Assets (css/js/images/fonts) should be loaded only once
- API calls for fetching data such as user information or partner information. This should be made only once even though we are loading them multiple times.
- When we make a change in one widget other widgets should reactively show the information
- Widgets should refresh based on external inputs without reloading the entire iframe.
Before solving these challenges, the implementation had been built for calling APIs every time we included a DIM.
Before solving for these challenges, the implementation had been built for a first-time API call only.
In order to overcome these challenges, we came up with a multi-step solution:
- We added a service worker to cache the assets locally on client browsers.
- Added a migration strategy to delete caches and recreate on subsequent releases.
- Added a global caching layer on top of our data providers.
- Added a data syncing mechanism in caching layer with Broadcast Channels.
- Established window messaging to pass down the config data into React widget.