3 Dead-Simple Features to Add to Your Next.js Blog
Introduction
Since I just built my blog last week, I thought I'd share some of the simple features I added that I think add some nice touches to the user experience. These features are very easy to implement and you can probably add all of them to your own blog in a couple of hours. Since my blog is built with styled-components, I'll be using it in the examples, but you can use any styling solution you prefer.
The features I'm going to talk about are:
- Scroll progress bar
- Scroll to top button
- Reading time
You can see these features in action on this very page. If you scroll down, you'll see a progress bar at the top that shows you how much of the content you've read. You'll also see a button in the bottom right corner that allows you to quickly scroll back to the top of the page. And finally, at the top of the page, you'll see a small piece of text that tells you how long it will take to read the article.
1. Scroll progress bar
A scroll progres bar is a very simple feature that shows the user how much content they have read and how much is left. You might be wondering why this is useful since the browser already has a scroll bar, which is a good point to bring up. I personally like this approach because it's more visually appealing and is more intuitive to show a progress of something in a horizontal bar (which is how progress is visualized pretty much everywhere) rather than a vertical one.
To implement this feature, you might be tempted to use a library, but it's actually very easy to do with just a few lines of CSS and JavaScript. Here's how I did it in my blog:
Here, I'm creating a component called ScrollProgress
with a scrollProgress
state variable that keeps track of the scroll progress in a numeric value between 0 and 1. In the useEffect
hook, I'm adding an event listener to the scroll
event that calculates the scroll progress based on the current scroll position and the total height of the page. Note that I'm returning a cleanup function to remove the event listener when the component is unmounted. Then, I'm rendering a styled component called ProgressBar
with the scroll progress as a prop.
This styled component is what actually renders the progress bar. It sets the width of the bar to the scroll progress and scales it horizontally as the user scrolls.
A couple of things to note here:
- I'm using transform to set the width of the progress bar instead of setting the
width
property directly because as it is a more performant way to update and animate the width of an element. - The
transform
property is defined inside thestyle
attribute of the component using theattrs
method from styled-components. This is the recommended way do it for frequently changing styles like this one (which changes on every scroll event)
Then all you need to do is import the ScrollProgress
component wherever you intend to use it:
That's it! You now have a scroll progress bar on your blog.
2. Scroll to top button
Continuing with the theme of scrolling, a scroll to top button is a nice feature to have not only for blogs but for any website with long content. It allows the user to quickly jump back to the top of the page without having to manually scroll. It's especially useful on mobile devices where scrolling can be a bit more cumbersome.
Here's how you can implement a scroll to top button in your blog:
Here I'm an isVisible
state variable to show or hide the button based on the scroll position. I have a toggleVisibility
function that sets the isVisible
state to true
when the user has scrolled more than a certain amount of pixels (in this case, 600). I'm using the useEffect
hook to add an event listener to the scroll
event that calls the toggleVisibility
function. And again, I'm returning a cleanup function to remove the event listener when the component is unmounted.
The scrollToTop
function scrolls the window back to the top of the page when the button is clicked.
And, in case you're wondering, the FaAngleUp
component is an icon from the react-icons library. You can use any icon you like here.
Then,my styled components look like this:
The styles here are just an example, but the important part is that the Wrapper
component is fixed to the bottom right corner of the page and the Button
component is styled as a floating action button with a circular shape and a background color that matches the theme of the blog.
Then, you can import the ScrollToTop
component and use it wherever you want to show the scroll to top button:
3. Reading time
The last simple feature I want to share with you today is a reading time indicator. This is a small piece of text that tells the user how long it will take to read the article. I like this feature because it's just as useful to the user - to know how much time they need to invest in reading the article - as it is to the author - to keep the content consise and to the point.
There are also libraries that can calculate the reading time for you, but it's very easy to do it yourself. I just added a couple of utility functions like this:
I'm creating a utility
function called calculateReadingTime
that takes the MDX content as input, transforms it into raw text, calculates the word count, and then divides it by the average reading speed (it's between 200-250, so I used 225) to get the reading time in minutes. I'm also using another utility function called transformMDXToRawText
to strip out the HTML tags and entities from the MDX content.
Then all you need to do is import the calculateReadingTime
function and use it wherever you want to display the reading time:
That's it! You now have a reading time indicator on your blog.
Putting it all together
If you implement all three of these features, your Post component might look something like this:
Conclusion
And that's it! If you want to see how I built the rest of my blog, you can read my previous article on how I built my blog.
Thanks for reading! 🫐