24 January 2021

Create a Breadcrumb Component With React and TypeScript

A breadcrumb trail on a webpage indicates where the user is currently located in the website hierarchy. It can help a user to better understand and explore the website effectively. A breadcrumb allows the user to navigate all the way up in the hierarchy of the website one level at a time. This articles explores how to easily implement a breadcrumb in React and Typescript in less than fifty lines of code.

The goal of creating a breadcrumb is twofold. The breadcrumb provides users with an easy way to navigate the structure of the website. Furthermore a correct implementation will enrich the search results of search engines. The latter is done by providing structured data for search engines.

Structured Data

First things first, let's take a deeper dive into the structured data. Search engines do their best to parse and understand the structure of the websites that they crawl. But they have limited understanding of what is discussed on specific webpages.

Structured data provides the search engine with additional information about the content of a webpage. There are various types of structured data. Information about recipes, books, reviews, articles and many more can be more added to a webpage.

Schema.org provides a shared vocabulary for structured data that is supported by Google, Microsoft, Yahoo and Yandex. Not all schemas result in an augmented search experience for the end user.

Which schemas help your website display richer features in search results can be found at the search gallery of Google. A breadcrumb is one example of the schemas that display navigation that indicates the page's position in the site hierarchy in the search results.

There are multiple formats to include structured data on your webpage. Most notably JSON-LD and Microdata. With JSON-LD the data is included in a script tag. In contrast Microdata nests the metadata in the existing content of the page. With this format HTML attributes are used to embed simple machine-readable data on webpages.

Microdata is used in this article because it reduces the amount of code needed. With the same code the goal of helping the user and the search engine is reached, essential killing two birds with one stone.

Microdata

Microdata is a HTML standard. In essence microdata consists of a group of name-value pairs. Each group is called an item. The specific name-value pairs describe the properties of an item.

To specify an item the itemscope attribute is added to an element. When this attribute is added you are declaring that the HTML contained inside that element is about a certain item.

Items have certain a type. This is specified by the itemtype attribute. Item types are provided as an URL to the schema.org website.

Additional information about an item is defined in its properties. These are declared by adding one or multiple itemprop attributes to an element. These attributes are attached to the nested elements of the item. The properties are either a string or a URL. The latter is generally expressed using the <a> element and its href attribute.

...waiting for Gist...

Above an example for microdata about a movie is provided. The outer div defines the movie item by setting the itemscope attribute and its itemtype to http://schema.org/Movie. The nested elements of this div element all describe certain properties of the movie. What they describe is set using the itemprop attribute.

This is a fairly straightforward example. However sometimes the value of an item property can itself be another item with its own set of properties. This is illustrated in the next section.

Markup

On Google Search Central a microdate breadcrumb example can be found. An ordered list with list elements is used. The list elements are visually separated with the > character.

...waiting for Gist...

The outer <ol> tag defines a microdata item called BreadcrumbList. The precise properties of this type can be found here. The list contains three elements which each describe an itemListElement, which is a property of BreadcrumbList.

In the last section it was noted that sometimes the value of an item property can itself be another item with its own set of properties. This is the case for the properties of the BreadcrumbList. The list elements are an item in itself, namely a ListItem.

Three properties of ListItem can be observed. The url, denoted by the item property, the name and the position of the element. Please note that the the position begins with one instead of zero.

Function component and props

Now let's start to think in React components and the data that would be needed in a component rendering the above markup. The variables are known, therefore creating type definitions for the properties of the component is relatively simple.

...waiting for Gist...

The data that is passed to the component is an array of breadcrumb elements, each with an url and name, which are both strings. Let's break the user interface into a component hierachy for React.

Repeating elements in the markup of the last section can be spotted: a list of items. This is implemented with two functional components, one for the Breadcrumb itself and one for the elements in it: BreadcrumbItem.

The Breadcrumb functional component receives the BreadcrumbProps as argument. The component can be implemented as:

...waiting for Gist...

The list is wrapped in a nav tag, because the content defines a block of navigation links. Class names are added using a BEM methodology to allow for styling later on. The rest of the markup is exactly as the example shown above. One thing to note is that the attributes are in camelCase, as is expected for all DOM properties in React.

The array of breadcrumb items that is passed is rendered using the map function, which maps the BreadcrumbItem type to the BreadcrumbItem component.

The BreadcrumbItem component expects four variables: the url, the name, the index and a boolean variable called isLast. The first two are provided by the properties of the element in the array, using the spread syntax. The position property is passed by adding one to the index of the current element being processed in the array.

If a BreadcrumbItem is the last element in a list, no visual separator should be rendered. Therefore the components needs to know whether or not it is the last item. This is by done by checking if the index of the current item in the map function equals the length of the array.

Last but not least a key attribute is added, this is not a property that is passed to the component itself. Keys are internal to React. It helps React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity.

The BreadcrumbItem can be implemented as follows:

...waiting for Gist...

The isLast parameter is used to conditionally render the divider. When the divider is shown, the component will return multiple DOM elements, therefore it is wrapped in a Fragment. Fragments let you group a list of children without adding extra nodes to the DOM.

Validation for rich results

The breadcrumb can now be rendered as follows:

...waiting for Gist...

The breadcrumb variable is an object that adheres to the BreadcrumbProps interface. There are a multitude of ways to obtain this object. It can be defined in a file on your server or you can receive it from a backend etc. For demonstrative purposes it is hard coded in a constant variable.

This component renders the following html:

...waiting for Gist...

The rendered HTML can be validated using the Rich Results Test from Google. The code can be pasted there and it will show that the page is eligible for rich results. The functionality of the breadcrumb is done.

The only thing that is left is to style the breadcrumb. This will be left as an exercise for the reader, because there are a plethora of ways to approach this. With the many methods out there the styling will vary wildly depending on the situation.

Conclusion

This article has shown an easy way to implement breadcrumb structured data using Microdata. I encourage the reader to explore the other available schemas that you can use to enrich the search results of your webpage.

When you have found more schemas that you want to implement, you can have a look at React Schemaorg, which provides two npm packages. One provides TypeScript definitions for the Schema.org vocabulary in JSON-LD format, so you don't have to do this yourself. Whereas the other one provides a way to easily insert valid Schema.org JSON-LD in your React apps.


Share article