Table of Contents
- New Content Types - Graphql Files
- Videotutorial creation Navitem Content Type
- Videotutorial creation NavItemGroup Content Type
- Videotutorial creation FooterItemGroup Content Type
- New NPM Packages
- Deeper Look in the Code
- List of all changed & added files
- Changes at tailwind.config.ts
- Enabling Contentful Draft Mode - Preview
- Configuration Content Preview Contentful
- GitHub Repo
In Part 1 we created the foundation of our Next.js 14 project. In Part 2 we created the frontend with Contentful as headless CMS, Tailwindcss for styling, and Typescript for the coding. Now we have reached part 3 and we will add a header and a footer component, as well as the so-called draft/preview functionality offered by Contentful. Not to forget the nowadays mandatory dark mode toggle. Here is already a spoiler to the final result -> Create Cloudapp.dev Example App
New Content Types - Graphql Files
We start with the creation of our new Content Types: Nav Item NavitemGroup FooterItemGroup

Since we have new Content-Types we must create the corresponding graphql-files under src/lib/graphql

With the new graphql-files in place we can launch the sync command
Which updates three files in the folder src/lib/__generated
sdk.ts graphql.schema.json graphql.schema.graphql
Let’s take a look at navItemFields.graphql. As you can see in the screenshot below, we have two fields in the Content-Type “Nav Item” and these two fields are represented in the graphql file.
Videotutorial creation Navitem Content Type
We reuse this fragment in the other files (navitemgroup.graphql)
Videotutorial creation NavItemGroup Content Type
Videotutorial creation FooterItemGroup Content Type
New NPM Packages
Now we are ready for the installation of three new NPM packages
We can now add the new components

In the header.component.tsx we receive the “menuItems” as props from layout.tsx and then we send them to the component “Navbar”.
Deeper Look in the Code
Let’s do a short deep dive into layout.tsx (src/app/layout.tsx)
On the top, we import these components for the new parts
and the “Providers” component for the dark mode handling.
Below I point out the return part of the src/app/layout.tsx, where we can see, that we wrapped the header, footer, and {children} into the <Providers></Providers> component, which allows us to use the dark mode toggle on every page.
Under {Providers} we import the data for Header/Footer.
getAllNavitemsForHome in Detail
which fetches the data via graphql query from Contentful. client.navItemGroup uses the graphql query specified in src/lib/graphql/navitemgroup.graphql
Because we reuse the same nav items in the header and the footer we defined them only once in graphql.
List of all changed & added files
Here is a complete list of all changed/added files in Part 3 of the tutorial. All files in the folder src/lib/__generated are generated by the command “npm run graphql-codegen:generate” mentioned at the beginning.

Changes at tailwind.config.ts
The tailwind.config.ts had a small modification as well. We added line 4 and line 27
With this change, we added the extra color “emerald”, which we used on line 34 (layout.tsx), within our draft mode banner
Enabling Contentful Draft Mode - Preview

To enable draft/preview mode we modified these pages and components

and we added these two routes

I added this import
and this constant and I reused the const for the graphql-query (example shows a code piece of src/app/page.tsx
above I used “client.pageBlogPost” with two params “slug” and “preview”. Slug for filtering (slug is defined as a unique field in Contentful), while preview is used to get the data for content records in “draft” status, which we need for the preview.
Configuration Content Preview Contentful
As a last step, we set up the “Content Preview” within Contentful.


We have to define three fields:
Name -> I used “Preview”
Select content types -> I selected “page — Blog post”
Url -> https://nextjs14-full-example-header-footer.vercel.app/api/draft?previewSecret=xxxxxxxxxxxxxx&redirect=/{entry.fields.slug} (use the value from the env variable -> CONTENTFUL_PREVIEW_SECRET)

Now let’s open “TestBlogPost3” in Contentful and click on the button “Open Live Preview” on the right side.

And here is the preview (to test it, modify the Title field on the left side (1) and then click on refresh (2) and you will see the draft mode banner and the change (3))

GitHub Repo
Here is the full code in the corresponding GitHub branch -> GitHub - cloudapp-dev/nextjs14-typescript-app-router-contentful at nextjs14-part3
where you also find the updated export.json file (folder “contentfulsync”), which you can use to import the data to contentful
Stay tuned for the next posts where we will add new functions like an Azure Entra ID (formerly Azure AD B2C) for identity management Algolia as an On-Site Search Engine and a lot more.
If you like what you see, then please support me with a clap or follow me on medium.com.