nextjs-blog-theme: a Netlify blog starter configured by environment variables
A customizable Next.js and Tailwind blog starter with visual editing and Git Content Source. Designed by the Bejamas agency.
At a glance
- What is it?
- The Netlify nextjs-blog-theme is a Next.js and Tailwind blog starter whose name, title, footer, theme and fonts are set entirely through BLOG_ environment variables, with a setup wizard for the non-terminal path. The README still describes Next.js v15 while the manifest has moved to Next 16.
- Who is it for?
- Adopt nextjs-blog-theme if you want a working blog with MDX posts, Tailwind styling and Netlify deployment in a few clicks, and skip it if you need the App Router or a content platform with its own editing UI. Before you start, check the Next.js version, since the documentation says v15 with the Pages Router while the package manifest pins next at 16.0.8, and note the last push was on 2026-10-19.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 3 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A starter whose configuration is a set of environment variables
The nextjs-blog-theme is a customizable blog starter built on Next.js v15 with the Pages Router, Tailwind v4.x, and built-in MDX support, including a modern design with dark and light themes. It is published under the netlify-templates organisation, designed by the Bejamas agency, with a live demo at https://bejamas-nextjs-blog.netlify.app.
What makes it more than a bare blog is the configuration model. The config is based on environment variables to make it easy to integrate with any Jamstack platform, like Netlify, and there are six of them.
BLOG_NAME is the name of your blog, displayed below the avatar. BLOG_TITLE is the main header, an h1, on the home page. BLOG_FOOTER_TEXT is the text in the footer. BLOG_THEME is the theme to pass to Tailwind, with default as its option. BLOG_FONT_HEADINGS is the font-family for all HTML headings, from h1 to h6, and BLOG_FONT_BODY is the font-family for all other HTML elements, with sans-serif as the default, plus serif and monospace as options for both.
The effect is that branding, theme and typography are separated from the code and can be set at deploy time, which is what makes the setup wizard possible and what lets the same repository be used for several blogs with different names and fonts.
The primary language is JavaScript, the licence is MIT, and the default branch is main.
Two ways in, and only one needs a terminal
There are two setup routes, and the documentation is explicit that both are supported.
Locally, you start with the use this template button on GitHub, which creates a new repository with this template's files on your GitHub account. You then clone your new repository and navigate to it in your terminal. The dependencies install with yarn install, and the project runs with yarn run dev, after which you open your browser and visit http://localhost:3000.
yarn installyarn run devThe wizard route goes through the setup wizard at nextjs-wizard.netlify.app, where you can create your blog in a few clicks and deploy to Netlify. There is a deploy to Netlify button in the README as well, pointing at the Netlify start flow for this repository.
The wizard is worth a second look because of what it is allowed to do. All of the env variables can be configured through the Wizard or through setting the project's environment variables, and the documentation gives the exact path in the Netlify dashboard: Site settings, then Build & deploy, then Environment, then Environment variables.
And if setting an environment variable isn't your cup of tea, the defaults can be changed in utils/global-data.js, and you can also remove the variables and hard code blog information where these variables are used in the code base. So the environment variables are a convenience layer, not a dependency.
Where each setting actually lands in the code
The documentation maps the six variables to the files that consume them, which is the part you need when you are editing rather than configuring.
BLOG_THEME, BLOG_FONT_HEADINGS and BLOG_FONT_BODY are used in utils/theme-utils.js. That file is the single place where the theme choice and the two font families are turned into something the styles can use, and the repository also holds a themes.js file at the root, which is where the available Tailwind theme values are defined.
BLOG_NAME, BLOG_TITLE and BLOG_FOOTER_TEXT are used in pages/index.js and pages/posts/[slug].js through the globalData object. So the home page and the individual post pages read their text from the same shared object rather than from the environment directly, which is why changing global-data.js changes the site everywhere the globalData object is consumed.
The tree also shows the rest of the structure: components/ for the React pieces, pages/ for the Pages Router routes, posts/ for the content, styles/ for the Tailwind entry point, public/ for static assets, and utils/ for the data and theme helpers. The netlify.toml at the root is what tells Netlify how to build and serve the site, and postcss.config.js is where the Tailwind PostCSS plugin is wired in.
The pages/ layout is what tells you this is a Pages Router project rather than an App Router one. There is no app/ directory, and the presence of next-env.d.ts and tsconfig.json alongside pages/ is the standard Pages Router shape.
Posts are MDX files in a directory
All posts are stored in the /posts directory, and to make a new post you create a new file with the .mdx extension. That is the whole content model, and it is deliberately small.
The reason for MDX rather than plain Markdown is stated directly: since the posts are written in MDX format you can pass props and components, which means you can use React components inside your posts to make them more interactive, with a pointer to the MDX docs on content for the details.
Two dependencies make that work. next-mdx-remote at 6.0.0 or newer handles rendering MDX at request time in the Pages Router, and gray-matter at 4.0.3 or newer parses the front matter, which is where the title, date and tags of a post live. remark-gfm adds GitHub Flavored Markdown parsing, so tables, task lists and strikethrough behave the way they do on GitHub.
There is also a dev:watch script in the package.json, defined as next-remote-watch ./posts, which reloads the running dev server when a file in the posts directory changes. For a content site, that loop matters more than it would in an application project, since most of the editing happens in Markdown rather than in components.
Code highlighting is handled at build time rather than in the browser. The @mapbox/rehype-prism plugin and prismjs at 1.29.0 or newer are in the dependency list, and rehype-unwrap-images at 1.0.0 or newer handles images in Markdown. The tailwindcss typography plugin at 0.5.19 or newer is what gives the rendered Markdown prose its styling, and classnames handles the conditional class logic in the components.
A version mismatch worth knowing about before you deploy
There is one inconsistency in the repository, and it is the kind that costs an afternoon if you hit it without warning.
The README says the template uses Next.js v15 with the Pages Router. The package.json lists next at 16.0.8 or newer, along with eslint-config-next at 16.0.8 or newer and next-env.d.ts and tsconfig.json in the tree. React is at 19.2.1 or newer and react-dom matches it.
So the prose describes a major version behind the manifest. The dependency ranges are caret ranges, which means an install resolves to the latest 16.x, and the documented behaviour of Next 15 is not necessarily what you get.
The Pages Router is the more durable signal, because the pages/ directory with no app/ directory is the structural difference, and that does not change between these majors. A template that documented the App Router would be a different project in a way that matters, and this one does not.
The other version-shaped detail is Tailwind v4.x, which is a real change in how Tailwind is configured, since v4 moves away from the JavaScript config file and towards CSS-first configuration with the @tailwindcss/postcss plugin. The presence of @tailwindcss/postcss at 4.0.16 or newer in the devDependencies, along with postcss.config.js, is consistent with that, and the themes.js file at the root is where the theme values that BLOG_THEME selects come from.
The scripts, and the dependency bot you may want to delete
The package.json scripts are the conventional Next.js set, with one addition.
dev runs next, dev:watch runs next-remote-watch ./posts, build runs next build, start runs next start, export runs next build and then next export, and lint runs next lint.
The export script is the interesting one for a static-first site. Running next build and then next export produces a static export of the site rather than a Node server, which is what a Jamstack deployment wants, and it is why the project can be hosted on any platform and not only on Netlify even though Netlify made it.
On the testing side, the section is titled Included Default Testing and it is short. The template currently uses Renovate, to regularly update our dependencies. If your team is not interested in this tooling, you can remove them with ease, and the Removing Renovate section is specific about the mechanism: delete the renovate.json file and commit that onto your main branch.
That is worth reading as a design decision rather than a footnote. Netlify ships a dependency bot in the template so the framework and its transitive dependencies stay current across the many templates they publish, which is the right default for a shared starter and the wrong default for a team that wants pinned versions and a reproducible build.
The tree also carries .eslintrc.json, .prettierrc.js, tsconfig.json and next-env.d.ts, so the linting and formatting setup is present as well.
Where this template stops being the right choice
There are three honest limits.
The first is that it is a Pages Router project, and the direction of travel in Next.js is the App Router. The template has no app/ directory, and the pages/ structure means the data fetching model, the layout nesting and the caching behaviour are all Pages Router ones. A team that intends to build a site on the App Router would be starting from a different template rather than adapting this one, and the mdX pipeline through next-mdx-remote is tied to the Pages Router model of rendering content at request time.
The second is the content model. Posts are files in a directory, and the visual editor comes from Netlify's Git Content Source tooling rather than from a CMS with its own database, revision history or scheduled publishing. For a blog where a writer commits Markdown to a repository, that is exactly right. For a site with multiple non-technical authors, or with content that changes on a schedule, the git-based model becomes the bottleneck rather than the feature.
The third is the version drift described earlier. A template whose documentation and manifest disagree on the framework major is a template where something in the walkthrough may not match what you get, and a starter that a user deploys and then has to debug is a poor first impression of Next.js.
The realistic alternative is a different kind of starter. A minimal Astro or a plain Next.js project with a markdown loader gives you the same end result with a smaller dependency surface and no bot in the repository, at the cost of the MDX-plus-Tailwind-plus-Netlify combination that is already assembled here. If your requirement is a personal or small team blog that deploys to Netlify today, this template removes a day of setup. If the requirement is a site you will be running for years, the version drift is the part to weigh before you start.
Editorial conclusion
Adopt nextjs-blog-theme if you want a working blog with MDX posts, Tailwind styling and Netlify deployment in a few clicks, and skip it if you need the App Router or a content platform with its own editing UI. Before you start, check the Next.js version, since the documentation says v15 with the Pages Router while the package manifest pins next at 16.0.8, and note the last push was on 2026-10-19.
Frequently asked questions
How do I set up the nextjs-blog-theme locally?
Use the use this template button on GitHub to create your own repository, clone it, run yarn install, then yarn run dev and open http://localhost:3000. The setup wizard at nextjs-wizard.netlify.app is the alternative route and deploys to Netlify in a few clicks.
Which environment variables configure the nextjs-blog-theme?
BLOG_NAME, BLOG_TITLE, BLOG_FOOTER_TEXT, BLOG_THEME, BLOG_FONT_HEADINGS and BLOG_FONT_BODY. The theme and font variables are used in utils/theme-utils.js, and the name, title and footer text are used in pages/index.js and pages/posts/[slug].js through the globalData object.
How do I add a new blog post to nextjs-blog-theme?
All posts are stored in the /posts directory, and you create a new post as a new file with the .mdx extension. Because the posts are MDX you can pass props and use React components inside them.
Can I remove Renovate from the nextjs-blog-theme?
Yes. The template uses Renovate to regularly update dependencies, and the documented way to remove it is to delete the renovate.json file and commit that onto your main branch.
Which Next.js version does the nextjs-blog-theme use?
The README describes Next.js v15 with the Pages Router, but the package.json pins next at 16.0.8 or newer along with eslint-config-next at the same version, so the installed dependency is ahead of the documented major version.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/netlify-templates-nextjs-blog-theme)Was this useful?