Roy Cheng
2 min readOct 29, 2021

--

Unit testing the meta tags rendered by next/head component

When it comes to SEO, Next.js has a very handy <Head /> component for you to add the <meta /> or<link/> tags. E.g. Specifying a canonical URL to the page.

I’ve recently used it to add a self-referencing canonical URL and a robots meta tag to block the crawler in one of our projects. It could be easily added from your _app.tsx. But unit testing for the children rendered by next/head is not so straightforward because it always render an empty <head /> after executing the React testing library’s render function.

After some looking around, I stumble upon this github issue, which suggested a workaround involving Next.js’s HeadManagerContext. It’s not ideal but it gets the job done.

import { render } from "@testing-library/react";
import { useEffect } from "react";
import ReactDOMServer from "react-dom/server";import { HeadManagerContext } from "next/dist/next-server/lib/head-manager-context";const HeadProvider: React.FC = ({ children }) => {let head: JSX.Element[];useEffect(() => {global.document.head.insertAdjacentHTML("afterbegin",ReactDOMServer.renderToString(<>{head}</>) || "",);});return (<HeadManagerContext.Providervalue={{updateHead: (state) => {head = state;},mountedInstances: new Set(),}}>{children}</HeadManagerContext.Provider>);};const renderHead = (): HTMLHeadElement => {const tree = render(<MySeoHead />, { wrapper: HeadProvider });return tree.baseElement.parentElement?.firstChild as HTMLHeadElement;};describe("Head", () => {
it("renders the meta tag, async () => {
const head = renderHead(); expect(head.querySelector("meta[name=robots]")?.attributes.getNamedItem("content")?.value,).toBe("noindex,nofollow"); });});

One thing to watch out for is that the location of the HeadManagerContext. Depending on which Next.js you use, it is located at “next/dist/next-server/lib/head-manager-context” for v10. However it has been relocated to “next/dist/shared/lib/head-manager-context” for v11. This could be the cause if you get “Cannot find module ‘next/dist/next-server/lib/head-manager-context’ error” after upgrading to Next.js v11.

--

--