Svelte Uber Eats Navigation
- 2/2024
This type of navigation is very popular with delivery apps, and is quite short to do with Svelte Actions.
But is not very intuitive, so I wanted to share how it’s done.
Here are the links:
- Full Site Example (with tailwind)
- Svelte REPL (only the skeleton, no style)
- Github Repo (give us a star 😎)

a screenshot of the navigation
Knowing what is on the screen
First, we need to know which food category is on the screen, for this we use the IntersectionObserver:
function enterViewPort(e) {
const observer = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
titleInFocus = e.id;
}
});
observer.observe(e);
}
This function will assing the element id (e.id
) to titleInFocus
each time an element enters the screen.
Then we add Svelte Action to each title (if you are not familiar with actions, Joy of Code has an amazing video about it). In our case with simply have to add use:enterViewPort
to the element.
Focusing the button on the nav bar
Now we have to listen for every change in titleInFocus
to scroll the button to the left.
We have to do some manual work know the position at which the scroll should be. scrollIntoView has APIs to do this, but they didn’t work for me.
$: {
let targetElement = document.getElementById(`nav-${titleInFocus}`);
let rect = targetElement?.getBoundingClientRect();
if (rect) {
navReference?.scrollTo({ left: navReference?.scrollLeft + rect?.left - 10, behavior: 'smooth' });
}
}
Note1: we are using id
for the title and nav-id
for the button (e.g. dishes
and nav-dishes
).
Note2: this hack only works if the nav starts at position 0,0 in the viewport. Open for sugestions.
Note3: I could not make both scrolling smooth
when clicking in a button (e.g. the nav bar is smooth but not the page scrolling) bc they would overlap and stop. Open for sugestions.
Conclusion
I’m amazed by how little Svelte is needed to do this, is almost pure DOM.
If you want a more impressive example of Svelte Actions you should check Geoff Rich: Detecting sticky positioning with Svelte actions.