Electric 官网旧版首页深度解析:基于 VitePress 的 Postgres 实时同步产品主页是如何构建的 📅 发布时间:2026/9/16 18:10:19 👁 浏览次数: Electric 官网旧版首页深度解析基于 VitePress 的 Postgres 实时同步产品主页是如何构建的【免费下载链接】electricThe agent platform built on sync.项目地址: https://gitcode.com/GitHub_Trending/el/electricElectric 是构建在同步能力之上的数据层平台其核心使命是把 Postgres 数据的子集同步到本地应用与服务中从而让开发者不必自己实现同步。本文以仓库中 website/old-index.md 这份 VitePress 首页模板为主体逐段拆解它的 frontmatter 配置、Hero 区、特性卡片、动态 Star 计数脚本、Demo 应用瀑布流、社区推文墙与 CTA 落地模块并结合仓库中的 demos 数据加载器、Star 计数工具 与 推文组件 等源码说明一个营销型技术首页从静态内容到数据驱动的完整实现路径。读完本文你可以掌握 VitePress Home 布局的配置语法、基于数据文件驱动的内容动态化思路以及如何把 GitHub API、本地缓存和组件化布局组合成一个高转化率的开源项目首页。一、页面定位一份被新首页替代的旧版 Landing 页在动手读代码之前先明确这份文件的定位。website/old-index.md是 Electric 官网在转向Agent 平台定位之前使用的首页模板文件名中的old-前缀已经说明它已被取代。当前生效的首页是 website/index.md其 frontmatter 中titleTemplate: :title | Agents on sync、pageClass: home-page正文通过HomePage /组件渲染且注释里明确写着旧版首页的四宫格特性卡片布局已不再反映 agent-platform 定位。因此old-index.md属于历史遗留页面它不再参与当前官网导航也不含任何技术教程性质的说明文字。它是一份 VitePress 首页的完整参考实现记录了Home 布局 脚本增强 数据文件驱动这套典型写法。本文以它为骨架逐一还原其结构与背后的实现细节供需要搭建开源项目官网首页的开发者参考。二、frontmatterVitePress Home 布局的声明方式old-index.md的开头是一段标准的 YAML frontmatter它声明了页面的布局、标题与 Hero 区内容--- layout: home title: ElectricSQL titleTemplate: Sync with your stack description: Sync little subsets of your Postgres data into local apps and services. hero: name: Realtime sync text: for Postgres tagline: - Sync is the best way of building modern apps. Electric solves sync so that you dont have to. image: src: /img/home/zap-with-halo.svg actions: - theme: brand text: Sign-up to Cloud link: /product/cloud/sign-up - theme: brand text: Sign-up link: /product/cloud/sign-up - theme: alt text: target: _blank link: https://github.com/electric-sql/electric - theme: alt text: GitHub target: _blank link: https://github.com/electric-sql/electric ---逐项说明layout: home启用 VitePress 内置的 Home 布局它由hero、features两大块加上页面正文共同组成。title/titleTemplateElectricSQL加上后缀Sync with your stack最终浏览器标签页标题为 ElectricSQL | Sync with your stack。description站点 meta description也是搜索引擎与社交媒体抓取时使用的摘要内容紧扣项目定位——把 Postgres 数据的子集同步到本地应用与服务中。hero.nameHero 区大字标题这里是 Realtime sync。hero.textHero 区副标题这里是 for Postgres。hero.tagline一句凝练的定位语点出同步是构建现代应用的最佳方式Electric 替你解决了同步问题。hero.imageHero 区右侧配图路径为/img/home/zap-with-halo.svg。hero.actions按钮组。theme: brand为主按钮Cloud 注册入口重复出现两次theme: alt为次级按钮GitHub 外链。注意第 25 行的text: 是一个空文本的备用按钮配合后面的脚本会往.actions区域内注入 GitHub 图标这解释了为什么按钮文本留空。这段配置直接对应 VitePress 官方 Home 模板的hero与actions结构任何基于 VitePress 的项目都可以原样复用这套写法。三、features 特性区三条产品线的卡片化表达紧随 frontmatter 的features区块定义了首页中央的三个特性卡片分别对应 Electric 的三大产品线features: - title: Electric details: - span classpara Sync subsets of your Postgres data into local apps and services. /span span classfeature-cta electric-star-count/span icon: src: /img/icons/electric.svg link: /product/electric - title: Cloud details: - span classpara Hosted sync thats blazing fast and scales to millions of users. /span span classfeature-cta sign-up-link/span icon: src: /img/icons/ddn.svg link: /product/cloud - title: PGlite details: - span classpara Sync into a lightweight WASM Postgres with real-time, reactive bindings. /span span classfeature-cta pglite-star-count/span icon: src: /img/icons/pglite.svg link: /product/pglite每张卡片由title、details支持 HTML 片段、iconSVG 图标路径与link点击跳转的产品页组成。details中嵌入了一个特殊的空容器span classfeature-cta electric-star-count/span。这个空容器是留给脚本动态填充内容的锚点——详见下文第四节。三张卡片恰好对应仓库中的三大资产核心同步引擎electric-sql/electric、托管云服务 Cloud、以及 WASM Postgres 客户端 PGlite。这套空容器 脚本填充的模式是整个首页最具工程参考价值的部分它把静态的 frontmatter 内容与运行时动态数据解耦页面在构建时是纯静态的运行时再由浏览器脚本补充实时数据。四、脚本增强Star 计数与按钮注入的运行时逻辑script setup是这份首页模板里技术含量最高的部分。它通过 VitePress 的onMounted钩子在页面挂载后执行以下工作给 GitHub 外链按钮注入图标遍历.actions a[href^https://github.com]为每个链接前置插入带vpi-social-github类名的图标元素。给 Cloud 卡片注入注册按钮向span.feature-cta.sign-up-link容器内插入一个指向/product/cloud/sign-up的 Sign up 按钮。渲染 Star 计数分别调用renderStarCount(electric, electric-sql/electric, ...)与renderStarCount(pglite, electric-sql/pglite, ...)把 GitHub Star 数动态写入对应卡片。renderStarCount的核心逻辑如下const renderStarCount async (containerClass, repoPath, initialStarCount) { let container document.querySelector(span.feature-cta.${containerClass}-star-count) if (!container) return let linkEl container.querySelector(a) if (linkEl) return linkEl document.createElement(a) linkEl.setAttribute(href, https://github.com/${repoPath}) linkEl.setAttribute(_target, _blank) linkEl.classList.add(VPButton, medium, alt) linkEl.innerHTML span classvpi-social-github/span GitHub const countEl document.createElement(span) countEl.classList.add(count) countEl.innerHTML formatStarCount(initialStarCount) linkEl.append(countEl) container.append(linkEl) const count await getStarCount(repoPath, initialStarCount) countEl.innerHTML formatStarCount(count) }实现要点幂等保护先检查容器内是否已存在a存在则直接返回避免重复渲染。先展示初始值再异步刷新先用initialStarCount来自构建期数据渲染计数随后await getStarCount(...)拉取实时值并更新实现无闪烁渐进增强。计数格式化formatStarCount把原始数值转换为(☆ X.Xk)的紧凑格式例如 12345 会显示为(☆ 12.3k)。其中getStarCount定义在 website/src/lib/star-count.ts它是一个带localStorage 缓存的封装export async function getStarCount(repoPath: string, currentCount: number) { const ttl 3_600 // 1 hour return localStorageCache(starCount.${repoPath}, ttl, async () { return await fetchStarCount(repoPath, currentCount) }) } export async function fetchStarCount(repoPath: string, currentCount: number) { const url https://api.github.com/repos/${repoPath} const response await fetch(url) if (response.ok) { const data await response.json() return data.stargazers_count } return currentCount }每次访问首页最多触发一次 GitHub API 请求结果在localStorage中以starCount.repoPath为键缓存 1 小时TTL 3600 秒过期后才重新拉取。请求失败时回退到传入的currentCount保证页面任何情况下都能展示数字。该模块还内置了一组 fallback 常量Electric 为 9000、PGlite 为 14000、TanStack DB 为 3000、durable-streams 为 1000供构建期数据不可用时兜底。构建期的初始 Star 数据来自 website/data/count.data.ts——一个 VitePress 数据加载文件其load()在构建阶段调用fetchStarCounts()批量抓取四个仓库的 Star 数并把结果注入页面。这形成了构建期静态注入 运行期增量刷新 失败回退的三级数据链路是营销型首页展示动态指标的标准做法。五、Demo 区由数据文件驱动的应用案例网格首页正文的features-content区块展示了 Demo apps 标题与一个demos-grid homepage网格通过DemoListing组件渲染homepage_demos列表div classfeatures-content ## Demo apps See the kind of applications you can build with Electric and what they feel like to use. /div div classdemos-grid homepage DemoListing v-for(demo, index) in homepage_demos :demodemo :keyindex / /divhomepage_demos由 website/data/demos.data.ts 在构建期从website/sync/demos/*.md的 frontmatter 中提取生成。加载器的工作方式监听../sync/demos/*.md目录读取每个 demo 文件头部的 YAML frontmatter依据demo: true过滤出演示应用依据homepage: true过滤出首页要展示的卡片再按order字段升序排序每条记录自动补上link: /sync/demos/slug作为详情页地址。以首页重点展示的 Linearlite 演示 为例其 frontmatter 声明--- title: Linearlite description: - Local-first project management app built with Electric and PGlite. demo: true homepage: true order: 10 ---也就是说首页 Demo 网格里的每一张卡片都不是硬编码的——只要在 website/sync/demos 目录新增一个带homepage: truefrontmatter 的 Markdown 文件首页会自动出现新卡片。仓库目前在该目录下提供了 19 个示例Linearlite、todo-app、gatekeeper-auth、phoenix-liveview、proxy-auth、redis、tanstack、yjs 等对应 examples 目录下可直接运行的工程代码例如todo-app 示例经典的 TodoMVC核心 Electric 代码集中在src/routes/index.tsx演示形状订阅与实时写入linearlite 示例local-first 项目管理应用基于 Electric 与 PGlite演示大数据集下的离线能力与本地实时响应write-patterns 示例聚焦写入模式涵盖冲突处理与并发策略。这种Markdown frontmatter 声明 构建期数据加载器聚合 组件渲染的内容管线让运营人员只需维护 demo 的 Markdown 元数据无需触碰 Vue 组件代码即可控制首页内容呈现。六、推文墙Masonry 瀑布流与响应式隐藏首页紧接着 Demo 网格的部分是MasonryTweets :tweetstweets /用于展示社区成员的推文。推文列表同样内联定义在script setup中const tweets [ {name: kyle, id: 1825531359949173019}, {name: fabio, id: 1823267981188542525}, {name: next, id: 1823015591579472318, hideMedium: true}, ... ]每条推文携带id推文 ID与可选的hideMedium/hideSmall响应式隐藏标记。组件实现在 website/src/components/MasonryTweets.vue关键细节基于vue-tweet组件嵌入推文传入tweet-id、aligncenter、conversationnone、themedark与dnt不追踪参数瀑布流布局通过 CSScolumns属性实现默认4 300px即每列最小 300px、最多 4 列由于 iframe 形式的推文加载时序不定组件在tweet-load-success/tweet-load-error事件后多次触发forceResize()分别在 0ms、6s、12s、20s 补偿调整手动修正 wrapper 高度防止页面滚动条跳动在window resize时同样会防抖触发重排通过.tweet-hide-md/.tweet-hide-sm媒体查询1082px 与 807px 断点在中等屏与窄屏上隐藏部分推文控制移动端首屏长度。这段代码的工程价值在于它演示了第三方嵌入内容Twitter iframe与响应式排版共存时的经典痛点与解法内容加载完成时机不可控 → 需要事件驱动的高度重算多列布局下内容高度不可预测 → 需要容器高度显式补偿。七、收尾 CTA技术与转化并重的落地区块页面底部依次渲染HomeYourStackSimplified与HomeCTA两个 partial以及UseCases :casesuseCases /用例区。HomeYourStackSimplified的内容定义在 website/src/partials/home-your-stack-simplified.mdElectric solves data loading, cache invalidation, scaling and availability. Making your software simpler, faster and more reliable.一句话讲清了产品价值主张Electric 替你解决数据加载、缓存失效、扩展性与可用性这正是构建实时应用时最耗时的四类基础设施问题。HomeCTA定义在 website/src/partials/home-cta.md它是一个技术含量很高的 CTA 区块同时给出了三种接入路径HTTP API通过 HTTP 同步 API 直接订阅形状客户端库与框架 Hooks使用 TypeScript 客户端 与 React 集成本地嵌入式 PGlite 数据库把同步数据落到 PGlite 中获得内置持久化与实时响应。该 partial 内嵌了两个可直接运行的代码示例。第一个是 React 中的useShapeHookimport { useShape } from electric-sql/react const Component () { const { data } useShape({ url: ${BASE_URL}/v1/shape, params: { table: items } }) return ( pre{ JSON.stringify(data) }pre ) }第二个是通过 /src/partials/sync-into-pglite.tsx引入的 PGlite 同步示例代码块由构建器从源码文件直接注入保证与仓库实现同步。useShape对应仓库中 electric-sql/react 这一包的 API——它把订阅某个 Postgres 表的同步形状封装成声明式的 Hook数据变化时组件自动重渲染。CTA 区最终还提供了 Quickstart、API docs、Demos 等入口按钮。useCases数据来自 website/data/use-cases.data.ts加载器监听../use-cases/*.md过滤出homepage: true的用例并按homepage_order排序与 Demo 数据管线同构。八、数据驱动首页的实现要点总结从old-index.md及其配套源码中可以提炼出这套 VitePress 首页的四条核心工程经验frontmatter 是首页的配置层layout: home、hero、actions、features全部声明式配置改文案不动组件。数据加载器是首页的内容管线count.data.tsStar 数、demos.data.ts演示应用、use-cases.data.ts用例在构建期从 Markdown frontmatter 与外部 API 聚合数据运营只需维护 Markdown。空容器 脚本注入实现运行时增强feature-cta空 span 作为锚点onMounted中动态插入按钮与实时数据配合 localStorage 缓存与失败回退保证静态页面也能展示动态指标。组件化处理第三方内容与响应式MasonryTweets.vue演示了 iframe 内容高度补偿与多断点隐藏的完整解法。需要注意的是本仓库当前生效的官网首页是 website/index.md它已转向 Agents on sync 的新定位old-index.md作为历史模板保留了上述完整实现是研究 VitePress 营销型首页工程化写法的绝佳样本。若要在自己的 VitePress 项目中复现这套首页可直接参照本文拆解的结构frontmatter 声明 Hero 与特性、数据加载器驱动内容网格、onMounted脚本做运行时增强、组件处理第三方嵌入与响应式布局。【免费下载链接】electricThe agent platform built on sync.项目地址: https://gitcode.com/GitHub_Trending/el/electric创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考