Configure and enable the blog system in your SaaS boilerplate.
The blog system is controlled by environment configuration:
Add blog page configuration to your environment file:
# .env.local or .env.production
ENABLE_BLOG=trueThis enables both blog routes:
/blog - Database-driven blog/blog/mdx - Static MDX blogThe boilerplate checks page enablement with:
// lib/utils.ts
import { PagesConst } from '@/env'
export function isPageEnabled(page: string): boolean {
return process.env[`ENABLE_${page}`] === 'true'
}
// Usage in pages
if (!isPageEnabled(PagesConst.BLOG)) {
return notFound()
}Start your development server to see the blog:
pnpm devAvailable Routes:
http://localhost:3000/blog - Database blog listhttp://localhost:3000/blog/mdx - MDX blog listhttp://localhost:3000/admin/blog - Admin dashboard (requires login)For the database blog system, ensure your database includes the blog schema:
Apply database migrations to create blog tables:
pnpm db:migrateThis creates the necessary tables:
post - Main post datapost_translation - Multi-language contentcategory - Content categorieshashtag - Content tagspost_hashtag - Tag associationsAdd sample blog content for development:
pnpm db:seedThis creates:
Check your database setup:
pnpm db:studioThis opens Drizzle Studio where you can:
Configure admin access for content management:
Blog management requires specific role permissions:
// Blog permissions by role
const blogPermissions = {
'blog-post:create': ['ADMIN', 'REDACTOR'],
'blog-post:read': ['ADMIN', 'REDACTOR', 'MODERATOR'],
'blog-post:update': ['ADMIN', 'REDACTOR'],
'blog-post:delete': ['ADMIN'],
'blog-post:publish': ['ADMIN', 'REDACTOR']
}Required Roles:
ADMIN - Full blog management accessREDACTOR - Can create, edit, and publish postsMODERATOR - Can view posts only/admin/blogIf you don't see the blog admin, check your user role in the database or use Drizzle Studio to update your user permissions.
Add blog links to your application navigation:
// components/navigation.tsx
const navigation = [
{ name: 'Home', href: '/' },
{ name: 'Blog', href: '/blog' },
{ name: 'Documentation', href: '/blog/mdx' },
// ... other links
]Configure SEO settings for blog pages:
Blog pages automatically generate SEO meta tags:
// Automatic meta generation for blog posts
export async function generateMetadata({ params }): Promise<Metadata> {
const post = await getPostBySlug(params.slug)
return {
title: post.title,
description: post.description,
openGraph: {
title: post.title,
description: post.description,
type: 'article',
publishedTime: post.publishedAt,
},
twitter: {
card: 'summary_large_image',
title: post.title,
description: post.description,
}
}
}Blog posts are automatically included in your sitemap:
// Blog posts added to sitemap.xml
const blogPosts = await getAllPublishedPosts()
const blogUrls = blogPosts.map(post => ({
url: `${baseUrl}/blog/${post.slug}`,
lastModified: post.updatedAt,
changeFrequency: 'weekly' as const,
priority: 0.7,
}))The blog system supports multiple languages:
Configure supported languages in your i18n setup:
// i18n/routing.ts
export const routing = defineRouting({
locales: ['en', 'fr', 'es'],
defaultLocale: 'en'
})
// Supported languages for blog content
type SupportedLanguage = 'en' | 'fr' | 'es'Blog posts automatically support multiple languages:
# Start development server
pnpm dev
# Check blog functionality
# Visit: http://localhost:3000/blog
# Visit: http://localhost:3000/admin/blog# Reset and seed database with sample content
pnpm db:reset-seed
# Open database studio to manage content
pnpm db:studio
# Check blog in browser
open http://localhost:3000/blog# Build application
pnpm build
# Run production migrations
pnpm db:migrate
# Deploy to your hosting platform
# Blog will be available at yourdomain.com/blogBlog Ready! Your blog system is now configured and ready for content creation. Visit /admin/blog to start creating content or add MDX files to start with static content.