我在这里写设计、AI 的使用、数字产品、房地产,以及在迪拜的家庭生活。我需要一个能让这些内容共存的网站:文章、照片、工作项目和交互工具都可以放在这里。

最初使用的是 Framer

我的第一个网站是用 Framer 搭建的。它至今仍可通过 nevskii.me 访问,作为我的产品设计作品集。

后来,我在 Ghost Pro 上另外开了一个博客。我购买了 Priority Vision 的 Scope 主题,并开始修改它。主题的开发通过 GitHub 和 GitHub Actions 进行。与此同时,我持续写作、积累内容,每月为 Ghost Pro 支付 35 美元。

随着时间推移,网站有了自己的设计和修改历史。再次迁移时,我希望把这些都保留下来。

AI 概念插画:作者坐在笔记本电脑前,周围是 Framer 作品集、使用 Scope 主题的 Ghost 博客和 GitHub Actions。
网站也有版本历史。它始于 Framer 和 Ghost

为什么转向 Astro

后来,我决定用 Astro 搭建网站会更简单。我移植了主题的设计,继续通过代码完善它。

Astro 用组件组装页面,并能提前生成完整的 HTML。这很适合博客:文章正文、照片和导航可以在布局完成后直接交给浏览器。读者不必等待 JavaScript 在自己的设备上构建页面。

迁移过程中,需要移植文章模板、文章列表、图库、菜单,以及浅色和深色主题。不同页面可以采用不同的布局。图文文章与短笔记信息流不必长得一样。

博客的外观仍以 Scope 为基础,但模板现在运行在 Astro 中。Framer 继续作为独立的作品集,也是视觉参考之一。

AI 概念插画:Framer 和 Ghost 页面转化为 Astro 组件和生成好的 HTML 页面。
外表还是那个博客,内部已经换成 Astro。搬家,家具照旧

后来有了 EmDash

EmDash 的第一个版本出现后,我决定把所有内容迁移过去。直到现在,我们仍在进行迁移,并继续开发网站。

EmDash 充当网站的 CMS,也就是内容管理系统。我在其中编辑文章、页面及其译文,修改图片说明和界面中的公共文案。每份内容都有草稿和已发布版本。

代码与内容相互分离。Astro 组件决定文章或图库如何呈现,EmDash 存储其中的内容。因此,修改一段文字不需要去模板文件中寻找对应段落,调整设计也不应该产生另一份文章副本。

AI 概念插画:EmDash 工作区中有文章、翻译、媒体库和发布设置。
在 EmDash 中,改一个逗号不用再翻遍组件。这正是我之前缺少的

各部分如何连接

网站分为编辑器、构建流程和公开版本。

我在 EmDash 编辑器中修改内容。文字和发布信息存储在 Cloudflare D1 数据库中。上传的媒体使用 Cloudflare R2 对象存储:照片和其他文件与网站代码分开保存。

每次发布网站时,Astro 会取得已发布内容的快照,并据此生成页面。同时准备译文链接、站点地图和搜索索引。草稿不会进入这次构建。

生成的网站运行在 Cloudflare Workers 上,通过 Cloudflare 的基础设施分发。普通文章页面不需要在每次打开时访问编辑器或数据库,因为它的 HTML 已经生成。搜索使用的是同一发布版本的索引。

一份内容会经过以下流程:

EmDash → D1 中的已发布版本 → Astro 构建 → Cloudflare → 读者

图片会单独处理。原始文件保留下来,同时为页面生成尺寸合适的图片版本。它们通过 cdn.nevsky.ae 分发,这样小卡片就不必加载一张完整尺寸的照片。

AI 概念架构图:EmDash、Cloudflare D1 和 R2、Astro 构建、Workers、CDN 及读者看到的页面。
表面上是一篇文章,底层是 D1、R2、Astro 和 Cloudflare。读者不必了解这些

如果依赖项没有变化,构建流程可以复用已经检查过的页面和资源。公共组件或网站结构发生变化时,可能需要完整地重新构建。

哪些地方使用 Svelte

项目使用 Svelte 处理更复杂的交互。它用于某些独立展示形式中的搜索和信息流筛选:读者可以修改搜索词或分类,更新结果,并将所选参数保存在页面地址中。

Astro 允许单独引入这些组件。文章仍然是普通的 HTML 页面,而交互区块只在需要的位置加载自己的 JavaScript。主博客并不是每个页面都加载 Svelte。

菜单、主题切换和其他小功能可以使用原生 JavaScript,不需要单独的 Svelte 组件。

AI 概念插画:静态 HTML 文章旁是用 Svelte 实现的交互式筛选和搜索。
不是每个按钮都需要框架。我只在真正需要交互的地方保留了 Svelte

一份内容,七种语言

网站支持俄语、英语、阿拉伯语、中文、法语、德语和西班牙语。俄语是内容的源语言。

在 EmDash 中,一篇文章保存为一份文档。它拥有统一的区块和图片顺序,而正文、标题、图片说明和 SEO 字段分别有对应的语言版本。

这样可以保持译文之间的关联。当我调整照片顺序时,不需要在七篇独立文章里手动重复同样的操作。每种语言版本仍可以拥有自己的地址和发布状态。

页面包含对应译文的链接,以及供搜索引擎使用的 hreflang 标记。阿拉伯语版本考虑了从右到左的书写方向。某个译文发布后,语言切换器就会将读者带到当前内容的对应语言版本。

AI 概念插画:同一篇文章的共用布局以俄语、英语、阿拉伯语、中文、法语、德语和西班牙语呈现。
七种语言,一份文档。我不想再把同一张照片挪七遍了

设计与代码

Scope 的字体排版和结构仍是网站设计的基础。公共颜色、按钮和其他重复使用的元素都记录在设计系统中。

目前,主要强调色是 #46a758。网站使用本地提供的 Geist 和 Geist Mono 字体,支持浅色和深色主题,图标来自 Remix Icon。样式使用普通 CSS 编写。

配色和组件示例集中展示在公开的设计系统页面上。技术规则和设计令牌记录在 design.md 中,让新页面使用一致的颜色、尺寸和按钮状态。

AI 概念插画:网站设计系统,包括配色、Geist、CSS 令牌、图标和组件库。
Geist、Remix Icon,还有我的绿色 #46a758。终于,一切都遵循同一套规则

2026 年 10 月的技术栈

项目基于 Astro 7.3.8 和 EmDash 1.2.0。复杂交互视图使用 Svelte 5.57.1,应用语言为 TypeScript 6.0.3,通过 @astrojs/cloudflare 14.3.4 接入 Cloudflare。EmDash 编辑器使用 React 19.2.4,全文编辑模式基于 Ghost Koenig 和 Lexical。这些是项目在 2026 年 10 月 19 日所使用的依赖版本。

每一层都有具体职责。Astro 负责 HTML 和模板,EmDash 负责编辑内容和修订版本,Svelte 负责交互组件。Cloudflare Workers 运行服务端代码,D1 保存编辑数据,R2 保存媒体和私有构建包。设计使用普通 CSS,包括变量、响应式网格、组件状态和不同的页面编排。

为什么选择这套技术栈

博客的大部分内容在读者发出请求前就已确定。标题、文章、照片和文章列表都可以提前生成。因此,主站通过 Cloudflare Workers Assets 提供静态 HTML。公开运行环境不连接 D1:编辑器和构建需要数据库,读文章时则不会查询 CMS。

Astro 也能承载复杂界面。在独立视图中,Svelte 组件负责交互信息流和显示参数。普通文章无需水合,搜索、菜单和主题切换各有小型脚本。这样我可以根据组件行为选择工具,也能控制读者需要加载多少 JavaScript。

作为数据模型的编辑文档

EmDash 中的一篇内容包含 locales、fields、共享的 blocks 数组,以及带有布局绑定的 presentation。每个内容块都有稳定 ID、共享结构和媒体,文字保存在不同语言的单元格中。图库共用一份图片顺序,说明和 alt 文本分别本地化。移动一张照片,只需修改一个结构,所有译文便会使用相同顺序。

俄语是源语言。英语、阿拉伯语、中文、法语、德语和西班牙语版本都存放在同一文档内,每种语言有自己的路径和发布状态。源文变化后,可以通过 sourceHash 标记过时的译文。导入翻译时会检查 ID、源文哈希和文本片段数量,防止模型回答改变内容结构或丢失图片。

共用标签、菜单和设置也由 EmDash 管理。内容可以引用其他文档中的共享字段,公开视图从已发布文档解析这些引用。因此,一个标签不会变成七份分别编辑的副本,修改导航也无需到模板中寻找文字。

自行开发的编辑器插件

我为这套模型开发了原生插件 nevsky-multilingual 1.0.0,接入编辑器以及 beforeSave、beforePublish 和 beforeSchedule 检查。它验证文档结构、语言版本、路径和必填数据。翻译直接添加在内容内部,发布或撤下内容后,插件会向发布系统发送信号。

全文模式使用 Ghost Koenig 编辑器,同时保留块编辑模式,两种模式操作的是同一文档。另一个插件 nevsky-grid 0.1.0 将内容与布局关联起来,检查页面编排所属的内容、块引用和布局修订版本。调整布局不会更换编辑内容的源头。

AI 帮助准备文字和翻译,插件则在保存和发布前检查结果。我可以在 ChatGPT 的项目或聊天中准备文章,按我们的 humanizer 规则编辑,再将其放入一篇多语言内容。当前尚未配置内置的服务端 AI 翻译提供方,实际流程使用事先准备并审核过的译文。

AI 概念插画:编辑文档、带稳定 ID 的内容块,以及 nevsky-multilingual 和 nevsky-grid 插件的检查。
AI 帮忙写作和翻译,插件再检查内容在过程中有没有走样

构建与发布如何运作

构建只通过 live_revision_id 读取原生已发布修订版,以及与分类、标签和作者的已发布关系。草稿不会进入导出数据。发布前会记录源码版本和已发布数据的指纹。如果构建过程中有人发布新内容或修改代码,后续检查会停止这次已经过时的发布。

为重复构建,我开发了页面级依赖追踪。渲染期间,适配器记录 SQL 查询、参数和结果哈希。下一次发布时,在新快照上重新执行这些查询;结果发生变化,页面就需要重新渲染,未变的 HTML 则可以复用。追踪涵盖信息流包含的内容及其顺序、空结果、作者、公共字段和相关卡片。代码、依赖、环境或路由清单变化时,系统会进行完整重建。

最终生成包含 HTML、搜索索引、样式、媒体和机器可读文件的完整包。先在本地检查,再上传新的 Worker 版本。上传后检查公开 URL 和发布元数据,检查失败时可以回退到上一版本。源码与已发布数据还会在上传前再次核对。

Cloudflare、云构建与聊天工作流

编辑器、D1、R2 和公开站点已经运行在 Cloudflare 上,代码位于 GitHub。用于云发布的私有 publisher 建立在 Workers 和 Durable Objects 上,能够接收 EmDash 事件、合并时间相近的发布,并通过 GitHub Actions 启动经过检查的构建。目前我关闭了自动触发,生产发布由终端手动执行,使用同样的检查。

验收通过的构建包可以保存在使用 AES-256-GCM 加密的私有 R2 缓存中。包内包含生成结果、依赖和校验和,不包括草稿、CMS 数据库或秘密信息。复用前核对源码、环境与文件完整性。这样的包支持在其他环境继续构建;新的操作系统或工具链版本,需要先建立自己的完整基线。

我正在把更多工作步骤迁移到云端,让网站任务能从项目或聊天中启动,不必依赖工作电脑一直开机。准备文字、修改代码和上线仍然是不同操作。对话界面依然需要草稿、变更检查和发布控制。

AI 概念插画:GitHub、构建检查和 Cloudflare 组成网站发布流程,发布须手动确认。
“Deploy”按钮看起来很诱人。不过,我暂时仍把自动发布关着

构建中的技术 SEO

每个已发布语言版本都有独立 URL、canonical、lang,以及指向对应译文的 hreflang。默认语言使用 x-default,阿拉伯语页面设置 dir="rtl"。标题、description、Open Graph 和 Twitter 元数据都与可见正文来自同一个 EmDash 文档。

JSON-LD 描述 WebSite 和具体页面类型:文章使用 BlogPosting,作者使用 ProfilePage,合集使用 CollectionPage,普通页面使用 WebPage。作者和日期来自编辑数据。站点地图按内容类型拆分,RSS 根据已发布内容生成。构建检查会遍历内部链接、canonical、hreflang 和 sitemap URL 的完整关系图,检查范围超过几个 meta 标签是否存在。

为 LLM 准备的内容

已发布内容会自动生成页面的 Markdown 版本,以及七种语言的 llms.txt 和 llms-full.txt。短文件提供个人介绍、语言和内容链接,完整文件提供扩展文本输出。机器可读版本与网站使用同一编辑源头,我不会另外维护一份面向机器人的个人介绍。

AI 工具可以取得带有标题、链接和来源 URL 的文字,无需解析页面界面。构建发布时,整套关联文件会一起更新。对我来说,这里把内容编辑、SEO 和 AI 联系起来:一篇内容需要认真地呈现给读者、搜索爬虫和模型。

AI 概念插画:文章通过 HTML、SEO 元数据、Markdown 和 llms.txt 文件提供给读者、搜索引擎和语言模型。
人读 HTML,搜索引擎解析标记,LLM 获取 Markdown。来源都是同一个

媒体交付与变更验证

媒体与 HTML 分开提供。构建选择响应式图片版本,保留原文件链接,并检查衍生文件。采用无损优化时,会比较解码后的像素。本地 Geist 和 Geist Mono 字体会准备字符覆盖,缺少的字符使用系统字体回退。Remix Icon 通过本地 CSS 蒙版引入。

修改需要通过类型检查、数据模型与发布测试、各视图构建、依赖审计和浏览器场景。上线版本还会单独检查:本地构建成功,不代表正确的 HTML、字体和译文已经到达公开地址。每次发布都会记录源码版本、内容指纹和验证结果。

我如何继续维护网站

我在 EmDash 中编辑内容,将代码保存在 GitHub 上。我使用 AI 工具辅助编写代码,并通过构建、测试和浏览器检查来验证修改。早在开发 Ghost 主题时,我就使用了 GitHub Actions。现在的项目也支持单独通过终端发布,在上传前和部署后进行检查。

保存文字会生成草稿。在 EmDash 中发布内容,与将新版本部署到公开网站,是两个独立的步骤。目前,网站发布在检查完成后手动启动。

迁移还在继续。七种语言的内容发布、共享内容库,以及同一批内容的多种展示方式都已经运行起来。我会在这个基础上继续完善编辑器、设计和交互页面。

我能基于这套方案构建什么

我可以为作者、工作室或企业设计并开发类似网站:从原来的 CMS 迁移内容,保留 URL,配置多种语言,并根据实际内容工作方式调整编辑器。如果项目需要目录或复杂展示,还可以加入交互组件和定制页面编排。

这项工作结合了我的产品设计经验与 AI 辅助开发。我可以负责完整流程:确定内容结构、构建界面、编写编辑插件、配置云交付,并验证上线结果。如果你需要这样的网站,可以在 Telegram 上联系我,介绍你想发布什么,以及准备怎样使用它。