Cultivate Your Mind: Build a Digital Garden for Mental Health with Next.js & MDX
Learn how to build a personal, searchable digital garden for your mental health notes using Next.js and MDX. A step-by-step tutorial for creating a space for reflection and growth.
On this page
In our fast-paced world, finding a quiet space for reflection is more important than ever. A "digital garden" is a unique approach to personal knowledge management—it's less of a chronological blog and more of a living, evolving space for your thoughts, learnings, and reflections. Unlike a traditional blog, a digital garden is a perpetual work in progress, allowing for interconnected ideas to grow over time.
This tutorial will guide you through building a digital garden specifically for your mental health notes using Next.js and MDX. We'll create a private, serene online space where you can document your journey, connect your thoughts, and cultivate a deeper understanding of yourself.
Prerequisites:
- Basic understanding of React and JavaScript.
- Node.js and npm (or yarn) installed on your machine.
- A code editor like VS Code.
Understanding the Problem: Beyond Traditional Note-Taking
Standard note-taking apps can be rigid and linear. For mental health, our thoughts are often interconnected and don't fit neatly into a timeline. A digital garden approach, with its emphasis on non-linear connections and personal growth, offers a more intuitive way to manage this kind of personal information.
By using Next.js, we get a powerful and fast framework for building our garden. MDX (Markdown with JSX) is the real game-changer here, allowing us to embed interactive React components directly into our notes for a richer, more dynamic experience.
Prerequisites: Setting Up Your Digital Greenhouse
First, let's get our project set up. Open your terminal and run:
npx create-next-app@latest mental-health-garden
Follow the prompts, choosing TypeScript and Tailwind CSS for this project.
Once the installation is complete, navigate into your new project directory:
cd mental-health-garden
Next, we'll install the necessary packages to work with MDX:
npm install @next/mdx @mdx-js/loader @mdx-js/react gray-matter
Now, let's configure Next.js to recognize MDX files. Create a next.config.mjs file in your project's root and add the following:
// next.config.mjs
import createMDX from '@next/mdx'
/** @type {import('next').NextConfig} */
const nextConfig = {
pageExtensions: ['js', 'jsx', 'md', 'mdx', 'ts', 'tsx'],
}
const withMDX = createMDX({
// Add markdown plugins here, as desired
})
export default withMDX(nextConfig)
This tells Next.js to treat .mdx files as pages.
Step 1: Planting Your First Seeds (Creating MDX Notes)
What we're doing
We'll create a directory to store our mental health notes as MDX files. Each file will contain some content and "frontmatter" (metadata like title, date, and tags).
Implementation
- Create a
notesdirectory at the root of your project. - Inside the
notesdirectory, create your first note, for example:first-reflection.mdx. - Add the following content to
first-reflection.mdx:
---
title: 'My First Reflection'
date: '2025-12-18'
tags: ['mindfulness', 'beginnings']
---
# Embracing the Journey
This is the first entry in my digital garden. It's a space for me to plant my thoughts and watch them grow.
Today, I'm focusing on the idea of **mindfulness**. It's about being present in the moment without judgment.
I find that when I'm mindful, my anxiety tends to decrease. It's a powerful tool.
How it works
The section between the --- is the frontmatter. We'll use a library called gray-matter to parse this data. The rest of the file is standard Markdown with the potential for JSX components.
Step 2: Displaying Your Notes
What we're doing
We'll create a dynamic route in Next.js to render our MDX notes. This means that any file we add to the notes directory will automatically become a page in our digital garden.
Implementation
- In your
appdirectory, create a new folder structure:notes/[slug]. - Inside
notes/[slug], create apage.tsxfile. This will be our template for displaying each note.
// app/notes/[slug]/page.tsx
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
import { MDXRemote } from 'next-mdx-remote/rsc';
import { notFound } from 'next/navigation';
const notesDirectory = path.join(process.cwd(), 'notes');
export async function generateStaticParams() {
const files = fs.readdirSync(notesDirectory);
return files.map((filename) => ({
slug: filename.replace('.mdx', ''),
}));
}
export default async function NotePage({ params }: { params: { slug: string } }) {
const { slug } = params;
const filePath = path.join(notesDirectory, `${slug}.mdx`);
if (!fs.existsSync(filePath)) {
return notFound();
}
const source = fs.readFileSync(filePath, 'utf8');
const { content, data } = matter(source);
return (
<article className="prose lg:prose-xl mx-auto p-4">
<h1>{data.title}</h1>
<p className="text-sm text-gray-500">
{new Date(data.date).toLocaleDateString()}
</p>
<div className="mt-4">
<MDXRemote source={content} />
</div>
</article>
);
}
How it works
generateStaticParamstells Next.js to pre-render a page for each of our notes.- The
NotePagecomponent reads the corresponding.mdxfile, parses the frontmatter and content usinggray-matter, and then renders the content usingMDXRemote.
Step 3: Creating a Mindful UI with Custom Components
What we're doing
A mental health garden should feel calm and personal. We'll use Tailwind CSS to create a clean, minimalist design and build a custom React component to embed in our MDX files for highlighting key insights.
Implementation
- Styling: In your
app/globals.css, you can define a soothing color palette and typography. - Custom Component: Create a
componentsdirectory in your project root. Inside, create a file namedInsight.tsx:
// components/Insight.tsx
import React from 'react';
const Insight = ({ children }: { children: React.ReactNode }) => {
return (
<div className="bg-blue-100 border-l-4 border-blue-500 text-blue-700 p-4 my-4 rounded">
<p className="font-bold">Insight ✨</p>
{children}
</div>
);
};
export default Insight;
- To use this component in your MDX files, create an
mdx-components.tsxfile in the root of your project:
// mdx-components.tsx
import type { MDXComponents } from 'mdx/types';
import Insight from './components/Insight';
export function useMDXComponents(components: MDXComponents): MDXComponents {
return {
Insight,
...components,
};
}
Note: This file is crucial for making your components available to MDX in the App Router.
- Now, you can use the
<Insight>component in your.mdxfiles:
---
title: 'Mindful Moments'
date: '2025-12-19'
tags: ['mindfulness', 'anxiety']
---
# Finding Calm in the Chaos
<Insight>
When I feel overwhelmed, taking just five deep breaths can make a world of difference.
</Insight>
Step 4: Interlinking Your Thoughts
What we're doing
A key feature of a digital garden is the ability to connect related ideas. We'll use Next.js's Link component to create these connections within our notes.
Implementation
- Update your
mdx-components.tsxfile to override the defaultatag with Next.js'sLinkcomponent for internal links.
// mdx-components.tsx
import type { MDXComponents } from 'mdx/types';
import Insight from './components/Insight';
import Link from 'next/link';
import { useMemo } from 'react';
export function useMDXComponents(components: MDXComponents): MDXComponents {
return {
Insight,
a: (props) => {
const href = props.href as string;
if (href.startsWith('/')) {
return <Link href={href} {...props} />;
}
return <a {...props} />;
},
...components,
};
}
- Now you can link between your notes using standard Markdown syntax:
This thought connects back to my [[first-reflection]].
[first-reflection]: /notes/first-reflection
Step 5: Implementing a Simple Search
What we're doing
To make your garden navigable as it grows, we'll add a simple search functionality. We'll create an API route that returns notes matching a search query.
Implementation
- Create an API route at
app/api/search/route.ts:
// app/api/search/route.ts
import { NextResponse } from 'next/server';
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
const notesDirectory = path.join(process.cwd(), 'notes');
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const query = searchParams.get('q');
if (!query) {
return NextResponse.json({ error: 'Query parameter is required' }, { status: 400 });
}
const files = fs.readdirSync(notesDirectory);
const results = files
.map((filename) => {
const filePath = path.join(notesDirectory, filename);
const fileContents = fs.readFileSync(filePath, 'utf8');
const { data, content } = matter(fileContents);
if (
data.title.toLowerCase().includes(query.toLowerCase()) ||
content.toLowerCase().includes(query.toLowerCase())
) {
return {
slug: filename.replace('.mdx', ''),
title: data.title,
};
}
return null;
})
.filter(Boolean);
return NextResponse.json(results);
}
- Create a search component in
components/Search.tsxto use this API route.
For a more robust search experience in a larger garden, consider using a library like fuse.js.
Conclusion
You've now built the foundation for a beautiful and functional digital garden for your mental health journey. This is a living project—a space for you to cultivate your thoughts, understand your emotions, and grow.
Next Steps:
- Tagging System: Create pages that list all notes with a specific tag.
- Visual Graph: Explore libraries like D3.js or React Flow to create a visual representation of how your notes are connected.
- Personalization: Continue to customize the styling to create a space that feels truly yours.
Resources
Quick Reference
| Aspect | Key Information |
|---|---|
| Topic | Development |
| Relevance | Patient education and awareness |
| Action | Discuss with your healthcare provider |
| Frequency | As recommended by your care team |
| Evidence | Based on current clinical guidelines |
Frequently Asked Questions
Q: How do I know if this applies to me? A: Discuss your personal and family medical history with your healthcare provider to assess your individual risk factors and determine appropriate next steps.
Q: What should I ask my doctor? A: Good questions include: "What do my results mean?", "What are my options?", "What lifestyle changes would help?", and "When should I follow up?"
Q: Are there lifestyle changes that can help? A: Most health conditions benefit from foundational measures: balanced nutrition, regular physical activity (150+ minutes/week), quality sleep (7-9 hours), stress management, and avoiding tobacco.
Medical Disclaimer
This article is for educational purposes only and does not constitute medical advice. Always consult with a qualified healthcare provider before making decisions about your health, treatment, or care. Individual circumstances vary, and what is appropriate for one person may not be appropriate for another.
If you are experiencing a medical emergency, call 911 (or your local emergency number) immediately.