Skip to content
YIZE
P.011 / PROJECT2026

个人数字空间Personal Digital Space

Personal Digital Space个人数字空间

就是本站。它被当作一个要长期存在的档案室来搭,而不是一份作品集;文档也写好了,让下一版比这一版更好写。

This website. Built as a long-lived archive rather than a portfolio, and documented so that the next version is easier to write than this one was.

角色Role
设计与开发Design and development
类型Type
软件Software · 网页Web
年份Year
2026
  • Next.js
  • TypeScript
  • Tailwind CSS
  • MDX
  • KaTeX
Project Screenshot
P.011-A
Project Screenshot · placeholder
目录Contents

这个站想活多久

它要回答的不是「怎么把东西放上去」,而是五年之后它还在不在。作品收集站的失效方式很具体:为了给招聘者看而搭一次,之后活往前走了、站没跟着走,于是每两年重建一遍——重建本身才是真正的成本。

所以这一版先把限制定死,其余的都在限制下面长出来:内容放在文件里而不是数据库里;页面是生成的而不是手工拼的;视觉系统小到能记住。三个限制决定了后面几乎所有的选择。

结构

data/            身份、论文、项目元数据、爱好、房间与密钥
content/notes/   笔记正文
content/projects/项目正文

加一个项目是一个 .mdx 文件,加一条笔记也是一个 .mdx 文件——不需要为了加内容去改任何一个组件。目前 28 个页面、42 个组件、22 个 lib 模块,运行期依赖 13 个,其中没有任何一个是状态管理库。

顶栏七项(首页 · 项目 · 学术 · 笔记 · 爱好 · 涂鸦墙 · 留言)的顺序不是随手排的:顺序本身就是论证。它同时是首页编号小节的序、每个页面的印刷号、以及站点地图的序,四处必须一致;移动一项就是改四处。这条约定写在 README 里,因为它是这个站最容易被后来者无意破坏的东西。

语言

中英双语不走 i18n 库。一份内容在 content/ 里是两个文件:<slug>.mdx 是中文,<slug>.en.mdx 是英文。理由有两个——frontmatter 只有一个家,不会出现两段 frontmatter 互相矛盾;两段正文也不会被一个忘记闭合的分隔符截断。中文是这个站先写的那一种语言,英文可以晚一点补齐。

如果英文文件还不存在,页面会把中文正文显示一遍,而不是显示另一半英文——未翻译是诚实的,翻译坏了不是。同一条规则也管着占位:标为占位的链接不会被发布,因为它和真东西无法区分。

它的视觉

概念是「数字珍奇柜 / 档案室」:纸色调、发丝线、印刷号、衬线标题配等宽元数据。由此带来的是一串否定式的规则,写下来是为了让后来的改动有据可依——不用渐变、不用发光、不用玻璃拟态、不用粒子;保持方角,因为圆角卡片是「变成一个仪表盘」的第一步。

主题色的全部定义集中在一个 theme 块里,所以整站可以在一处重新着色。

有锁的部分

公开的部分之外还有几扇门,每扇门配一把自己的密钥:一间网盘、一间魔术基地、一组工具,以及一个后台(涂鸦墙的管理与留言的收件都在里面)。

这一块有两条硬约定。门由服务端决定:每个受保护的路由渲染的是挑战界面替代房间,房间的标记根本不进入服务端交给浏览器的数据;每个受保护的接口自己再查一次。失败朝关闭方向倒:没有配置密钥就是一个空房间加一句说明,绝不会是有一把默认钥匙的房间。

密钥注册表放在一个不进版本库的目录里,权限分层也写进了文档:其中一把能进任何房间并且会被记住,其余的密钥一律只在本次开启期间有效。

这一页不给它们列地址。加锁的房间不放指路牌——没有链接、没有重定向、没有导航项、也没有文案提及。另外,公开发过的旧地址用永久重定向保留,而准备加锁的地址刻意返回 404:重定向是给爬虫看的机器可读地图,不是给打算关门的人用的。

我写下来的取舍

故意没做的东西和做了的东西一样多:账号体系、数据库、文件上传、真实认证。它们各自都有页面和界面,但在底下这层结构还没有证明自己扛得住内容之前把它们做出来,是错的。空的页面也不用灰方块假装有内容,而是打印一张「将会归档什么」的目录表——列在页面上的东西必须有页面。

过程上的顺序是:结构 → 设计系统 → 页面 → 内容 → 最后才是好玩的部分。先写两条真笔记、再定版式,这件事对版式的改动比我盯着它看多久都大。

文档也跟着写了:README 有 12 节,从主题与语言一路写到「现在还有哪些东西是占位」。它存在的理由不是礼节,而是让下一版比这一版好写。

这一页不写的

源码仓库与部署流水线。这一页写的是这个站的判断,不是它的运维。

这一页也不需要截图——你正在看的就是它。

目录Contents

How long this site is meant to last

The question it answers is not "how do I put things online" but "will this still be here in five years". Portfolio sites fail in one specific way: they get built once, for an audience of recruiters, then the work moves on and the site does not — so it gets rebuilt every two years, and the rebuilding is the actual cost.

This version therefore fixes the constraints first and lets everything else grow underneath them. Content lives in files, not in a database. Pages are generated, not assembled by hand. The visual system is small enough to remember. Those three decisions account for almost every other choice here.

Structure

data/              identity, papers, project metadata, hobbies, rooms and keys
content/notes/     note bodies
content/projects/  case-study bodies

Adding a project is one .mdx file. Adding a note is one .mdx file. No component is edited to add content. Today that is 28 routes, 42 components and 22 lib modules on 13 runtime dependencies — none of which is a state management library.

The seven items in the header (Home · Projects · Academic · Notes · Hobbies · Wall · Letter) are not in that order by accident: the order is itself an argument. It is simultaneously the numbering of the home page's sections, the printed number on each page, and the order in the sitemap. Moving one item means changing four places. That rule is written into README, because it is the thing a later hand is most likely to break without noticing.

Language

Bilingual content does not use an i18n library. One document in content/ is two files: <slug>.mdx in Chinese, <slug>.en.mdx in English. Two reasons: front matter has exactly one home and cannot contradict itself, and two bodies cannot be truncated by a separator someone forgot to close. Chinese is the language this site is written in first; English is allowed to arrive later.

When the English file does not exist yet, the page shows the Chinese body twice over rather than showing half an English one — untranslated is honest, badly translated is not. The same rule governs placeholders: a link marked as a placeholder is not published, because it cannot be told apart from a real one.

The visual system

The concept is a digital cabinet of curiosities, or an archive: paper tones, hairline rules, filing numbers, serif headings against monospaced metadata. What that produces is mostly a list of prohibitions, written down so later changes have something to argue against — no gradients, no glow, no glassmorphism, no particles, and square corners, because a rounded card is the first step toward becoming a dashboard.

Every theme colour is defined in one theme block, so the whole site can be recoloured from one place.

The locked part

Beyond the public pages there are a few doors, each with its own key: a private drive, a studio, a set of tools, and an owner's desk that carries the wall's moderation and the message inbox.

Two rules hold that part together. The door is a server decision: every protected route renders the challenge instead of the room, so the room's markup never enters what the server sends to the browser, and every protected API checks again on its own. Failure falls closed: an unconfigured key means an empty room with a note, never a room with a default key in it. The key register lives in a directory that is not in version control, and the permission split is documented: one key opens any room and is remembered, every other key lasts only for the session.

This page does not print their addresses. A locked room gets no signpost — no link, no redirect, no navigation entry, no mention in prose. Addresses that were public once are kept alive with a permanent redirect; addresses about to be locked deliberately return 404. A redirect is a machine-readable map for crawlers, not a favour to whoever wanted the door shut.

The trade-offs I wrote down

What is deliberately missing is as much as what is here: accounts, a database, file uploads, real authentication. Each of them has a page and an interface, and each would have been the wrong thing to build before the structure underneath had proven it can carry the content. Empty pages do not fake it with grey boxes either — they print a table of contents saying what will be filed there, because anything listed on a page has to have a page.

The order of work was: structure, then the design system, then pages, then content, then the parts that are actually fun. Writing two real notes before settling the layout changed the layout more than any amount of staring at it did.

The documentation was written too: README runs to twelve sections, from theme and language all the way to "what is still a placeholder". It exists so the next version is easier to write than this one, not as a formality.

What is not on this page

The source repository and the deployment pipeline. This page is about the site's judgements, not its operations.

It also does not need a screenshot — you are looking at it.