Next.jsReact作品集博客启动器

ahurle-dev — Next.js 作品集模板

作者 fracture91

基于 Next.js、React、TypeScript、Theme UI 与 MDX 的个人网站和开发者博客模板,是 Devii 的深度改造分支,采用 MIT 许可。

看看你的网站会是什么样

浏览真实页面截图,比较内容排版与手机效果。点击下方缩略图切换,放大查看整页细节。

3 个预览视图
桌面端首页1 / 3
桌面端截图首屏预览

由服务器浏览器实际访问页面后截取。

全部页面与视图 3

截图用于了解视觉与布局,交互效果请以实际项目为准。

采集于 2026-10-02查看来源

值得关注的模板亮点

从已有项目资料中,快速了解它的特点。

01

Next.js、React、TypeScript、Theme UI 与 MDX 组合,文章 front matter 由 zod 校验

02

从博客文章自动提取摘要、目录与阅读时长,代码块带语法高亮

03

页面采用静态生成,关闭客户端 JS 时站点仍可运行,图片经 next/image 优化

04

内置 GoatCounter 分析、Sentry 异常上报与 TinyLetter 订阅表单的接入点

05

提供 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 需要服务端转换图片。

Next.jsReact作品集博客启动器

适合你的项目吗?

适用场景

  • 搭建个人开发者博客并发布 MDX 文章
  • 作为个人作品集网站的基础,替换头像、logo 与页面文案
  • 以 fork 方式改造为自有站点,替换分析、异常上报与订阅服务账号

适合人群

  • 熟悉 Next.js 与 React、愿意自行配置外部服务的开发者
  • 需要 MDX 写作流程与静态生成博客的个人站点作者
  • 希望以 MIT 许可代码为起点、自行调整样式与内容的用户

上手与定制指南

结合仓库当前版本的说明,按下面的资料检查内容、配置与运行要求。

  1. 1

    需要 nvm 与 yarn;克隆仓库后执行 nvm use、yarn install、yarn dev,本地地址为 http://localhost:3000

  2. 2

    修改 helpers/globals.ts 中的名称、域名等常量,并同步更新 next-sitemap.js 中的 URL

  3. 3

    替换 GoatCounter、Sentry、TinyLetter 的账号标识,不需要时可设为 null 关闭对应功能

  4. 4

    替换 public 目录下的头像、favicon 与 logo,并清理不需要的静态文件;正文内容位于 pages 目录

  5. 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 原文

[imageSizeLoader.js](./config/imageSizeLoader.js) based on [image-size-loader]

README 原文
https://github.com/fracture91/ahurle-dev/blob/master/LICENSEhttps://github.com/fracture91/ahurle-dev/blob/master/README.md

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)
反馈内容错误

看看同类模板

对比同技术栈与用途的模板,找到更适合的视觉与内容结构。