Building a Single Page App on HubSpot

Kiosk_SingleApp-01.jpg

Background: We've been working on a large project for a client, that required creating a single page app(SPA) on HubSpot, this SPA had to work on a large touchscreen kiosk and numerous iPads.

This is a "what we learned and how we did it" sort of post.

We had the following requirements:

  • The app needed to be as performant as we can make it (ideally feel like an app) and the location where the kiosk was being used it was possible internet speed could be slow.

  • The app had to use HubSpot forms that would send different PDFs to the visitors via email, based on requests they made from the app.

  • The PDFs needed to be rendered live in the app with the ability to page through them. Without using an external service, or converting to jpgs.

  • The same app had to look good on both iPads and a giant screen.

  • The app had to be locked down so it was hard to break out of it. (full screen, no ability to escape)

  • The app had to handle users walking away after interacting with it.

  • At no point can we ever let the kiosk show another user's information. In the case where someone abandons a form, or someone fills out a form, we can't let the browser pre-fill the form again.

  • Some of the content throughout the app couldn't go live until a huge announcement was made, once it was made the app had to be able to instantly reflect the update.
    As added security the secret content physically wasn't on the page nor downloaded by the browser until triggered to do so, which prevents hacking and snooping for the data.

  • The client wanted to continue to update this app down the road so it has to be maintainable.

  • We needed a way for team members on the ground to refresh the data in the apps as well as push our updates live when appropriate.

The Tech we used:

  • Large human sized touch screen kiosks with Windows 10 PC's hidden inside. They run Google Chrome full-screen on tablet mode.

  • iPads

  • Vue.js

  • pdf.js

  • HubSpot (CMS, workflows, forms API, image resizing, custom modules)

  • Dexie.js for indexDB integration

  • slick-slider.js

We needed the app to feel fast and we knew it was going to be complex, so we needed to have a way to keep it maintainable. We chose Vue.js for it's simplicity and efficiency. 

We had tons of data we had to load from HubSpot HubDB tables, some of it was processed on an external server and sent back, some of it we were able to use HubL to generate JSON arrays right in the SPA page allowing us to instantly load a good portion of the app. This allows the app to work while the larger bulk of the data was still downloading.

The data that was downloaded to the browser is stored locally in indexDB via Dexie.js. If the page is reloaded, the app checks to see if the data is there first and if so, it wouldn't have to download all of the data again. This allow reloads to be highly performant and almost instantaneous. This also reducing the need for an internet connection, which is important in tradeshow floor where WiFi is inconsistent.

All of the data for the app gets downloaded right off the bat except the images and PDFs. The images lazy load on demand, and when a user taps to open a PDF, the files are downloaded by the device and rendered onto the screen live.  There is about a 1 second load time for the PDFs, but once downloaded turning pages is near instantaneous.

Forms on the app are dynamically updated based on the user requests and activity. When submitted, HubSpot workflows take over - assigning properties, putting folks in lists, and sending email responses. The email uses personalization tokens to show or hide links to different PDFs based on the users selection. Of course this is all tracked in the HubSpot CMS, with a record of the person using the kiosk. On HubSpot's end they can track every time that person has interacted with the kiosk, the website, the iPads, and provide that data to the sales team. Since the forms need to be regenerated so the next visitor can fill them out without seeing the previous visitors information, the forms get destroyed when the user navigates away from them. 

In order to get the iPads in good order for the kiosks we actually built the app almost as a Progressive Web App (PWA). The page has a manifest file, and runs as a standalone app when added to the home screen. In the future, if needed, we can employ a service worker and actually make the whole SPA work offline, as well as automatically sync updates to the application data.

Reflecting back on the project, we did have our share of challenges. There was an incompatibility between iPad’s mobile Safari browser and Dixie.js. We ended up having to fork Dixie.js to fix the issue. There was another issue with Windows 10 PC's on-screen keyboard. The keyboard for the kiosks had an annoying flaw that we had to work around - it was movable by the visitors, which was nice, but the problem was if they moved the keyboard over the fields they were editing Windows would slide up a blank white screen cropping the page and sliding up the content of the page to be above the keyboard. This is so the user could see the text they were editing. While this was acceptable on a tablet, it was a bad experience on a 6 foot tall kiosk. To work around this issue we simply moved the forms so they would be near the top of the app, with the educated guess that most people would not want the keyboard higher than eye level.

Our team had a lot of fun with this project. If your next project requires SPA functionality, let us know how we can help!