Randomizing pages titles (and having good SEO)
Tags: webdev, nextjs, tutorial, design
Published: 2024-02-20 18:47:37

I recently implemented a new feature on my [portfolio website](aneshodza.ch) where the website randomizes its title every time its refreshed.
An example of that:

![Gif of the changing page titles](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qbfw48cmfrrgmgnx3ay8.gif)

This article is about how I implemented this (with code examples in NextJS) and how I fixed my SEO.

### Why would you need to fix your SEO?

The issue with the changing page titles is simple: Every time the google crawler goes onto your website he sees a different title that gets indexed, changing it in the search results.
That can mess with your SEO, as something like "[Your Name]'s personal website" is much better for finding the website than "Ran on my machine".

## Implementing the titles
This tutorial on how to implement it will be in NextJS, but you can follow along in every language, as it shouldn't change depending on the language.

### Setting the title for the Google crawler
First you want to go on your `_document.jsx`, or inside of any layout page that you have, like `application.html.erb` if you're implementing this in Rails. There you want to set the boring title, or the one that should get indexed. In addition to that you want to set the meta description and your favicon:
```
// NextJS code example
<Head>
  <meta
    name="description"
    content="I need to make the computer overlord happy, so: Anes Hodza made this! This is Anes Hodzas' digital property!"
  />
  <link rel="icon" href="/favicon.ico" />
  <title>Anes Hodzas' personal website</title>
</Head>
```

### Creating the custom titles
Then you want to go to your `index` page (the one that gets shown on `/`).
There you want to create a `const` array with all your titles as strings:
```
const titles = [
  'Ran on my machine',
  'Web developer? I think?',
  'Engineer is an overstatement',
  'I\'m testing this in prod',
  'Does anyone read these?',
  'I\'m not a robot',
  'http://localhost:3000',
  'I don\'t use arch, btw'
]
```
In the case of something like Rails, where the backend logic is somewhat separated from the html code, you would probably put this in the controller.

### Sending the user your custom titles
It's very important that the changing page titles are handled in the backend, as otherwise Google starts indexing your webpage weirdly.
In the case of NextJS you would want to create a `getServerSideProps` function:
```
export async function getServerSideProps(context) {
  // ...
}
```
Now in there we want to pick the title randomly and return it as a `prop`:
```
export async function getServerSideProps(context) {
  const index = Math.floor(Math.random() * titles.length);
  let title = titles[index];

  return {
    props: {
      index,
      title
    }
  }
}
```
Now if you start refreshing your page you should see that the title changes.

### Fixing Google SEO again, because it's better to be safe than sorry
The Google crawler for some reason sometimes still indexes a random title, so we will also have to change that in the server-side function. What we do first is define a function that checks if the `useragent` is any google crawler. That we can do as follows:
```
const isGooglebot = (userAgent) => {
  return /(googlebot|google-inspectiontool\/1\.0)/i.test(userAgent);
};
```
Why not just match any occurrence of Google you might ask. It's just a precaution in case Chrome decides to adapt the word Google into its user agent string.

And now you also have to call the function and return your wanted title in case its the crawler:
```
export async function getServerSideProps(context) {
  const index = Math.floor(Math.random() * titles.length);
  let title = titles[index];

  let userAgent = context.req.headers['user-agent'] || '';

  if (isGooglebot(userAgent)) {
    title = "Anes Hodzas' personal website"
  }

  return {
    props: {
      index,
      title
    }
  }
}
```
And after waiting for Google to index your website again, you should be good to go!

## Won't this get marked as cloaking?

I had this feature on for two weeks by now and there wasn't any indication of it being marked as cloaking:

![Picture of my website being show in the google search results](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hnth33i1a85htq2j0jqu.png)

In case anything happens, I'll keep you updated!