Your First Website with Sanity CMS: A Beginner's Step-by-Step Guide to Building and SEO

date
March 17, 2026
category
Web Design
Reading time
8 Minutes

So, you want to build a website. Not just any website, but one that you can actually update without having to beg a developer every time you want to change a sentence or add a photo. You've probably heard the term "CMS" (Content Management System) thrown around. Think of it as the command center for your website's content.

Today, we're diving into Sanity.io. It's what's known as a "headless CMS." That sounds complicated, but here's the simple truth: instead of your website's content and the way it looks being welded together (like in WordPress), a headless CMS keeps them separate. This gives you incredible power and flexibility . You manage your content in a beautiful, easy-to-use editing room called the Sanity Studio, and then you, or a developer, can display that content anywhere—on a website, an app, or anything else .

Think of it like this: Sanity is the backstage area where all your props and scripts are organized, and your website is the stage where the performance happens. They are connected, but changing a script doesn't collapse the stage.

In this guide, we'll build your first website using Sanity and Next.js, a popular framework from Vercel that's a match made in heaven for this kind of project . We'll also lay the groundwork for SEO right from the start, because what's the point of a beautiful site if no one can find it?

Let's get started. We're going to build something you can be proud of.

Step 1: Setting Up Your Content Command Center (Sanity Studio)

This is where you'll spend your time writing blogs, creating pages, and uploading images. Let's get it set up.

1.1. Create Your Account

First, head over to manage.sanity.io and create a free account. You can sign in with Google, GitHub, or your email .

1.2. Install the Sanity CLI (Command Line Interface)

Don't let the name scare you. This is just a tool that lets you talk to Sanity from your computer's terminal. Open your terminal (Mac) or command prompt (Windows) and run this command:

bash

npm install -g @sanity/cli

This installs it globally on your computer, meaning you only have to do it once .

1.3. Initialize Your First Project

Now, let's create a folder for your project and set up Sanity inside it.

  1. In your terminal, type: mkdir my-awesome-website && cd my-awesome-website
  2. Then, type: sanity init
  3. The CLI will guide you through a setup wizard:
    • Login: It'll ask you to log in through your browser. Do that.
    • Create new project: Select "Create new project" and give it a name, like "My First Sanity Site" .
    • Use default dataset configuration: Say Yes. A dataset is just a place to store your content. "Production" is the standard name .
    • Project output path: Just press Enter to accept the default (the current folder).
    • Select project template: Here, choose "Blog (schema)" . This gives us a ready-made structure for blog posts and authors, which is perfect for learning .
    • Use TypeScript? You can say No for now to keep things simpler, but if you're feeling adventurous, TypeScript is a great way to catch errors .

And just like that, you have a fully functional CMS backend! You'll see a new folder called studio (or similar) inside your project.

1.4. Run Your Studio Locally

Let's see your new command center. In the terminal, navigate into the studio folder and start it up:

bash

cd studiosanity dev

This will open up http://localhost:3333 in your browser. This is your Sanity Studio! Go ahead, click on "Post" and create your first blog post. Give it a title, some content, and hit "Publish" . You're now a content creator!

Step 2: Bringing Your Website to Life (The Frontend with Next.js)

Your content is safe and sound in Sanity. Now, let's build the "stage"—the website your visitors will actually see. We'll use Next.js.

2.1. Create Your Next.js App

Open a new terminal window. Don't close the one running your studio! We'll create your website in a separate folder alongside your studio folder.

  1. Navigate back to your main project folder. If you're inside the studio folder, type cd .. to go back.
  2. Run the Next.js creation command:

bash

npx create-next-app@latest frontend

  1. You'll be asked a few questions:
    • Would you like to use TypeScript? No for now (we're keeping it simple).
    • Would you like to use ESLint? Yes.
    • Would you like to use Tailwind CSS? If you want some pre-made styles, say Yes. It's popular and easy.
    • Would you like to use src/ directory? No.
    • Would you like to use App Router? Yes! This is the modern way to build Next.js apps.
    • Would you like to customize the default import alias? No.

Once it's done, navigate into your new frontend folder:

bash

cd frontend

2.2. Connect Next.js to Sanity

Now for the magic—connecting your new website to your content.

  1. Install the Sanity client for Next.js:

bash

npm install @sanity/client @sanity/image-url

  1. @sanity/client is what we use to fetch data, and @sanity/image-url helps us handle images .
  2. Create a Sanity Client File: Inside your frontend folder, create a new folder called lib. Inside that, create a file called sanity.js. This will be our connection file.
  3. Add the Connection Code: Open frontend/lib/sanity.js and paste this in. You'll need two pieces of information from your Sanity project: your Project ID and the dataset name.
    • Go back to your Sanity Studio (http://localhost:3333).
    • Click on the gear icon (Settings) in the top left, or go to manage.sanity.io and find your project.
    • You'll see your Project ID (a string like abc123de) and your Dataset name (probably production).
    javascript// frontend/lib/sanity.jsimport { createClient } from '@sanity/client'import imageUrlBuilder from '@sanity/image-url'export const client = createClient({  projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID, // we'll set this next  dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,  useCdn: true, // set to false if you want fresh data on every request  apiVersion: '2024-01-01', // use a UTC date string})const builder = imageUrlBuilder(client)export function urlFor(source) {  return builder.image(source)}
  4. Set up Environment Variables: To keep your Project ID secure, we'll use environment variables. Create a file in your frontend folder called .env.local. Add these lines, replacing the placeholders with your actual info:

text

NEXT_PUBLIC_SANITY_PROJECT_ID=your_project_id_hereNEXT_PUBLIC_SANITY_DATASET=production

  1. Restart your Next.js server (npm run dev) after creating this file.

2.3. Create a Simple Page to List Blog Posts

Let's prove the connection works by listing your blog posts on the homepage.

  1. Open frontend/app/page.js. Delete all the default code.
  2. Replace it with this:

javascript

// frontend/app/page.jsimport { client } from '@/lib/sanity'async function getPosts() {  const query = `*[_type == "post"] | order(publishedAt desc){    title,    slug,    publishedAt,    body  }`  const posts = await client.fetch(query)  return posts}export default async function Home() {  const posts = await getPosts()  return (    <main>      <h1>My Awesome Blog</h1>      {posts.map((post) => (        <div key={post.slug.current}>          <h2>{post.title}</h2>          {/* We'll link to the full post later */}        </div>      ))}    </main>  )}

  1. This code uses a GROQ query (Sanity's query language) to ask for all posts, and asks for their title and slug . It then lists them on the page. Go to http://localhost:3000 and you should see your blog post title!

Step 3: Building SEO Best Practices into Your Content

This is where we make sure Google can not only find your site but also understand it and show it to the right people. We'll build SEO right into your content model .

3.1. The SEO Object: Your Secret Weapon

Instead of having SEO fields scattered everywhere, we create a single, reusable "object" in Sanity. This is the core of a great SEO strategy .

  1. Stop your Sanity studio server (where you ran sanity dev) with Ctrl+C.
  2. Navigate to your studio/schemaTypes folder.
  3. Create a new file called seo.js.
  4. Paste this in:

javascript

// studio/schemaTypes/seo.jsimport { defineField, defineType } from 'sanity'export default defineType({  name: 'seo',  title: 'SEO',  type: 'object',  fields: [    defineField({      name: 'metaTitle',      title: 'Meta Title',      type: 'string',      description: 'Title for search engines (recommended length: 50-60 characters)',      validation: Rule => Rule.max(60).warning('Should be under 60 characters')    }),    defineField({      name: 'metaDescription',      title: 'Meta Description',      type: 'text',      rows: 3,      description: 'Description for search engines (recommended length: 150-160 characters)',      validation: Rule => Rule.max(160).warning('Should be under 160 characters')    }),    defineField({      name: 'noindex',      title: 'Hide from search engines',      type: 'boolean',      description: 'Check this if you do NOT want this page to appear in search results.',      initialValue: false    }),  ]})

  1. This creates a structured field with validation to keep your titles and descriptions from being cut off in search results .

3.2. Add the SEO Object to Your Blog Post

Now, let's add this new SEO object to your blog post schema.

  1. Open studio/schemaTypes/post.js.
  2. At the top, import your new SEO object: import seo from './seo'
  3. Inside the fields array, add the SEO object as a field. Your fields might now look something like this:

javascript

// ... inside post.jsfields: [  // ... other fields like title, slug, etc. ...  defineField({    name: 'title',    title: 'Title',    type: 'string',  }),  defineField({    name: 'seo',    title: 'SEO',    type: 'seo', // This references the object we just made  }),  // ... more fields ...],

  1. Restart your Sanity studio (sanity dev). Now, when you edit a post, you'll have a neat "SEO" section where you can fill in your meta title and description.

3.3. Display SEO Metadata in Your Next.js Site

Finally, we need to tell your Next.js site to use this new SEO information. We'll update our blog post page to use these fields in the <head> of the document.

  1. First, create the dynamic page to show a single blog post. In frontend/app, create a new folder called blog. Inside that, create a file called [slug]/page.js. The brackets make it dynamic .
  2. Add this code to frontend/app/blog/[slug]/page.js:

javascript

// frontend/app/blog/[slug]/page.jsimport { client } from '@/lib/sanity'async function getPost(slug) {  const query = `*[_type == "post" && slug.current == $slug][0]{    title,    body,    "seo": seo {      metaTitle,      metaDescription,      noindex    }  }`  const post = await client.fetch(query, { slug })  return post}export async function generateMetadata({ params }) {  const post = await getPost(params.slug)  // Use SEO fields if they exist, otherwise fall back to the post title  return {    title: post?.seo?.metaTitle || post?.title || 'Blog Post',    description: post?.seo?.metaDescription || 'Read this blog post',    robots: post?.seo?.noindex ? 'noindex' : 'index',  }}export default async function BlogPost({ params }) {  const post = await getPost(params.slug)  return (    <article>      <h1>{post.title}</h1>      <div>{/* Render your post body here */}</div>    </article>  )}

  1. The magic happens in generateMetadata. Next.js automatically takes the metadata we return and puts it in the <head> of the page, giving you perfect, per-post SEO control .

Step 4: Advanced (But Important!) SEO Tactics

For a truly findable site, you need a few more things. These are tactics that the best websites use .

  • Generate a Sitemap (for Google): A sitemap is a file that lists all the important pages on your site. You should build one dynamically. In Next.js App Router, you can create a sitemap.js file in your app folder. Inside, you'd write a function that uses the Sanity client to fetch all your post slugs and page slugs, then formats them into an XML sitemap for search engines .
  • Optimize Your Images: Sanity has a powerful image CDN. Always use the urlFor function we set up earlier to transform your images on the fly—resize them, change their format to modern webp, and adjust quality. And never forget alt text. Add an alt field to your image schemas in Sanity so your content editors can write descriptive text, which is crucial for accessibility and image search .
  • Internal Linking with Guardrails: When you link to another page on your site, use Sanity's "reference" type. This creates a connection between documents. The huge SEO benefit? If you ever change a URL slug, Sanity can automatically update every internal link pointing to it, preventing broken links and the SEO loss that comes with them .

Step 5: Launching Your Site to the World (Deployment)

Your site works on your computer. Now, let's put it on the internet. We'll use Vercel, the company that made Next.js, because it's incredibly easy.

  1. Push Your Code to GitHub:
    • Create a repository on GitHub.
    • In your terminal, from your main project folder, run:
    • bashgit initgit add .git commit -m "Initial commit"git branch -M maingit remote add origin https://github.com/your-username/your-repo-name.gitgit push -u origin main
    • (Replace the URL with your actual GitHub repo URL.)
  2. Import to Vercel:
    • Go to vercel.com and sign up with your GitHub account.
    • Click "Add New..." and then "Project".
    • Import the GitHub repository you just pushed.
    • Vercel will automatically detect that it's a Next.js project.
  3. Add Environment Variables:
    • In the Vercel project configuration screen, look for "Environment Variables".
    • Add the same two variables we put in your .env.local file: NEXT_PUBLIC_SANITY_PROJECT_ID and NEXT_PUBLIC_SANITY_DATASET with their values.
    • Click "Deploy".
  4. Add Your Live Site to Sanity CORS:
    Your deployed site needs permission to talk to Sanity.
    • Go back to manage.sanity.io, find your project, and go to the API tab.
    • Under CORS Origins, click "Add CORS origin".
    • Enter your new Vercel deployment URL (e.g., https://your-site.vercel.app). You can leave the "Allow credentials" checkbox unchecked for now .
    • Click "Save".

Once the deploy finishes, Vercel will give you a live URL. Visit it. That's your website, live on the internet, powered by your content from Sanity.

Conclusion: You Did It!

Congratulations! You've just built a modern, scalable, and SEO-friendly website. You're no longer just a consumer of the web; you're a creator.

You've taken a huge step. You set up a flexible CMS, connected it to a powerful frontend, and built a solid SEO foundation that many developers overlook. From here, the possibilities are endless. You can create new page types, add more complex components to your Sanity Studio, and fine-tune your site's design.

The web is yours. Go build something awesome.

Nutriwin whatsapp chat header
SAMI HARAKETI
Respond within a few hours.
Whatsapp Logo
Start a WhatsApp chat