终端模拟器界面:每个标签是真实 Next.js 路由,配有标题栏、标签条与状态栏
personal-website — Next.js 作品集模板
作者 janguenzel
一个用 Next.js 构建、以标签页终端模拟器为界面的个人作品集网站,支持中英双语、多主题与键盘导航。
看看你的网站会是什么样
浏览真实页面截图,比较内容排版与手机效果。点击下方缩略图切换,放大查看整页细节。
全部页面与视图 3
截图用于了解视觉与布局,交互效果请以实际项目为准。
值得关注的模板亮点
从已有项目资料中,快速了解它的特点。
键盘优先导航:命令面板、标签切换、主题与配色切换、语言切换等快捷键
双语支持:基于路由的自定义 i18n,英语与德语字典保持键位一致
主题系统:CSS 变量令牌,亮/暗模式加四种命名配色方案,无闪烁切换
可选留言板:GitHub OAuth 登录,开发用 JSON 文件、生产用 Neon Postgres
动画可降级:打字机、扫描线、矩阵雨等效果受 prefers-reduced-motion 控制
模板详细介绍
这个模板把个人网站做成标签页式终端模拟器:每个终端标签对应一个真实的 Next.js 路由(位于 app/[locale]/…),而不是客户端单页视图。站点自带终端外壳(标题栏、标签条、状态栏),导航既可以用鼠标点击标签,也可以用键盘完成,包括命令面板、标签切换、主题切换、语言切换等快捷键。
内容与配置分离。公开信息(姓名、角色、社交账号、fastfetch 文本)来自 NEXT_PUBLIC_* 环境变量,法律/版本说明数据来自仅服务端读取的环境变量,因此无需改动代码即可替换成自己的信息。项目内容与个人简介集中在 content/ 目录。
站点为双语(英语/德语),采用基于路由的自定义 i18n,所有面向用户的字符串在 en.json 与 de.json 中保持键位一致。主题使用 CSS 变量令牌,支持亮/暗模式与四种命名配色方案,通过 data-theme 与 data-scheme 切换,并由内联脚本在绘制前应用以避免闪烁。
可选功能包括 GitHub OAuth 登录的留言板,开发环境使用本地 JSON 文件、生产环境使用 Neon Postgres,未配置相关环境变量时留言板不启用。动画效果(打字机开场、光标闪烁、CRT 扫描线、矩阵雨等)均受 prefers-reduced-motion 控制,并降级为静态回退。
SEO 与无障碍方面包含每页元数据、canonical 与 hreflang、站点地图、robots、按语言生成的 OpenGraph 图片和 JSON-LD;标签为真实链接并带 aria-current,覆盖层使用对话框语义,焦点可见,两种主题下对比度满足 WCAG AA。
限制:模板未提供可直接使用的托管演示数据,需要自行填写环境变量;留言板依赖外部 GitHub OAuth 应用与数据库服务;演示图片、字体、图标等第三方素材需按各自许可单独核对。
适合你的项目吗?
适用场景
- 搭建个人作品集网站,用终端风格展示项目与个人简介
- 需要中英(或英德)双语个人站点的开发者
- 希望用环境变量配置站点信息、不把个人信息写进代码的部署方式
- 想研究 Next.js App Router、自定义 i18n 与 CSS 变量主题实现的项目
- 需要带 GitHub 登录留言板的轻量互动功能
适合人群
- 熟悉 Next.js 与 TypeScript、愿意自行配置环境变量的开发者
- 偏好终端美学与键盘操作的个人网站作者
- 需要双语作品集并希望内容与代码分离的独立开发者
上手与定制指南
结合仓库当前版本的说明,按下面的资料检查内容、配置与运行要求。
- 1
克隆仓库后执行 npm install,复制 .env.example 为 .env 并填写环境变量,再运行 npm run dev
- 2
公开站点信息通过 NEXT_PUBLIC_* 变量配置;法律/版本说明数据通过仅服务端变量配置
- 3
启用留言板需设置 AUTH_SECRET、GITHUB_CLIENT_ID、GITHUB_CLIENT_SECRET 与 DATABASE_URL,并将 OAuth 回调地址设为 <NEXT_PUBLIC_SITE_URL>/api/auth/callback
- 4
项目与个人简介内容在 content/ 目录中编辑
- 5
可用脚本包括 npm run build、npm run start、npm run lint、npm run typecheck、npm test
授权与来源资料
使用条件与限制
免费使用 · 保留许可声明本次收录的是公开仓库中采用 MIT 许可的免费版本;免费范围为该版本代码,不代表外部服务或第三方素材免费。
使用时需要遵守
- 允许免费使用、修改、商用和分发该版本代码。
- 分发代码副本或实质性部分时,保留原作者版权声明和完整 MIT 许可声明。
- 代码按现状提供;担保与责任限制以原许可证及适用法律为准。
额外费用与待核对事项
- 演示图片、字体、图标及其他第三方素材需按各自许可核对,不能仅凭代码的 MIT 许可判断。
- 域名、托管、数据库、支付或 AI 等外部服务可能另外收费。
- 留言板为可选功能,仅在设置 AUTH_SECRET、GITHUB_CLIENT_ID、GITHUB_CLIENT_SECRET 等环境变量后启用;不设置则站点正常运行但无留言板。
- 启用留言板需自行在 GitHub 创建 OAuth 应用并获取客户端 ID,依赖外部 GitHub 服务与账号。
- 生产环境留言板与访问统计需连接 Neon Postgres 数据库;未配置时仅使用本地 .data/ 下的 JSON 文件,不适合生产。
- 使用 GitHub OAuth 登录时必须将回调地址配置为 <NEXT_PUBLIC_SITE_URL>/api/auth/callback,否则登录流程无法完成。
- 未设置 IMPRINT_NAME 等法律/版本说明变量时,/imprint 与 /privacy 页面显示占位内容,需自行填写真实信息。
查看原文依据
Permission is hereby granted, free of charge
许可证原文
The GitHub-authenticated message board only activates when these are set. Leave them empty to run the site without the board.
README 原文
OAuth app client ID ([create one here](https://github.com/settings/developers)).
README 原文
Neon Postgres connection string for board + visit storage in production. Auto-injected by Vercel once a Neon database is connected (`POSTGRES_URL` is also accepted); unset, the board uses a local JSON file under `.data/`.
README 原文
For the GitHub OAuth app, set the **Authorization callback URL** to `<NEXT_PUBLIC_SITE_URL>/api/auth/callback`.
README 原文
https://github.com/janguenzel/personal-website/blob/main/LICENSEhttps://github.com/janguenzel/personal-website/blob/main/README.mdUntil `IMPRINT_NAME` is set, placeholder values are shown.
README 原文
DeepSeek 根据仓库许可证和 README 整理 ·2026-10-13。结果仅覆盖已读取资料,依赖、图片、字体及后续条款变更以各自原文为准。
项目核对记录与介绍依据
模板资料
- 来源平台
- GitHub
- 资料与维护参考分
- 资料较完整 · 83 / 100
- 技术栈
- Next.js · React
- 网站类型
- 作品集
这个分数如何计算
本站按许可资料(最高30分)、演示链接(12分)、预览图(10分)、Star数(15分)、记录的维护时间(15分)、描述完整度(8分)、功能记录(5分)和分类资料(5分)计算。它不是代码、安全或性能测试,也不是 Google 评分;有链接不代表已实测可用。
这个项目需要核对什么
- 记录的仓库更新时间
- 2026-06-19
- 截图检查日期
- 2026-10-13
已收录演示链接。请用你的内容与屏幕尺寸检查;有演示不代表表单、认证或支付已经可用。
目录记录的主要技术栈是 Next.js。请通过依赖清单和锁文件核对实际版本与托管要求。这些说明基于收录资料,不代表代码审计或部署实测。
查看具体选型方法 →介绍的制作与核对状态
介绍由 AI 辅助整理目录与仓库资料。仓库作者不等于这篇介绍的审核者。
审核声明: [email protected] · 2026-10-13
查看当时使用的来源资料
SHA-256: 4549be8a02fe331da31892d309b976ecaff795da3397777c17911382766fe999
2026-10-13T07:53:47.193Z
来源文件 / 仓库# personal-website — Terminal Portfolio [](https://github.com/janguenzel/personal-website/actions/workflows/ci.yml) [](./LICENSE) A personal website written in **Next.js 16** with **Tailwind CSS v4** and **Framer Motion**, dressed up as a **tabbed terminal emulator**. Every tab is a real route, navigation is keyboard-first with an interactive prompt and a command palette, and the whole thing is bilingual (English / German), themeable (dark + light + extra color schemes), and full of tasteful, reduced-motion-safe animation. ## Fork it & make it yours Like it? **Fork it.** This project is intentionally built to be forkable — nothing personal is committed to the repo. All public details (name, role, socials, fastfetch text) come from `NEXT_PUBLIC_*` env vars, and legal/imprint data comes from server-only env vars, so the whole site re-themes around you without touching a line of code. It's released under the [MIT License](./LICENSE), so you're free to use, copy, modify, extend, publish, and distribute it for your own purposes — personal or commercial. Just keep the copyright notice. Go build your own terminal portfolio. 🚀 And if this made you smile or saved you some time — **drop a ⭐ on the repo**. It costs you one click and genuinely makes my day. Thank you! 😊 ## Getting started Once you've cloned the repo: ```bash npm install # install dependencies cp .env.example .env # then fill in the values (see "Environment variables" below) npm run dev # start the dev server at http://localhost:3000 ``` Other useful scripts: ```bash npm run build # production build (run this before declaring done) npm run start # serve the production build npm run lint # ESLint npm run typecheck # tsc --noEmit npm test # run the Vitest unit + component suite npm run test:watch # Vitest in watch mode npm run test:coverage # coverage report (./coverage) ``` > **Note:** Next.js 16 has breaking changes vs. older versions. The bundled guides under > `node_modules/next/dist/docs/` are the source of truth. ## Environment variables Copy `.env.example` to `.env` (local) or set these in your host's environment (production). Everything has a sensible fallback, so the site runs out of the box — the values below just personalize it and enable the optional GitHub message board. ### Public site config (`NEXT_PUBLIC_*`) Safe to expose to the browser. Powers SEO tags, the title bar, and the fastfetch landing. | Variable | Description | Default | | ---------------------------- | ------------------------------------------------------------------ | ------------------------------------------------- | | `NEXT_PUBLIC_SITE_URL` | Canonical absolute URL, no trailing slash (SEO + OAuth redirects). | `http://localhost:3000` | | `NEXT_PUBLIC_SITE_NAME` | Display name in the title bar / metadata. | `Jan Henning Günzel` | | `NEXT_PUBLIC_SITE_HOST` | Shell-style host for the prompt (`user@host`). | `jan-guenzel` | | `NEXT_PUBLIC_SITE_USER` | Shell-style username for the prompt. | `visitor` | | `NEXT_PUBLIC_SITE_ROLE` | Your role, shown in fastfetch. | `Software Engineer` | | `NEXT_PUBLIC_SITE_LOCATION` | Your location, shown in fastfetch. | `Germany` | | `NEXT_PUBLIC_SITE_EMAIL` | Public contact address on the landing page. | `[email protected]` | | `NEXT_PUBLIC_GITHUB_USER` | GitHub username (links + socials). | `janguenzel` | | `NEXT_PUBLIC_TWITTER_HANDLE` | Twitter/X handle (empty = hidden). | _empty_ | | `NEXT_PUBLIC_LINKEDIN_URL` | Full LinkedIn profile URL (empty = hidden). | _empty_ | | `NEXT_PUBLIC_SITE_DISTRO` | Fastfetch "OS" flavour text. | `PortfolioOS 1.0 (terminal edition)` | | `NEXT_PUBLIC_SITE_SHELL` | Fastfetch shell value. | `zsh` | | `NEXT_PUBLIC_SITE_EDITOR` | Fastfetch editor value. | `vscode, neovim` | | `NEXT_PUBLIC_SITE_LANGUAGES` | Comma-separated languages for fastfetch. | `TypeScript,Rust,Python` | | `NEXT_PUBLIC_SITE_STACK` | Comma-separated stack for fastfetch. | `Next.js,React,Node.js,Nest.js,PostgreSQL,Docker` | | `NEXT_PUBLIC_CODING_SINCE` | ISO date you started coding (drives the fastfetch "uptime"). | `2015-01-01` | ### Legal / imprint config (server-only) Read server-side only and rendered into the `/imprint` and `/privacy` pages (both `noindex`), so your real name and address never get committed or shipped to clients. Until `IMPRINT_NAME` is set, placeholder values are shown. | Variable | Description | | ----------------- | ---------------------------------------------------------------- | | `IMPRINT_NAME` | Your legal name. Setting this marks the imprint as "configured". | | `IMPRINT_STREET` | Street address. | | `IMPRINT_CITY` | Postal code + city. | | `IMPRINT_COUNTRY` | Country. | | `IMPRINT_EMAIL` | Contact email (falls back to `NEXT_PUBLIC_SITE_EMAIL`). | | `IMPRINT_PHONE` | Phone number (optional). | | `IMPRINT_VAT_ID` | VAT ID (optional). | ### Auth & message board (optional) The GitHub-authenticated message board only activates when these are set. Leave them empty to run the site without the board. | Variable | Description | | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `AUTH_SECRET` | Secret used to sign the HMAC-SHA256 session cookie. Use a long random string. | | `GITHUB_CLIENT_ID` | OAuth app client ID ([create one here](https://github.com/settings/developers)). | | `GITHUB_CLIENT_SECRET` | OAuth app client secret. | | `DATABASE_URL` | Neon Postgres connection string for board + visit storage in production. Auto-injected by Vercel once a Neon database is connected (`POSTGRES_URL` is also accepted); unset, the board uses a local JSON file under `.data/`. | For the GitHub OAuth app, set the **Authorization callback URL** to `<NEXT_PUBLIC_SITE_URL>/api/auth/callback`. ## How it works A bit more detail on what's under the hood: - **Routing = tabs.** Each terminal "tab" is a real Next.js route under `app/[locale]/…`, not a client-only SPA view. `proxy.ts` (Next 16's middleware) redirects locale-less paths to `/[locale]/…`, and the `[locale]` layout wraps every page in the terminal chrome (title bar, tab strip, status bar). `lib/nav.ts` is the single source of truth for tabs — the TabBar, command palette, hotkeys, and sitemap all derive from it. - **Server-first.** Pages are React Server Components that read locale dictionaries directly. Interactive pieces (the shell, board, palette, effects) are client components with a low boundary. - **Dual navigation.** Click tabs _or_ drive everything from the keyboard: `⌘/Ctrl+K` opens the command palette, `Ctrl+]`/`[` switch tabs, `g`+number jumps, `⌘/Ctrl+J` toggles the theme, `Ctrl+.` cycles the color scheme, `?` shows help, and `L` swaps the language. (Browser-reserved combos are deliberately avoided.) - **i18n.** Custom, route-based i18n. Every user-facing string is a key present in **both** `lib/i18n/dictionaries/en.json` and `de.json`, kept at full parity. German is natural and informal ("du"). - **Theming.** All colors are CSS-variable tokens (no inline hex). Light/dark via `data-theme`, four named color schemes via `data-scheme`, applied pre-paint by a no-FOUC inline script and persisted to localStorage + cookie. - **Auth & board.** A hand-rolled GitHub OAuth web flow (zero auth deps) sets a signed httpOnly session cookie via Web Crypto. The message board lives behind a pluggable backend — a local JSON file in dev, Neon Postgres (via `@neondatabase/serverless`) in production — with a per-user post cooldown and edit/delete of your own messages. - **Animation & gimmicks.** A boot-style typewriter intro, blinking block cursor, glitch-on-hover ASCII, CRT scanline toggle, matrix rain (Konami code), and `motion` transitions — every effect is gated behind `prefers-reduced-motion` and degrades to a calm static fallback. - **SEO & a11y.** Per-page metadata with canonical + hreflang alternates, a sitemap, robots, per-locale OpenGraph images, and JSON-LD. Route tabs are real links with `aria-current`, overlays are proper dialogs, focus is visible, and contrast meets WCAG AA in both themes. ### Tech stack | Concern | Choice | | --------- | ---------------------------------------------------- | | Framework | Next.js 16 (App Router / RSC, Turbopack) | | UI | React 19 | | Language | TypeScript (strict) | | Styling | Tailwind CSS v4 (CSS-first `@theme`, no config file) | | State | Zustand | | Animation | Framer Motion (`motion`) + CSS + canvas | | i18n | Custom, route-based | | Auth | Hand-rolled GitHub OAuth (Web Crypto signed cookie) | | Storage | JSON file (dev) / Neon Postgres (prod) | | Tests | Vitest + React Testing Library (jsdom) | ### Project layout ``` proxy.ts # Next 16 middleware: locale redirect (cookie/Accept-Language) + locale cookie app/ # routes (one per terminal tab) + API routes, sitemap, robots, OG images components/ # terminal shell, fastfetch, board, about, ui, effects lib/ # i18n, store, hooks, themes, nav, site/imprint config, auth, board content/ # projects + about bio (the only place to edit your content) test/ # Vitest unit + component tests ``` Forking? Start with `lib/site.ts` env vars and `content/{projects,about}.ts` — that's where your identity and work live. --- Licensed under [MIT](./LICENSE).
看看同类模板
对比同技术栈与用途的模板,找到更适合的视觉与内容结构。

react-resume-template
A personal resume website template built with React.js, Typescript, Next.js, and styled with Tailwind css
Next.js · 作品集

nxt-lnk
Custom bio links for creatives who love coding. A perfect custom alternative for linktree, bio and other short…
Next.js · 作品集

sylph
A minimal portfolio template.
Next.js · 作品集

sleek-portfolio
sleek-portfolio 是一个面向开发者个人品牌展示的现代作品集模板,基于 Next.js 15、TypeScript、Tailwind CSS 和 Shadcn UI 构建。
Next.js · 作品集

research-website-template
React + Next.js template for research websites (for PhD students, researchers, etc)
Next.js · 作品集

shadcn-portfolio
shadcn-portfolio 是一个面向开发者的作品集模板,技术栈为 Next.js 15、shadcn/ui、Tailwind CSS 和 Framer Motion。
Next.js · 作品集
