Sitemap
In this chapter, we will ensure all major search engines like Google Search, Bing, DuckDuckGo (through Bing), are indexing our website by providing Google Search Console and Bing Webmaster Tools with an initial sitemap that will contain links to all our pages
We have 3 options when it comes to creating a sitemap for our Next.js project, either search for a free online sitemap generator, or create a sitemap.xml manually and add it into your /app
folder or generate a dynamic sitemap using code
Static sitemap
First, we are going to create a static sitemap, go into the /app
folder, and create a sitemap.ts
file:
Line 1: we import the MetadataRoute
type from Next.js which we use (line 3) to strictly type our sitemap response
Lines 7 to 10: we create a sitemap entry for our homepage
Now that your sitemap is done, make sure your dev server is running, and then have a look at your sitemap http://localhost:3000/sitemap.xml
in the browser
This is of course the most basic possible version, at least you may want to add more pages or have a look at the next chapter, where we will create a dynamic sitemap
Dynamic sitemap
One way of doing a more advanced sitemap, is by listing your MDX files (pages) that are in folder and then loop through the result to create the entries of the sitemap, one for each page you find
For that we first need a glob pattern package, I compared fast-glob, glob, globby using npm-compare, there is also a very interesting section at the end of the glob repository readme with is a comparison of the 3 and it also has some benchmarks
In the end I decided to use glob, as it seems to be well supported, has a decent amount of stars and has all the features I need:
Another package we need to add is vfile-matter a package we will use to read the frontmatter of our documents:
This dynamic sitemap generator will use a third package called vfile but we do NOT need to install it manually because it already got installed when we added support for MDX documents (vfile is a dependency of @mdx-js/mdx which is a dependency of @mdx-js/loader)
Lines 2 and 3: we import two modules from nodejs which we will use to create a path and open the pages we want to include in our sitemap
Lines 4 to 6: we import 3 more packages, glob will be used to get a list of pages in a directory, vfile will be used to turn the page content from a string into a vfile and finally vfile-matter will be used to extract the frontmatter from the vfile. The last two packages are part of unifiedjs which is the organization that does all those amazing packages like remark, rehype, mdx and a lot more
Lines 8 to 15: we declare a module for our vfile content to strictly type the frontmatter we will extract as they suggest doing in the vfile-matter README. This will tell typescript that frontmatter.modified and frontmatter.permalink are strings instead of having typescript assume that they are of type any.
Line 19: we set a default date for all pages that don't have frontmatter and hence no last updated date
Lines 21 to 26: we create a first entry for our sitemap which is for the homepage of our website/blog
Line 28: we use the glob package to find all our MDX pages, I set the maxDepth glob option to 4 meaning it will only fetch pages that 4 levels deep (to only fetch main pages and no pages in sub-folders); if you want to fetch all pages then you can remove this option entirely, or if you want to go a little bit deeper then increase the value to what suits your needs
Lines 30 to 50: we loop through all the pages that the glob package found; for each page we use the two node modules (we imported earlier) to create a full path and then read the content of the page file; next we use the vfile package to turn the page content (which is a sting) into a valid vfile; then we use the vfile-matter package to extract the frontmatter from the page and turn it into a frontmatter object; then for pages that have no permalink we create a default page url (if all your pages have frontmatter then you can delete or comment this line out); finally we create a sitemap entry using all the values we have gathered
If you want to have a look at your sitemap, make sure the dev server is running (npm run dev
) and then open http://localhost:3000/sitemap.xml
in your browser
robots.txt
Even if you don't plan on having a complex robots.txt, first it could be useful to help bots find your sitemap and second it will just avoid getting 404s every time a bot attempts to read your robots.txt
You can of course create a static robots.txt and place it into your /app
folder, or you can create a more complex and dynamic robots file using typescript:
This is a basic robots.txt file, we define that all bots can crawl our website, no matter what URL. We also inform the bot about the location of sitemap.xml
If you want to have a look at your robots.txt, make sure the dev server is running (npm run dev
) and then open http://localhost:3000/robots.txt
in your browser
Google Search Console
Start by visiting the Google Search Console website and then click on Start now
Then you need log in or if you don't have a google account yet, you will need to create one, you can do so with any email address, so NOT just with a gmail address, for example an @hotmail.com email address works too
If this is your first domain you will have a field in the middle of the page asking you what domain you want to add, enter your domain name and then click on Continue
If you already added a domain in the past, on the top left click on the down arrow of the domains select box and then select + Add property, then enter your domain name and then click on Continue
Next, you need to verify that you own the domain (property) by either adding a txt or CNAME record
As we deployed our website using Vercel and added our domain in Vercel for the production website, we need to also use the Vercel DNS tool to add the txt record
First, visit Vercel.com and then log in
You should now be on the overview page, in the top navigation click on domains
Now click on the 3 dots next to your domain name and click on configure
We are now going to create a new DNS record, the Name (subdomain) field we leave it empty
Then as Type chose TXT
For the value go back to the search console and copy the google verification string from the verification modal box, then go back to vercel and paste the google-site-verification=xxxxxxx into the value field
The TTL value we use the default 60 seconds, and Priority we leave empty, the comment is optional, I left it empty but if you want you can add one
Now click on add and you are done on vercel, so back to the Google Search Console interface
Now you can click on the Verify button, if it fails just wait one minute and try again, it might take a few minutes before google sees your new DNS entry
Now in the left navigation click on Sitemaps, then enter your sitemap URL (https://example.com/sitemap.xml) and then click on Submit
The Google Search Console documentation says that after the verification, data should start appearing after a few days
Bing Webmaster Tools
Start by visiting the Bing Webmaster Tools website and then click on Get started (or Sign In)
Then you need log in or if you don't have a Microsoft account yet, you will need to create one
After you have signed in, you will need to let the Webmaster Tools access your Microsoft account data, click on Accept
If this is your first domain you will get asked if you want to import your data from the Google Search Console, this is the easiest way to get started, as Bing will reuse your Google Search Console website verification, but if you don't want to link both services you can also pick the Add your site manually option
If you want to add your site manually, either put a file in your public folder and then deploy your project before telling Bing to start the verification or you can add CNAME to the DNS of your domain
As we deployed our website using Vercel, and added our domain in Vercel for the production website, we need to also use the Vercel DNS tool to add the CNAME record
First, visit Vercel.com and then log in
You should now be on the overview page, in the top navigation click on domains
Next, click on the 3 dots next to your domain name and click on configure
We are now going to create a new DNS record, the subdomain field add the Bing hash (the long series of numbers and letters)
Then as Type choose CNAME
For the value insert the verify.bing.com Bing subdomain into the value field
The TTL value we use the default 60 seconds and Priority we leave empty, the comment is optional, I left it empty but if you want you can add one
Now click on add and you are done on vercel, so back to the Bing Webmaster Tools page
On the top right, click on the Submit sitemap button, then enter your sitemap URL (https://example.com/sitemap.xml) and then click on Submit
When this is done, next time you want to re-submit the sitemap, just click on the 3 dots on the right or the sitemap row and select Re-submit
If you want to learn more about the Bing Webmaster Tools then have a look at their documentation
Manifest
You can create one more file besides the sitemap.xml and robots.txt, which is called a manifest.
By using a manifest, you tell the browser how it should display your website when viewed as a progressive web app (PWA). Most browsers support the format, but they use it differently, I recommend having a look at the caniuse manifest pages for up-to-date information about manifest browser support
If you add a manifest file to your project, some browsers will show an icon when someone visits your website. A click on the icon will add your website to their desktop or mobile device. Chrome for desktop for example displays a small icon (a screen with a down arrow) in the address bar next to the bookmark icon:
You can put a static manifest.webmanifest
file into the /app
folder. To create a static manifest you could for example use an online generator or reuse the tool realfavicongenerator.net (we already saw when creating a favicon), as it does not only generate a favicon, the downloaded package will also contain a manifest
If you prefer you can rename the manifest file to something else than manifest.webmanifest
, the specs specify that any name is valid and that the extension needs to be .webmanifest
, there is one exception which the .json extension, you could use manifest.json
as filename like for example, GitHub does: https://github.com/manifest.json
Or you can create a dynamic manifest.ts
file in the /app
folder, which is not only useful when you need it to be dynamic to fetch data, but as the typescript uses the MetadataRoute types you will benefit from code autocomplete for the manifest options
Now, make sure the dev server is running (npm run dev
) and then open http://localhost:3000/
in your browser, then Press F12
or right-click and then select Inspect to have a look at the elements inside of the <head>
You will see that Next.js automatically created the metadata for you:
If you want to have a look at your manifest, open http://localhost:3000/manifest.webmanifest
in your browser
manifest debugging
To debug your manifest file, open the developer tools of your browser and then open the Application tab, then there is a section called Manifest
In Firefox, you will see a preview of your manifest. It is the same in Chrome, but Chrome will also list errors and warnings regarding your manifest file:
Fin
Congratulations 🎉 you made it through all of the pages of this tutorial.
If you have feedback, suggestions or a question, then please use the discussion page and if you found a bug please report it using the issues.