Dynamic Sitemap + RSS feed in NextJS
This article will contain three sections one for the sitemap, RSS feed, and keeping them dynamic together.
Sitemaps
What is a sitemap?
A sitemap is a file on your site that tells Google which pages on your site google should know about.
Why is it important to have a sitemap?
Sitemap makes sure search engines can find and crawl to the most important pages in your website.
Now lets keep the theoretical part short and start with the fun part the implementation.
In order to generate a sitemap in NextJS we are going to use the help of a library called next-sitemap, install it and go through the instructions provided by them.
- npm install next-sitemap
- create a next-sitemap.config.js file in your project root directory.
- add the below config to your file you can definitely change the config depending on your needs, make sure to check the library documentation for that.
/** @type {import('next-sitemap').IConfig} */
module.exports = {
siteUrl: 'https://website-url-example.com',
changefreq: 'daily',
priority: 0.7,
sitemapSize: 5000,
generateRobotsTxt: true,
exclude: ['/termsconditions', '/privacypolicy'],
// Default transformation function
transform: async (config, path) => {
return {
loc: path, // => this will be exported as http(s)://<config.siteUrl>/<path>
changefreq: config.changefreq,
priority: config.priority,
lastmod: config.autoLastmod ? new Date().toISOString() : undefined,
alternateRefs: config.alternateRefs ?? [],
}
},
robotsTxtOptions: {
policies: [
{
userAgent: '*',
allow: '/',
},
{
userAgent: 'black-listed-bot',
disallow: ['/termsconditions', '/privacypolicy'],
},
],
},
}
4. add “postbuild”:”next-sitemap” to your package.json in your scripts object.
"scripts": {
"dev": "next dev",
"build": "next build",
"postbuild": "next-sitemap",
"start": "next start",
"lint": "next lint"
},
5. delete your existing build, and re-build the project, you should see in your public folder sitemap.xml, sitemap-0.xml, robots.txt files added.
And just like that you have finished the sitemap config 🎉🎉
RSS feed
What is RSS feed?
RSS stands for “really simple syndication” or “rich site summary”, it is an XML file that contains a summary of updates from a website, often in the form of a list of articles with links. it is great to get traffic on your website as well, especially if you integrate it with google news.
Why is it important to have an RSS feed?
RSS makes it easier for readers to get the information they’re seeking without wasting time browsing the World Wide Web for it.
Now lets get started with the cool stuff 👩💻
In order to get started we need to install a library called Feed, install it and go through the instructions provided by them.
- npm install feed
- create a file for the feed service I called it generateRssFeed.js you can name it anything you want.
Add the config needed for your article/blog/news, you should have three important things the feed and the items and writing the XML file in your public directory using fs library which you should install if you dont have it.
Below you will find an example for the feed code.
import fs from 'fs'
import { Feed } from 'feed'
export default async function generateRssFeed() {
const siteURL = 'https://example.com'
const date = new Date()
const author = {
name: 'example',
email: 'user@example.com',
link: 'https://twitter.com/example',
}
const feed = new Feed({
title: 'example title',
description: 'example description',
id: siteURL,
link: siteURL,
image: `${siteURL}/favicon.ico`,
favicon: `${siteURL}/favicon.ico`,
copyright: `All rights reserved ${date.getFullYear()}, example`,
updated: date, // today's date
generator: 'Feed for example website',
feedLinks: {
rss2: `${siteURL}/rss/feed.xml`, // xml format
json: `${siteURL}/rss/feed.json`, // json fromat
},
author,
})
}
Below you will find an example for the item/s code.
feed.addItem({
title: title,
id: url,
link: url,
description: description,
content: content,
author: [author],
contributor: [author],
date: new Date(date),
image: image,
})
Below you will find an example for the fs code.
In my case I created a folder named RSS and filled all the categories of the website in it and each category folder includes a feed.xml file which has all the RSS XML feed to it.
fs.mkdirSync(`./public/rss/${category['name']}`, {
recursive: true,
})
fs.writeFileSync(`./public/rss/${category['name']}/feed.xml`,
feed.rss2(),
'utf8'
)
4. Finally add the generateRssFeed() function that you implemented and add it to your index.js file in the getStaticProps() function.
export async function getStaticProps() {
await generateRSS() // generates the RSS feed
}
And just like that you can build and start your project and you will get your RSS feed working !! 🎉🎉
Pretty cool stuff we have come a long way now, the only issue with this is when it goes to production there is nothing triggering this function to make it update the RSS feed, but luckily we have GitHub actions to help us with that!
GitHub actions ( CI/CD )
What is a GitHub actions?
A continuous integration and continuous delivery (CI/CD) platform that allows you to automate your build, test, and deployment pipeline.
Now in our case we are going to use GitHub actions in order to keep our RSS feed up to date, so lets get started!
- under the root directory of the project create “.github” folder.
- under the .github folder create another folder called “workflows”.
** the naming here is important because this is the only way GitHub can understand that this is a GitHub action pipeline **
3. create the rss.yml file, you can name this file anything you want.
name: RSS Generation
on:
schedule:
- cron: '0 * * * *'
env:
NEXT_PUBLIC_ENV: ${{ secrets.NEXT_PUBLIC_ENV }}
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 'lts/*'
cache: 'npm'
- name: Build and push to github to update vercel RSS
run: |
npm i
npm run build
git config --global user.name 'github username'
git config --global user.email 'github email'
git status
git add .
git commit -m "Automated RSS"
git push
Then we are going to create this pipeline, the goal of this pipeline is the following:
- every 1 hour it should be called to generate a new RSS feed because we are using a cron job here.
- when this pipeline is called, it will check if this project needs any environment variables.
- build the project and push the code to GitHub.
- the idea behind pushing the code to GitHub is to trigger vercel to upload the new version of the updated RSS feed.
And just like that you have successfully created a dynamic RSS feed and a sitemap, congrats!🎉🎉
** just wanted to point that the minimum amount of duration for cron jobs in GitHub actions is 5 mins, and the job can be delayed during periods of high loads of GitHub Actions workflow, might be delayed for like 15 mins and you can read more on the official docs for GitHub **
You can easily integrate this with google news by providing the links of the RSS to google news and your news will available there and up to date.
Conclusion
In this article we have walked through the set up and implementation of the sitemap, RSS feed, and keeping everything dynamically updated using GitHub actions.
Happy coding! 👩💻