How I put the scroll percentage in the title bar
Scroll down!
I mean it! Just scroll!
And then look up. A bit further. Yes, to the area of your tab bar where the <title>
content ends up. And then scroll again.
There's a percentage there. And it changes when you are scrolling. Kinda cool isn‘t it? Now you can tab away from this site and still have a sense of how far you have read. That surely makes your existence a tad more pleasant, doesn‘t it?
The idea to put the scroll percentage in the title bar came from this tweet by @round.
I didn’t make a browser extension, rather, I just put the mechanics into my own blog post template. Since I’m on Gatsby and React, it was not that hard. Here’s how to do it:
First I installed the react-scroll-percentage
package. That takes care of most of the heavy lifting. Then, and I’m honestly feel a bit out of depth here, I thought it made sense to put the actual mechanics into useEffect
. It may be that it would have been possible to make Gatsby and React rerender the <title>
part in another way, but I was just following my gut here (tell me on Twitter if there‘s a better way). So I ended up with something like this (actual code here):
import React, {useEffect} from 'react'import {useScrollPercentage} from 'react-scroll-percentage'import Container from '../components/container'import BlogPost from '../components/blog-post'import SEO from '../components/seo'import Layout from '../containers/layout'import {toPlainText} from '../lib/helpers'const BlogPost = ({post}) => {const {title, _rawExcerpt} = postconst [ref, percentage] = useScrollPercentage()useEffect(() => {if (post) {const percent = Math.round(percentage * 100)document.title = `${percent}% ${post.title}`}}, [percentage])return (<Layout>{post && <SEO title={` ${title}` || 'Untitled'} description={toPlainText(_rawExcerpt || [])} />}<div ref={ref}>{post && <BlogPost {...post} />}</div></Layout>)}export default BlogPost
Since react-scoll-percentage uses Intersection Observer, which is a relatively new browser API, we also need a polyfill for browsers that doesn’t support it yet. First install it as a dependency.
npm i intersection-observer
Then we want Gatsby only to use the polyfill in the browser, and import it dynamically when it‘s needed. We’ll do that by inserting this into gatsby-browser.js
:
// gatsby-browser.jsexport const onClientEntry = async () => {if (typeof IntersectionObserver === `undefined`) {await import(`intersection-observer`);}}
And that’s it! Now, marvel at your new updating reading lenght!