Add your blog in 5 minutes
This adds a blog section (at yoursite.com/blog) to your existing Next.js site. Every post you generate in the dashboard appears there automatically — styled to match your own site.
tz_live_). Lost it? Open your dashboard → API Keys → create a new one. A key can only be viewed once, so store it somewhere safe.Have a Next.js site already?
If yes, skip to Step 1. If you’re starting fresh, run this to create one, then open the new my-site folder in your code editor:
npx create-next-app@latest my-site
cd my-siteInstall the package
Run this in your project folder’s terminal:
npm install @tezblogs/nextAdd your API key
Create a file named .env.local in the root of your project (or add these lines if it exists). Replace tz_live_paste_your_key_here with your real key. The API URL is already filled in for you.
TEZBLOGS_API_KEY=tz_live_paste_your_key_here
TEZBLOGS_API_URL=https://tezblogs.techCreate the connection file
Make a new file at lib/tezblogs.ts. This connects your site to TezBlogs using the key from Step 2.
import { createTezBlogsClient } from '@tezblogs/next'
export const tezblogs = createTezBlogsClient({
apiKey: process.env.TEZBLOGS_API_KEY!,
baseUrl: process.env.TEZBLOGS_API_URL!,
})Add the blog list page
Make a new file at app/blog/page.tsx. This is your blog index — the list of all published posts at yoursite.com/blog.
import { BlogIndex } from '@tezblogs/next'
import { tezblogs } from '@/lib/tezblogs'
export default async function BlogPage() {
const { docs } = await tezblogs.getPosts()
return (
<main style={{ maxWidth: 720, margin: '0 auto', padding: 24 }}>
<h1>Blog</h1>
<BlogIndex posts={docs} />
</main>
)
}Add the single-post page
Make a new file at app/blog/[slug]/page.tsx (the folder name is literally [slug], with the square brackets). This renders each individual article. Change https://YOUR-SITE.com to your real domain for correct SEO tags.
import { BlogPost, postMetadata } from '@tezblogs/next'
import { notFound } from 'next/navigation'
import { tezblogs } from '@/lib/tezblogs'
type Props = { params: Promise<{ slug: string }> }
export async function generateStaticParams() {
return (await tezblogs.getSlugs()).map((slug) => ({ slug }))
}
export async function generateMetadata({ params }: Props) {
const post = await tezblogs.getPost((await params).slug)
return post ? postMetadata({ post, siteUrl: 'https://YOUR-SITE.com' }) : {}
}
export default async function PostPage({ params }: Props) {
const post = await tezblogs.getPost((await params).slug)
if (!post) notFound()
return (
<main style={{ maxWidth: 720, margin: '0 auto', padding: 24 }}>
<BlogPost post={post} />
</main>
)
}See it working
Start your site (npm run dev) and open http://localhost:3000/blog. Generate a post in your dashboard, publish it, and it appears here. That’s it — deploy your site as you normally would.
Optional: instant publishing (no redeploy)
Want new posts to appear the instant you publish, without redeploying? Add this file at app/api/tezblogs/revalidate/route.ts, then set the same URL + secret under your tenant’s Webhook settings in the dashboard.
import { createRevalidateHandler } from '@tezblogs/next'
export const POST = createRevalidateHandler({
secret: process.env.TEZBLOGS_WEBHOOK_SECRET!,
})Troubleshooting
The /blog page is empty
That’s expected until you publish a post. In the dashboard, generate an article, open it, and set its status to Published. Refresh /blog.
“Unauthorized” or 401 errors
Your API key is missing or wrong. Check .env.local — the key must start with tz_live_ and have no extra spaces or quotes. Restart npm run dev after editing it (Next.js only reads env files on startup).
Module not found: @tezblogs/next
Run npm install @tezblogs/next again inside the project folder, then restart your dev server.
Posts look unstyled / plain
Posts render as clean semantic HTML and inherit your site’s styles. If you use Tailwind, add the Typography plugin and the built-in prose styling kicks in automatically. You can also pass your own className to <BlogPost>.
Still stuck?
Email contact@tezads.comwith your site URL and what you’re seeing, and we’ll get you running.