Next.js、React、TypeScript、Theme UI 与 MDX 组合,文章 front matter 由 zod 校验
ahurle-dev — Next.js 作品集模板
作者 fracture91
基于 Next.js、React、TypeScript、Theme UI 与 MDX 的个人网站和开发者博客模板,是 Devii 的深度改造分支,采用 MIT 许可。
看看你的网站会是什么样
浏览真实页面截图,比较内容排版与手机效果。点击下方缩略图切换,放大查看整页细节。
全部页面与视图 3
截图用于了解视觉与布局,交互效果请以实际项目为准。
值得关注的模板亮点
从已有项目资料中,快速了解它的特点。
从博客文章自动提取摘要、目录与阅读时长,代码块带语法高亮
页面采用静态生成,关闭客户端 JS 时站点仍可运行,图片经 next/image 优化
内置 GoatCounter 分析、Sentry 异常上报与 TinyLetter 订阅表单的接入点
提供 ESLint、Prettier、Jest 与 GitHub Actions CI,页面带 next-page-tester 冒烟测试
模板详细介绍
这是一个用于搭建个人网站与开发者博客的 Next.js 模板,仓库说明其驱动 ahurle.dev 站点,并且是 Devii 项目的深度修改分支。技术组合为 Next.js、React、TypeScript、Theme UI 与 MDX:文章和其他页面用 MDX 撰写,front matter 以 JS 对象导出并由 zod 校验。
内容层面,模板从每篇博客文章中提取摘要、目录与阅读时长,代码块带语法高亮,并支持 Theme UI 提供的深色模式。页面使用静态生成,站点在关闭客户端 JS 时仍可运行;图片通过 next/image 处理。
配套功能包括 GoatCounter 分析、Sentry 客户端异常上报、TinyLetter 订阅表单、RSS 与 sitemap,以及 ESLint、Prettier、Jest 和 GitHub Actions CI 配置;页面还带有基于 next-page-tester 的冒烟测试。
作为 fork 使用时,需要修改 helpers/globals.ts 中的名称与域名、next-sitemap.js 中的 URL,并替换 GoatCounter、Sentry、TinyLetter 的账号标识;头像、favicon 与 logo 等静态资源位于 public 目录,正文内容集中在 pages 目录。仓库说明中提到部署以 Vercel 最省事,且依赖部分 VERCEL_* 环境变量,next/image 需要服务端转换图片。
适合你的项目吗?
适用场景
- 搭建个人开发者博客并发布 MDX 文章
- 作为个人作品集网站的基础,替换头像、logo 与页面文案
- 以 fork 方式改造为自有站点,替换分析、异常上报与订阅服务账号
适合人群
- 熟悉 Next.js 与 React、愿意自行配置外部服务的开发者
- 需要 MDX 写作流程与静态生成博客的个人站点作者
- 希望以 MIT 许可代码为起点、自行调整样式与内容的用户
上手与定制指南
结合仓库当前版本的说明,按下面的资料检查内容、配置与运行要求。
- 1
需要 nvm 与 yarn;克隆仓库后执行 nvm use、yarn install、yarn dev,本地地址为 http://localhost:3000
- 2
修改 helpers/globals.ts 中的名称、域名等常量,并同步更新 next-sitemap.js 中的 URL
- 3
替换 GoatCounter、Sentry、TinyLetter 的账号标识,不需要时可设为 null 关闭对应功能
- 4
替换 public 目录下的头像、favicon 与 logo,并清理不需要的静态文件;正文内容位于 pages 目录
- 5
改动后运行 yarn test 更新快照,并确认 yarn lint 通过
授权与来源资料
使用条件与限制
免费使用 · 保留许可声明本次收录的是公开仓库中采用 MIT 许可的免费版本;免费范围为该版本代码,不代表外部服务或第三方素材免费。
使用时需要遵守
- 允许免费使用、修改、商用和分发该版本代码。
- 分发代码副本或实质性部分时,保留原作者版权声明和完整 MIT 许可声明。
- 代码按现状提供;担保与责任限制以原许可证及适用法律为准。
额外费用与待核对事项
- 作者请求(非许可强制)fork 使用者调整样式使其成为自己的站点,并删除原作者博客文章等内容;MIT 许可本身不强制此要求。
- 使用 GoatCounter 站点分析需自行注册账号并替换 goatCounterId;不需要时可设为 null 关闭。
- 使用 Sentry 客户端异常上报需自行注册账号并替换 sentryPublicKey 与 sentryDsn;不需要时可设为 null。
- TinyLetter 订阅表单需自行注册账号并替换 tinyLetterUsername,或设为 null 禁用表单。
- 部署推荐使用 Vercel 并注册账号;项目依赖部分 VERCEL_* 环境变量,且 next/image 需要服务端转换图片。
- 依赖 VERCEL_* 环境变量,且 next/image 图片优化需要服务端,纯静态托管可能无法使用该图片优化功能。
- GitHub Actions 中部分 action(尤其 bundlewatch)可能需要额外单独配置。
- config/imageSizeLoader.js 基于 Apache License 2.0 的第三方代码,使用时需遵守该许可的署名等条件。
- 演示图片、字体、图标及其他第三方素材需按各自许可核对,不能仅凭代码的 MIT 许可判断。
- 域名、托管、数据库、支付或 AI 等外部服务可能另外收费。
查看原文依据
Permission is hereby granted, free of charge
许可证原文
All I ask is that you style it a little differently - make it "yours". And remove my blog posts and stuff, of course.
README 原文
If you want to use GoatCounter for site analytics, [sign up for an account]
README 原文
You can use Sentry to catch unhandled exceptions on the client side of your app. [Sign up for an account]
README 原文
The site contains newsletter signup forms thanks to TinyLetter. [Sign up for an account]
README 原文
The easiest way to deploy this app is through Vercel. [Sign up for an account]
README 原文
Note that I depend on some `VERCEL_*` environment variables, and [`next/image`](https://nextjs.org/docs/basic-features/image-optimization?utm_source=ahurle-dev) requires a server to transform image URLs.
README 原文
You may also need to do some separate setup for the specific actions I'm using - especially [bundlewatch]
README 原文
https://github.com/fracture91/ahurle-dev/blob/master/LICENSEhttps://github.com/fracture91/ahurle-dev/blob/master/README.md[imageSizeLoader.js](./config/imageSizeLoader.js) based on [image-size-loader]
README 原文
DeepSeek 根据仓库许可证和 README 整理 ·2026-10-02。结果仅覆盖已读取资料,依赖、图片、字体及后续条款变更以各自原文为准。
项目核对记录与介绍依据
模板资料
- 来源平台
- GitHub
- 资料与维护参考分
- 资料一般 · 73 / 100
- 技术栈
- Next.js · React
- 网站类型
- 作品集 · 博客 · 启动器
这个分数如何计算
本站按许可资料(最高30分)、演示链接(12分)、预览图(10分)、Star数(15分)、记录的维护时间(15分)、描述完整度(8分)、功能记录(5分)和分类资料(5分)计算。它不是代码、安全或性能测试,也不是 Google 评分;有链接不代表已实测可用。
这个项目需要核对什么
- 记录的仓库更新时间
- 2022-12-07
- 截图检查日期
- 2026-10-02
已收录演示链接。请用你的内容与屏幕尺寸检查;有演示不代表表单、认证或支付已经可用。
目录记录的主要技术栈是 Next.js。请通过依赖清单和锁文件核对实际版本与托管要求。这些说明基于收录资料,不代表代码审计或部署实测。
查看具体选型方法 →介绍的制作与核对状态
介绍由 AI 辅助整理目录与仓库资料。仓库作者不等于这篇介绍的审核者。
已完成服务器许可规则与 AI 来源核对;未经过人工编辑审核。
查看当时使用的来源资料
SHA-256: 79a4fb5e7daf91346c73b215e9914b9147cd066712aefc4d914eab9069dff4af
2026-10-02T20:06:06.593Z
来源文件 / 仓库# ahurle-dev
Powers the
[ahurle.dev](https://ahurle.dev/?utm_source=github)
website and developer blog. Heavily modified fork of
[Devii](https://github.com/colinhacks/devii?utm_source=ahurle-dev).
[I wrote a blog post about this project](https://ahurle.dev/blog/overengineering-a-nextjs-dev-blog?utm_source=github)
if you want some more context on why it exists.
Feel free to fork this repo for your own website! I know how annoying it is to get everything working nicely if you were to start from scratch instead. All I ask is that you style it a little differently - make it "yours". And remove my blog posts and stuff, of course. It would also be nice if you linked back to me, but it's all MIT licensed so... 🤷♂️
## Features
- Modern Next.js, React, TypeScript stack
- Author blog posts and other pages in [MDX](https://mdxjs.com/?utm_source=ahurle-dev), export "front matter" as a JS object validated by [`zod`](https://github.com/colinhacks/zod?utm_source=ahurle-dev)
- Syntax highlighting for code blocks in your blog posts
- Dark mode support with [`theme-ui`](https://github.com/system-ui/theme-ui?utm_source=ahurle-dev)
- All pages get automatic smoke tests from [`next-page-tester`](https://github.com/toomuchdesign/next-page-tester/?utm_source=ahurle-dev)
- All pages use [static generation](https://nextjs.org/docs/basic-features/pages?utm_source=ahurle-dev#static-generation-recommended) and the site functions with client-side JS disabled
- Effortless image optimization with [`next/image`](https://nextjs.org/docs/api-reference/next/image?utm_source=ahurle-dev)
- Free analytics from [GoatCounter](https://www.goatcounter.com/?utm_source=ahurle-dev)
- Free hosting from [Vercel](https://vercel.com?utm_source=ahurle-dev)
- Free client-side exception reporting from [Sentry](https://sentry.io?utm_source=ahurle-dev)
- ESLint, Prettier, Jest, and a CI config for [Github Actions](https://github.com/features/actions?utm_source=ahurle-dev) - Free!
- Newsletter signup with [TinyLetter](https://tinyletter.com/?utm_source=ahurle-dev)
- Excerpt, Table of Contents, and Reading Time get extracted from each blog post
- SEO, a11y, RSS, sitemap, page speed are all in pretty good shape
## Getting started
- Install [nvm](https://github.com/nvm-sh/nvm#installing-and-updating)
and [yarn](https://yarnpkg.com/getting-started/install)
(perhaps [yvm](https://yvm.js.org/docs/overview) too).
- Clone/fork this repo and `cd` into it
```bash
nvm use # see .nvmrc
yarn install
yarn dev
```
You should now see my site running on http://localhost:3000
<details>
<summary>M1 Mac Special Instructions</summary>
I ran this on node 14.x for a while without problems. At some point it started exploding on `yarn install`. I was able to get around it like so:
```bash
nvm install v15.11.0
nvm use v15.*
vim package.json # change engines -> node to "15.x"
```
Note that vercel does not support node 15.x or higher yet. It will probably also work if you use Rosetta for Node 14 rather than trying to compile it natively for arm64.
</details>
<br/>
## CLI
- `yarn dev` - Starts the development server. Equivalent to `next dev`.
- `yarn build` - Creates an optimized, production build of your site. Equivalent to `next build`. Use `yarn start` to run this build locally.
- `ANALYZE=true yarn build` - Also opens webpack-bundle-analyzer output in your browser
- `yarn export` - Exports your site to static files. Equivalent to `next export`.
- `yarn lint` - Run eslint and prettier checks. Use `yarn lint:eslint` or `yarn lint:prettier` for specific checks
- `yarn test` - Run tests
## Creating Your Own Website As a Fork
There are a few basic things you'll want to change right away to make it "your" site:
### [helpers/globals.ts](./helpers/globals.ts)
The constants in this file are pretty self-explanatory. Change the name to match your name, the domain to match yours, etc.
### [next-sitemap.js](./next-sitemap.js)
I got lazy here and duplicated some config from `globals.ts` - change the URL to match your prodUrl, and add any exclusions for e.g. unpublished blog posts.
### GoatCounter
If you want to use GoatCounter for site analytics, [sign up for an account](https://www.goatcounter.com/signup?utm_source=ahurle-dev) and replace `goatCounterId` with your own. If you don't want to use it, you can set `goatCounterId` to null.
[`GoatCounterScript`](./components/GoatCounterScript.tsx) and [`GoatCounterPixel`](./components/GoatCounterPixel.tsx) contain some hardcoded checks to make sure you don't accidentally dump your data into my account in case you haven't read these instructions yet. Changing/Removing these is left as an exercise for the reader.
By default, analytics are only enabled in the prod environment, but you can test in dev by commenting out the prod checks.
### Sentry
You can use Sentry to catch unhandled exceptions on the client side of your app. [Sign up for an account](https://sentry.io/signup/?utm_source=ahurle-dev) and replace `sentryPublicKey` and `sentryDsn` with your own. If you don't want to use it, you can set either constant to null.
Like with `GoatCounterPixel`, there are some hardcoded checks in `SentryLoader` that you might want to remove.
By default, sentry only runs in prod and preview mode, but it can run in dev by commenting out the checks. Try calling `window.onerror("hello world")` to make Sentry log an error.
### TinyLetter
The site contains newsletter signup forms thanks to TinyLetter. [Sign up for an account](https://tinyletter.com/?utm_source=ahurle-dev) and replace `tinyLetterUsername` with your own, or set it to null to disable the forms.
### Snapshots
Once you've changed all this stuff, run `yarn test`. You'll probably have a bunch of failing snapshots that used to contain _my_ globals. Press `u` to update the snapshots to contain _your_ globals. Making sure `yarn lint` still passes is also a good idea.
### Github Actions
This project contains a [CI config](./.github/workflows/ci.yml) that should run whenever you open/update a PR or push to master. It's a good idea to make sure that's passing now. [Here's some documentation to get you started](https://docs.github.com/en/actions/quickstart?utm_source=ahurle-dev).
You may also need to do some separate setup for the specific actions I'm using - especially [bundlewatch](https://github.com/jackyef/bundlewatch-gh-action?utm_source=ahurle-dev) - but I don't remember the specifics 🤷♂️
### Vercel
The easiest way to deploy this app is through Vercel. [Sign up for an account](https://vercel.com/signup?utm_source=ahurle-dev) and you can have it deploy your repo with a few clicks. You should be able to visit your site at a `*.vercel.app` domain for now, and later you can point a domain at it like `ahurle.dev`. Remember to change `prodUrl` in `globals.ts` if your domain changes.
If you want to use something else then it's probably not very difficult to switch. Note that I depend on some `VERCEL_*` environment variables, and [`next/image`](https://nextjs.org/docs/basic-features/image-optimization?utm_source=ahurle-dev) requires a server to transform image URLs.
### Assets
- [me.jpg](./public/img/me.jpg): Change this to be an image of you, or delete it if you don't want one
- [favicon.ico](./public/favicon.ico),
[logo.png](./public/img/logo.png),
and [logo.svg](./public/img/logo.svg):
This is the favicon for your site. You'll want to replace these with images of your own creation.
- The rest of the non-SVG files in [/public](./public) can probably be deleted
### Content
Most of the text on the site lives in [/pages](./pages). If you aren't familiar with the concept of pages in Next.js, I recommend [reading the docs](https://nextjs.org/docs/routing/introduction?utm_source=ahurle-dev). You will probably also want to change the [Footer](./components/Footer.tsx) and [Header](./components/Header.tsx).
### Have fun!
The rest is up to you!
<br/>
## License
Most code © 2021 Andrew Hurle, [MIT License](./LICENSE)
Based on [Devii](https://devii.dev/?utm_source=ahurle-dev), © 2020 Colin McDonnell, [MIT License](https://github.com/colinhacks/devii/blob/31ffa9e1399acabd0f79f228dd19336864907165/LICENSE)
[imageSizeLoader.js](./config/imageSizeLoader.js) based on [image-size-loader](https://github.com/boopathi/image-size-loader), © 2015 Patrick Collins and Boopathi Rajaa, [Apache License 2.0](https://github.com/boopathi/image-size-loader/blob/bf1f3bc31c1a9ef579a957a77514ef665681848c/LICENSE)
[mdxDefaultLayout.js](./config/mdxDefaultLayout.js) based on [a file from silvenon.com](https://github.com/silvenon/silvenon.com/blob/3f1bfaad8ad4794cacd7623bff7627ce5e21ceda/etc/remark-mdx-default-layout.js), © 2020 Matija Marohnić <[email protected]> (silvenon.com), [MIT License](https://github.com/silvenon/silvenon.com/blob/3f1bfaad8ad4794cacd7623bff7627ce5e21ceda/license)
[mdxImageMetadata.js](./config/mdxImageMetadata.js) based on [a file from kylepfromer.com](https://github.com/kpfromer/portfolio/blob/ba194a9a82c176f7e58f912572d6a0ff8e8bad4c/plugins/image-metadata.ts), © 2019 Kyle Pfromer, [MIT License](https://github.com/kpfromer/portfolio/blob/ba194a9a82c176f7e58f912572d6a0ff8e8bad4c/LICENSE)
[prismStyle.ts](./helpers/prismStyle.ts) based on [the darcula theme from react-syntax-highlighter](https://github.com/react-syntax-highlighter/react-syntax-highlighter/blob/efc3f7b7537d1729193b7a472067bcbe6cbecaf1/src/styles/prism/darcula.js), © 2019 Conor Hastings, [MIT License](https://github.com/react-syntax-highlighter/react-syntax-highlighter/blob/efc3f7b7537d1729193b7a472067bcbe6cbecaf1/LICENSE)
看看同类模板
对比同技术栈与用途的模板,找到更适合的视觉与内容结构。

ai-website-cloner-template
Clone any website with one command using AI coding agents
Next.js · 启动器

Next.js SaaS Starter
Next.js SaaS Starter 是 Next.js 官方维护的 SaaS 起点模板,定位介于学习资源和可直接部署的脚手架之间。
Next.js · SaaS

Next.js Commerce
Next.js Commerce 是 Vercel 团队维护的电商启动模板,基于 Next.js App Router 构建,采用服务端渲染、React Server Components、Server Actions …
Next.js · 电商

Next-js-Boilerplate
Next-js-Boilerplate 是一个面向 Next.js 16、Tailwind CSS 4 和 TypeScript 的启动器,核心定位是开发者体验优先。
Next.js · 启动器

tailwind-nextjs-starter-blog
tailwind-nextjs-starter-blog 是一个面向个人技术博客的 Next.js 与 Tailwind CSS 启动模板,其 v2 版本基于 App Router 与 React Server Comp…
Next.js · 博客

next-forge
Production-grade Turborepo template for Next.js apps.
Next.js · 启动器
