[Pitch] Quick navigation in DocC Render

Hi everyone!

I’m excited to share a new feature I’ve been working on for swift-docc-render - Quick navigation. The goal is to create an accessible, easy and fast way to navigate and discover symbols in the documentation through fuzzy search. Quick navigation aims to bring a similar experience to what you achieve using Open Quickly in Xcode and other search tools inside IDEs or web-based documentation.

For me, this is particularly exciting because improves the search experience within the web-rendered documentation, making it easier for the community to find what they need, and allowing the reader to discover and quickly jump through symbols without having to remember the exact name. Including this type of feature on swift-docc-render makes the whole documentation experience more robust and enjoyable.

Key functionalities

  • Fuzzy search - Quick navigation allows approximate match between the user input and the symbol names, returning results relevant to the user.
  • Symbols ranking - Results are sorted in a way that the most relevant ones are at the top of the list. This is done using similarity metrics, such as the length difference between the input and the match, the length of the symbol name, and how far from the beginning of the string the match occurs.
  • Keyboard navigation - This feature will be fully accessible via keyboard shortcuts, making it easy to perform queries even when the navigation bar is collapsed.

UI and keyboard shortcuts

The UI consists of a modal containing a text input and a list, the list is displayed once the user starts typing, and the query matches get ordered by similarity. This modal can be opened by clicking the / button inside the navbar input filter and closed by clicking outside the container or the ESC button.

Interactions with the modal can be done via keyboard shortcuts:

  • / or ⌘+shift+o to open the modal
  • ESC key to dismiss the modal
  • Up and down arrow keys to move through the list of results
  • Enter key to access the selected symbol

I've set up a prototype on my argument-parser fork with the proposed feature, you can test it here https://sofiaromorales.github.io/swift-argument-parser/documentation/argumentparser/

Quick navigation is still under development, but I'd love to hear your feedback and suggestions!

One of the biggest questions we have right now is where to place the button to open the modal (currently located inside the sidebar filter input) so that it makes the most sense with the expected functionality creating a great user experience.

The things that are on the roadmap for the upcoming weeks are:

  • Improve a11y
  • Improve the sorting algorithm by prioritizing results that match the input by being case sensitive
  • Fix performance bugs in larger documentations

Quick navigation is currently part of this PR https://github.com/apple/swift-docc-render/pull/396 under the quickNavigation feature flag. I'm still in the process of polishing and fixing bugs, so I'd highly appreciate that if you find any bugs while testing the feature to file an issue here.

Future directions

Some of the things that would be nice to work on in the future regarding Quick navigation are:

  • Add Quick navigation in /tutorials. Right now the modal can only be opened on the /documentation path.
  • Add the symbol abstract into the information displayed for each list item, this would provide the reader more context about the symbol without having to access it. We would have to add the abstract to the index.json file generated by the compiler, significantly increasing the file size which could cause performance issues.
  • Match the sidebar filtering algorithm to the Quick navigation filtering algorithm. Currently, the sidebar only does exact matches between the user input and the symbol name, and it might be beneficial to do partial matches here as well.

Special thanks to my mentors @marinaaisa @franklin and @beatriz, who helped me develop this feature and took the time to review my progress.

I look forward to hearing your feedback!


Love it! :tada:

Just from having a quick play it works how I would expect it to work. Although it has made me realise it would be nice to have some colours on the type icons to help distinguish the type of the search results at a glance, but that's a separate issue.

Great job.


Very nice!

Only minor improvement is perhaps that if I type a symbol quickly and hit Enter, then I will press Enter before the search results arrives - then I will need to press it again. Don't know if it's possible, but would be nice to go to the first search result if I did press return while waiting for them to display.


It's nice, if a little slow to respond to input after a keypress (although I saw you are still working on performance optimisations, so that might be why).

One niggle I hit trying the prototype: Pressing Cmd+A whilst the search box is focused selects the entire modal div, not merely the content of the search box. That means pressing backspace to clear doesn't work.


This looks really great! :rocket: Definitely a great future that will be used lots

One area for future directions could be adding the documentation body to the search as well - this would enable it to work as a quick search feature so I can search for terms that appear in the docs rather than just symbols.

Overall however, really like this pitch and big +1 from me


That's awesome!

A small thing I've noticed: the module page (i.e. documentation/ArgumentParser) does not show up when I search for "ArgumentParser".

Your fuzzy search already handles missing letters really well! A direction for the future could be handling duplicated letters or such that are switched around. E.g. searching for ArggumentParser or AgrumentParser yields zero results right now. However, I'm not sure if it would be worth it as it could increase the memory footprint and search latency quite a bit.

1 Like

This is really exciting. Great work @sofiaromorales! I’ve long thought that most websites should have a feature like this, it's just so useful.

Two little things I noticed:

  1. If your browser window is just a little bit too narrow so that the sidebar isn't shown, there seems to be no UI element to discover this option if you don't know the keyboard shortcut. Even when opening the sidebar the button with the slash is not visible (but I really think there should be a search button in the main interface when the sidebar isn't visible).

  2. In my browser, Firefox on Mac, the Cmd+Shift+O shortcut doesn't work, presumably because it's bound to a browser feature (it opens the Library window). I don't know if you can do anything about this and even if you can, you probably shouldn't because people will not want websites to steal their keyboard shortcuts. So kudos for providing two alternatives!

@dlbuckley I'm glad you liked it! I've been trying to match the design of the feature as much as possible to the website because I don't want to be too disruptive with the current UI, but I totally agree that adding a subtle color difference to each of the symbol type icons would make it a lot easier for the user, thanks for the feedback!

Thanks @hassila! I do need to improve the performance to get those results faster, definitely something I'll be working on these days


That’d be nice, but if it is possible to understand enter was hit while getting the results and just apply it after the results were received, it’d be ok too - not sure what is technically possible in a browser context though!

1 Like

Thanks for taking the time to test the feature @bzamayo :blush: Cmd+A selects all the elements on the screen by default on any website, but thanks for pointing it out, focusing on the input field when the backspace key is pressed or entirely disabling that shortcut is a good idea

Yes, this is something that I would like to see as part of the feature too, maybe not the entire documentation body but only the abstract of each symbol, the main blocker of this is that it would imply adding more content into the index.json file, which works as the data source for the sidebar and Quick navigation, probably causing some considerable performance issues, I'm glad you liked it tho!

@theMomax thanks for testing the prototype! I'll take a look into that "ArgumentParser" case :eyes:

Regarding the typo tolerance, it wasn't considered mainly because of the use case, originally the feature was intended to help the user find the symbols faster without having to type the entire name or having to remember it completely, so making it typo tolerable wasn't part of the feature goal, but if it is something that the community is interested in it could be considered for future development, thanks for bringing that up!

1 Like

I hink simple typo tolerance when just switching two chars (by far my most common typo) would be nice - it could be done as a fallback if there are zero hits for a search only (as there typically would be in that case) so no overhead when not doing typos.


Generally true, but in the context of a text input form element it typically only selects the focused text content. EG. you can try Command+A in this forum's search bar, or the sidebar search bar in the docs, and it only selects the text in the search bar.

  1. This has been a topic of discussion during the development of the feature. The current placement is temporal because, as you mentioned is not very visible, and the user might get confused expecting that, since it's inside the sidebar input filter, it will trigger an action related to that component, on the other hand, since both have similar functionalities we wanted to keep the button near to the sidebar, but then it wouldn't be visible when is hidden, do you have any preference of where the open-modal button should be placed?

  2. I wonder if there's any other browser where the keyboard shortcuts are colliding, I prefer not overriding the native implementations, so I'm glad we have both to open the modal :)

Thanks for the feedback @ole!

1 Like

Really great work here @sofiaromorales! UX-wise, this is quite delightful to use. Some questions/comments:

  1. I share @bzamayo's feedback regarding the performance of it. ArgumentParser is not a huge library, so I'm wondering what the cause of the slight delay is. Reducing that delay will make the experience feel even quicker.

  2. I feel like the / button is misplaced. I'm all for making this feature more discoverable, but when it's placed inside the navigator filter bar, it feels like pressing / will focus the navigator filter bar rather than present a modal. I'm wondering if a :mag: icon next to the new toggle sidebar button could work. That way the feature is discoverable whether the sidebar is enabled or not.

  3. I'm not sure that ESC label in the Quick Navigation bar is useful. On narrow viewports, I'd expect to take up space away from the query string. I feel like it's a common expectation that the Escape key closes modals, so I'd lean towards not including the label at all and keep the design simpler.

I also filed some small bugs to make sure we don't lose track of them :) Issues · apple/swift-docc-render · GitHub

Amazing work!

1 Like

@sofiaromorales On some further investigation, I believe the feeling of 'slowness' is mostly being caused by the key input events being debounced by 500ms on every key press here. AFAICT, this is unnecessary and simply removing that delay (or reducing it to something lower like 10-50ms) would help a lot.

1 Like

Hello Sofia, this looks great I just have a few small things:

  1. Would users be able to use this on mobile devices or its only meant for desktop?
  2. Same as other users have pointed out, I think we should move the icon to toggle it somewhere else. You may close the navigator, so it becomes hidden. Also this way it feels like part of the Navigator, which it is not.
  3. Sorry I missed this in the initial discussions, but I’m wondering what was your thought process regarding uses of navigator sidebar filtering vs. Quick Navigation? Are there specific scenarios you expect to use one over the other, and how does that impact how you’ve decided to display results?
1 Like

Great work! Thanks :pray:

1 Like