Framer x Deliveroo: The Veteran Challenge
Part II of II: How Deliveroo uses Framer to design scalable UI components & input real data for user testing prototypes.
Editor’s note: We’ve made some big changes to Framer, and this article refers to a deprecated tool. Learn more about what Framer is today →
Almost a year ago, Deliveroo Design Lead Jonny Burch gave us a behind the scenes look at how the team was beginning to use Framer in their workflow. In this two part series, Deliveroo product designers Tim Davey and Brendan Fagan share their respective beginner and veteran perspectives on how Framer continues to influence Deliveroo’s design, prototyping and user testing workflow.
One of the big projects we’ve been working on is helping our users find and discover food that matters to them. The project encompassed a multitude of changes to navigation, new features, and refinement of existing ones. We had a new area for catering to the job of discovery, but we were also improving search and adding the ability to filter and sort results.
High-fidelity prototypes of our chosen direction would be key in validating design decisions through internal and external user-testing.
Since we were basically looking at re-creating the entire consumer experience, pre-checkout, in a prototype — it was obvious that Framer was the perfect tool to get us there.
So while Tim was learning the ropes of Framer and starting to contribute on the micro-interaction level, I needed to figure the best way to equip our prototype with multiple flows, using scalable components in a variety of layouts, all populated by real data. I’d experimented with components before and messed around with the occasional array, but never at this scale.
Three lessons, learned the hard way, helped me get there.
Components as a foundation
Since we were going to be using a variety of layouts with repeating elements in multiple screens. Starting with components from the very beginning was key.
Initially, I started with Classes, manually creating every component in code. Setting elements I knew would change and inherit data as options.
This worked well enough, but it wasn’t the easiest to share with Tim or other designers. I wanted to explore actually creating a ui-kit of visual components one could copy and paste from.
I started to experiment with Framer’s Design tab to create the components visually. As you would with Classes, you’re setting up the layers within each Frame as placeholders for when you eventually start to pass data.
With components on the Design side, Framer allows you to do some pretty cool stuff with the .copy() and .selectChild() functions.
For example, you could use a loop to create as many cards as you want with .copy(), then you’re able individually select and modify any layer within the component using .selectChild().
for i in [0...3]
card = cardComponent.copy()
card.selectChild("strName").text = "Hello world"
You can see in this example how I’m simply copying over our standard restaurant card component into a new Layer.
Then I’m able to call out any part within the component. For example, my text string is called strRestName. Now I can swap out the placeholder text of the component with whatever I want.
With this method, I was able to create a few components in a ui-kit file, paste it into my discover prototype, and start to pass in fixed data for the restaurant names, prices, cuisine tags, etc.
However, I still needed to layout content within dynamic lists and carousels throughout multiple different areas.
Using layout functions
Most of the different layouts consisted of two interaction patterns. A vertical scroll view, and a horizontal scroll view. The latter sometimes needed to snap to certain items when the user would stop dragging.
Once I had my components, I started to write functions which could easily place them within a scrollComponent or pageComponent (this allows us to snap).
You can see in the example below how the relationship works between the Design and Code parts of Framer. I’ve created a function here to create a vertical scroll view of restaurant cards. The function only has three parameters:
- Amount of cards (the scroll view’s height adjusts based on this)
- Parent view (add the items to the scroll view)
- Data source (restaurant names, photos, cuisine tags, etc.)
Again using .copy() and .selectChild(), I‘m able to reference my original components and start to create dynamic layouts.
We’re making progress! At this point, we started to swap out our fixed arrays with JSON, which brings me to the next lesson.
Really “real” data
We couldn’t have a bunch of fixed arrays for an area that might have 40 or so restaurants. Not only because it would be tons of effort set things up, but what if we wanted to change the area and pass down a bunch of new restaurants?
We wanted to be able to grab data relevant to the user testing participant, so we needed to be able to pull JSON from any UK post code.
Luckily one of our designers, Sam King, was able to write a little script which pulled a master restaurant list file from any UK post code, giving us names, images, ratings, reviews, etc. It also included individual menu level files, so we could grab dish names, prices, things like that.
With the functions setup to inherit data, it was as simple as setting the layers being called with .selectChild() to loop through the corresponding JSON file, rather than the arrays I was using before.
Using .do() here was key to allow data to pass from one area to another. As well, .filter() allowed me to create a dynamic restaurant list based on cuisine tags. That way, when a user would tap on the American cuisine card, we’d scour the JSON to only pass in relevant restaurants to the createRestaurantList() function and create a new restaurant list screen. Special shout out to Matt Vagni for helping me grasp these concepts (and putting up with coffee script).
We were even experiencing a little delay when loading the data(due to the amount of restaurants and my crappy designer code). So why not simple placeholder animation within the functions to make it feel even more real!
Bringing it together
By now, Tim had finished his work on the discover screen, and it was just a matter of translating that over to the components and layout functions. He was able to continue to polish away while I focused on the secondary search and sorting flows.
Again, I was starting with components for new elements like rows and table views. Re-using many of the layout functions, and used filtering to provide a high-fidelity search experience with actual user input from the keyboard.
To wrap up
Even though I’d been using Framer for a while, the need for high-fidelity prototypes at this scale forced me out of my comfort zone. Starting with components, using layout functions, and working with data have all been key lessons in allowing us to take our prototypes to the next level.
As well, one of the most interesting things about this project was seeing how, even though Tim and I had varying familiarity with Framer, we were both able to work side by side on different parts of the experience, each learning new concepts, before combining it all together into one file.
The team has come a long way since Jonny first brought the Framer team to London and got everyone excited, and it’s been instrumental in transforming the way we approach usability testing and we can’t wait to see what Framer has in store to make working with components and real data even more delightful.
If you’re looking for the Framer beginner perspective, I recommend reading Tim Davey’s post on how he found ways to add value to the project even as he was still learning. We’d also love to hear how you use prototyping tools and what works for your team. Feel free to give us a shout at Deliveroo Design Team. If you like what you read, we’re hiring product designers, content strategists, and researchers!