How do Localise and Personalize Content with Sanity.io and Next.js

Rate this content
Bookmark

Structuring your content with Sanity.io means you can query content based on signals from your visitors, such as their location. Personalisation is a tricky problem with static sites and the jamstack, this demo will show you how it can be done with Sanity.io, Next.js, and Vercel.

8 min
25 Oct, 2021

Video Summary and Transcription

Sanity.io provides a content platform for structured content that replaces traditional CMS. Their solution allows businesses to structure and query content anywhere using the Sanity studio and open source React application. The talk focuses on solving the challenge of sending personalized data to users in a static website environment using Next.js Vercel for hosting and Sanity for content querying and delivery. The Sanity studio allows for modeling pages, articles, and banners, with banners being shown to visitors based on their country. The solution involves using Grok queries to fetch the right banner based on country information, demonstrating personalization based on localization and dynamic content querying.

Available in Español

1. Introduction to Sanity and the Problem

Short description:

Hello, I'm Simeon, a solution engineer at sanity.io. We provide a content platform for structured content that replaces traditional CMS. Our solution allows you to structure and query your business's content anywhere, using the sanity studio and open source React application. We work with large companies to leverage the best of the modern web stack. Today, we will solve the challenge of sending personalized data to users in a static website environment. Our solution involves Next.js Vercel for hosting and Sanity for content querying and delivery. Let's explore the solution we've built.

Hello, I'm Simeon, a solution engineer here at sanity.io. Sanity is a content platform for structured content and it replaces the need for a traditional CMS for your website and instead allows you to structure all of your business's content and query that wherever you like. You're able to use the sanity studio and open source React application, which you can host where you like or deploy onto our infrastructure and really set up the best editing experience for your team that makes sense to your workflow and your needs.

We work with a lot of large companies that want to leverage the very best of a modern web stack. Now the problem that we're going to solve today is that before Jamstack took over the entire world, we used to serve websites from servers and those servers contained a lot of information about your visitors as they came to each page. But now that we statically build a lot of pages ahead of time and serve them on globally distributed CDNs, those static files are exactly the same, so how do you send a personalized piece of data to a user based on some information that we have? Well, we've got a solution today that we think's quite tidy. It involves Next.js Vercel for the hosting and Sanity, of course, for the content querying and delivery, but this is an idea that could be worked across many different platforms and serverless function hosts. So let's take a look at the solution as we've built it today.

2. Sanity Studio and Banner Component

Short description:

The Sanity studio allows you to model pages, articles, and banners. Banners are shown to visitors based on their country. The banner component fetches the banner URL using an API route. It sets up state and tracks the date when the banner is seen. The API route checks for country information, allowing manual override or checking headers and IP information.

Here we have the Sanity studio of a fake online candy retailer. Now, your studio might look somewhat different to ours, but this is the one that we've modelled with pages, articles, but most importantly, let's take a look at banners.

Now, these are the banners that we're going to show to visitors as they come to the page, and it's going to depend on what country they're in. I'm in the UK, and so I want to make sure that they get to see this content here. First of all, we've got a dropdown here, which is populated by a list of countries coming from an npm package, and this is the benefit of structured content in JavaScript files, is that it allows you to make near infinitely configurable schema.

Then we've got a string field here for the title, a text field for the content, and an image field where we've pulled in a delightful picture of the UK here from an Unsplash asset source. So that's the banner we want to serve to visitors, and let's take a look at what that's going to look like. I've already visited this page before, so I don't get sent that banner, but if I was to come into a new incognito window, here I get served that banner because this is where I'm at. So how does this work? Let's jump into some code.

We're going to very quickly take a look at this. The concepts here are quite straightforward, and perhaps we'll be able to make this code available as well. But here is the banner component that we're looking at. So you can see at the very top, the get banner URL here is going to fire off to the api route. API routes are a way of running server-side logic on a Next.js website. But again, most JAMstack technologies have similar concepts around running serverless functions to modify pages. And I've built in a fallback here that during development, I can simply set the country in a query string, or otherwise, if I'm in production, go and hit that get banner API route directly.

Now, a banner component here is going to set up some state, and it's also going to track using this sticky state hook, which is all that's doing is making sure we log some information to local storage. And we're going to store the date of when I saw this banner. And it would be possible to extend this component to say, if I haven't seen this banner for, say, 24 hours, it might get served again. So what we're going to do here when the component mounts is first fetch this banner URL. And if the status is not correct, we're going to set that the banner has been seen or if it's empty for whatever reason, we don't want to do that. But if the banner information does get returned properly, then we want to set that into the component and then set that the banner has been seen. And if we have if we don't have any data because we've seen this before or the fetch failed and return no data, then this component does nothing. However, if we do get banner data, then we've got some frame of motion and some tailwind to style that component being loaded into view there with nice animation and styling. So let's have a look at our API route. So as the request comes in to this API route, it is going to check first of all, what country information do we have? First of all, it's going to check, did we manually override this? Perhaps there'd be use cases to manually set the country here. Otherwise, we can check the headers on certain plans. On Vercel, you do get information about the country based on the IP. There are NPM packages as well that allow you to do that. And a lot of other providers will send along that information with requests, such as where the user is.

3. Grok Query for Banner Retrieval

Short description:

If we have country information, we use a Grok query to fetch the right banner. Grok allows powerful and expressive queries. We check for banner documents with the same country field as the variable passed in. The response data is modified to send relevant data, including a reference to the image. This demonstrates personalization based on localization and the ability to dynamically query content based on user behavior.

So again, if we don't have the country, we want to eject from that request. However, if we do have country information, here's our Grok query to be able to go and get the right banner. Grok is the query language that is created for querying data from Sanity. It allows us to do really powerful and expressive queries. And in this case, it's quite straightforward.

We're looking for any document of the type banner, and we're going to check of all the banner documents, which ones have the same country field information as the country variable that we're passing into the query. And you can see there's a function here as well to make sure that we transform both of those to uppercase to help with the matching process in case we get lowercase information or if the document happened to be written in a different way.

The second parameter here in our fetch is that country information that's being passed in as a variable. If there doesn't happen to be a banner for the country that we're visiting from, we'll return nothing, otherwise we return this data. And if we were to take a look at what that response looks like, this is the data that goes back to the component. We can modify this to send less data or more relevant data. You can see here this is all that got sent through. The image is actually loaded by an image building library so we don't have to go and retrieve the entire image information there, but just the reference and then build that image out from there. And that's how we get these banners onto the homepage or any page where we wanted to serve those actually.

So that's sort of scraping the surface of personalization just by using the metric of localization. But it's a demonstration of if you have information about a visitor on the website, say the article they're reading or the articles they've clicked on or what they've spent more time looking at, and your content is then structured to understand those signals, you can then dynamically write queries that takes the signals of your users' behavior and then queries content that's relevant to them. If you'd like to know more, you can come to sanity.io.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

React Summit 2022React Summit 2022
20 min
Routing in React 18 and Beyond
Top Content
Concurrent React and Server Components are changing the way we think about routing, rendering, and fetching in web applications. Next.js recently shared part of its vision to help developers adopt these new React features and take advantage of the benefits they unlock.In this talk, we’ll explore the past, present and future of routing in front-end applications and discuss how new features in React and Next.js can help us architect more performant and feature-rich applications.
React Summit Remote Edition 2021React Summit Remote Edition 2021
43 min
RedwoodJS: The Full-Stack React App Framework of Your Dreams
Top Content
Tired of rebuilding your React-based web framework from scratch for every new project? You're in luck! RedwoodJS is a full-stack web application framework (think Rails but for JS/TS devs) based on React, Apollo GraphQL, and Prisma 2. We do the heavy integration work so you don't have to. We also beautifully integrate Jest and Storybook, and offer built-in solutions for declarative data fetching, authentication, pre-rendering, logging, a11y, and tons more. Deploy to Netlify, Vercel, or go oldschool on AWS or bare metal. In this talk you'll learn about the RedwoodJS architecture, see core features in action, and walk away with a sense of wonder and awe in your heart.
React Summit 2023React Summit 2023
27 min
The New Next.js App Router
Next.js 13.4 recently released the stable version of the "App Router" – a transformative shift for the core of the framework. In this talk, I'll share why we made this change, the key concepts to know, and why I'm excited about the future of React.
React Advanced Conference 2023React Advanced Conference 2023
28 min
A Practical Guide for Migrating to Server Components
Server Components are the hot new thing, but so far much of the discourse around them has been abstract. Let's change that. This talk will focus on the practical side of things, providing a roadmap to navigate the migration journey. Starting from an app using the older Next.js pages router and React Query, we’ll break this journey down into a set of actionable, incremental steps, stopping only when we have something shippable that’s clearly superior to what we began with. We’ll also discuss next steps and strategies for gradually embracing more aspects of this transformative paradigm.
Vue.js London 2023Vue.js London 2023
28 min
A Saga of Web Rendering Woes
This talk will look at the evolution of web rendering modes and what the Jamstack movement is all about. We will build a demo project to show how a static site generator and a Headless CMS can be combined to create dynamic and engaging stories while maintaining a static site's performance and scalability benefits.You will learn about the advantages and limitations of each rendering mode and gain a deeper understanding of how to use Jamstack to build powerful and dynamic storytelling experiences.

Workshops on related topic

React Summit 2022React Summit 2022
173 min
Build a Headless WordPress App with Next.js and WPGraphQL
Top Content
WorkshopFree
In this workshop, you’ll learn how to build a Next.js app that uses Apollo Client to fetch data from a headless WordPress backend and use it to render the pages of your app. You’ll learn when you should consider a headless WordPress architecture, how to turn a WordPress backend into a GraphQL server, how to compose queries using the GraphiQL IDE, how to colocate GraphQL fragments with your components, and more.
React Day Berlin 2022React Day Berlin 2022
53 min
Next.js 13: Data Fetching Strategies
Top Content
WorkshopFree
- Introduction- Prerequisites for the workshop- Fetching strategies: fundamentals- Fetching strategies – hands-on: fetch API, cache (static VS dynamic), revalidate, suspense (parallel data fetching)- Test your build and serve it on Vercel- Future: Server components VS Client components- Workshop easter egg (unrelated to the topic, calling out accessibility)- Wrapping up
React Summit 2023React Summit 2023
139 min
Create a Visually Editable Next.js Website Using React Bricks, With Blog and E-commerce
WorkshopFree
- React Bricks: why we built it, what it is and how it works- Create a free account- Create a new project with Next.js and Tailwind- Explore the directory structure- Anatomy of a Brick- Create a new Brick (Text-Image)- Add a title and description with RichText visual editing- Add an Image with visual editing- Add Sidebar controls to edit props (padding and image side)- Nesting Bricks using the Repeater component- Create an Image gallery brick- Publish on Netlify or Vercel- Page Types and Custom fields- Access Page meta values- Internationalization- How to reuse content across pages: Stories and Embeds- How to create an E-commerce with Products’ data from an external database and landing pages created visually in React Bricks- Advanced enterprise features: flexible permissions, locked structure, custom visual components
React Summit 2023React Summit 2023
71 min
Building Blazing-Fast Websites with Next.js and Sanity.io
WorkshopFree
Join us for a hands-on workshop where we'll show you how to level up your React skills to build a high-performance headless website using Next.js, Sanity, and the JAMstack architecture. No prior knowledge of Next.js or Sanity is required, making this workshop ideal for anyone familiar with React who wants to learn more about building dynamic, responsive websites.
In this workshop, we'll explore how Next.js, a React-based framework, can be used to build a static website with server-side rendering and dynamic routing. You'll learn how to use Sanity as a headless CMS to manage your website’s content, create custom page templates with Next.js, use APIs to integrate with the CMS, and deploy your website to production with Vercel.
By the end of this workshop, you will have a solid understanding of how Next.js and Sanity.io can be used together to create a high-performance, scalable, and flexible website.
GraphQL Galaxy 2021GraphQL Galaxy 2021
161 min
Full Stack GraphQL In The Cloud With Neo4j Aura, Next.js, & Vercel
WorkshopFree
In this workshop we will build and deploy a full stack GraphQL application using Next.js, Neo4j, and Vercel. Using a knowledge graph of news articles we will first build a GraphQL API using Next.js API routes and the Neo4j GraphQL Library. Next, we focus on the front-end, exploring how to use GraphQL for data fetching with a Next.js application. Lastly, we explore how to add personalization and content recommendation in our GraphQL API to serve relevant articles to our users, then deploy our application to the cloud using Vercel and Neo4j Aura.

Table of contents:
- Next.js overview and getting started with Next.js
- API Routes with Next.js & building a GraphQL API
- Using the Neo4j GraphQL Library
- Working with Apollo Client and GraphQL data fetching in Next.js
- Deploying with Vercel and Neo4j Aura
React Summit 2022React Summit 2022
50 min
High-performance Next.js
Workshop
Next.js is a compelling framework that makes many tasks effortless by providing many out-of-the-box solutions. But as soon as our app needs to scale, it is essential to maintain high performance without compromising maintenance and server costs. In this workshop, we will see how to analyze Next.js performances, resources usage, how to scale it, and how to make the right decisions while writing the application architecture.