Incorporating Sanity into a Next.js template with Tailwind and MDX
No worries about the greeting, and welcome to the community! You're actually in a pretty common situation – retrofitting a CMS into an existing template is definitely doable, and you're thinking about it the right way.
Yes, you'll be "reverse engineering" the content model from your template, but that's totally normal! Here's how I'd approach integrating Sanity with your Next.js 14 + MDX template:
Step 1: Identify Your Content Types
Look through your MDX files and template structure to identify distinct content types. For example:
- Blog posts (probably have title, date, author, body content)
- Pages (about, services, etc.)
- Case studies or portfolio items
- Any repeated data structures
Step 2: Set Up Sanity with Next.js 14
Since you're on Next.js 14 (which supports the App Router), you'll want to:
- Initialize Sanity: Run
npm create sanity@latestin your project (you can initialize it in a subfolder like/sanity) - Install the integration package:
npm install next-sanity @sanity/image-url - Set up the Sanity client to fetch data in your Next.js app
The Visual Editing with Next.js App Router guide has excellent step-by-step instructions for this exact setup.
Step 3: Create Schemas Based on Your MDX Structure
For each MDX file type, create a corresponding schema in Sanity. For example, if your blog posts have frontmatter like:
--- title: "My Post" date: "2024-01-15" author: "John" ---
You'd create a schema like:
defineType({
name: 'post',
type: 'document',
fields: [
{ name: 'title', type: 'string' },
{ name: 'date', type: 'datetime' },
{ name: 'author', type: 'string' },
{ name: 'body', type: 'array', of: [{type: 'block'}] }
]
})Step 4: Handle the MDX → Portable Text Transition
This is the trickiest part. Sanity uses Portable Text instead of MDX. You have a few options:
Option A (Recommended): Use Sanity's Portable Text for rich content going forward. It's more structured and gives you better control. You can still embed custom components using custom block types.
Option B: Keep using MDX by storing it as a text field in Sanity, though you lose some of the benefits of structured content.
Option C: Use a markdown field type from the community if you want to keep markdown but still use Sanity.
Step 5: Keep Your Animations & Styling
The good news: your Framer Motion animations and Tailwind styling stay exactly as they are! You're just swapping where the content comes from (MDX files → Sanity API).
Step 6: Fetch Data in Your Components
Your Next.js page components would change from:
// Before: importing MDX
import content from './content.mdx'To:
// After: fetching from Sanity
import { client } from '@/sanity/lib/client'
const post = await client.fetch(`*[_type == "post"][0]`)Optional: Set Up Live Preview
Since you're on Next.js 14, you can set up live preview so editors can see changes in real-time. With the new Live Content API, this is much simpler than before – no websockets needed.
Bottom Line
You're not going about it backwards at all! Many people start with templates and add a CMS later. The key is mapping your existing content structure to Sanity schemas, which gives you a much better editing experience going forward.
I'd recommend starting with one content type (like blog posts) to get the pattern down, then expanding from there. Check out the Stablo template – it's actually a Next.js + Tailwind + Sanity blog template that might give you some good reference patterns for your setup!
Sanity – Build the way you think, not the way your CMS thinks
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.