feat(site): refine homepage messaging and accessibility

This commit is contained in:
tianma-if committed 2026-08-29 11:44:38 +08:00
1 parent caea154b91
commit d03554f1ee
13 files changed
+85 -179

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
/_astro/*
Cache-Control: public, max-age=31536000, immutable
+1
View File
@@ -0,0 +1 @@
https://www.edgeever.org/* https://edgeever.org/:splat 301
+5 -5
View File
@@ -16,17 +16,17 @@ const copy = siteCopy[locale].nav;
href="https://www.dujin.org/"
target="_blank"
rel="noopener noreferrer"
title="感谢独立博主缙哥哥在项目成长中提出的宝贵建议与教程分享"
class="hover:text-emerald-700 transition-colors"
aria-label={locale === "en-US" ? "Thanks to independent blogger Dujin for product feedback and tutorials" : "感谢独立博主缙哥哥在项目成长中提出的宝贵建议与教程分享"}
class="inline-flex min-h-11 sm:min-h-0 items-center hover:text-emerald-700 transition-colors"
>
{locale === "en-US" ? "Thanks" : "特别致谢"}
</a>
<span class="text-slate-300">•</span>
<a href={getLocalizedPath(locale, "/contact")} class="hover:text-emerald-700 transition-colors">
<a href={getLocalizedPath(locale, "/contact")} class="inline-flex min-h-11 sm:min-h-0 items-center hover:text-emerald-700 transition-colors">
{copy.contact}
</a>
<span class="text-slate-300">•</span>
<a href={getLocalizedPath(locale, "/privacy")} class="hover:text-emerald-700 transition-colors">
<a href={getLocalizedPath(locale, "/privacy")} class="inline-flex min-h-11 sm:min-h-0 items-center hover:text-emerald-700 transition-colors">
{copy.privacy}
</a>
<span class="text-slate-300">•</span>
@@ -34,7 +34,7 @@ const copy = siteCopy[locale].nav;
href="https://github.com/tianma-if/edgeever"
target="_blank"
rel="noopener"
class="hover:text-emerald-700 transition-colors"
class="inline-flex min-h-11 sm:min-h-0 items-center hover:text-emerald-700 transition-colors"
>
GitHub
</a>
+8 -110
View File
@@ -8,8 +8,6 @@ import { getLocalizedPath, getSiteLocale, siteCopy } from "@/i18n";
const locale = getSiteLocale(Astro.url.pathname);
const copy = siteCopy[locale].hero;
const agentPromptText = copy.agentPromptText;
---
<main class="relative grid gap-8 lg:gap-10 lg:grid-cols-2 place-items-center pt-4 pb-10 md:pt-10 md:pb-16 overflow-hidden max-w-full">
@@ -23,8 +21,8 @@ const agentPromptText = copy.agentPromptText;
<div class="relative z-20 w-full max-w-full flex flex-col items-start min-w-0">
{copy.badgeText && (
<a
href={`${getLocalizedPath(locale, "/")}blog?tag=migration`}
class="animate-rise flex items-center gap-2 max-w-full min-w-0 px-3 py-1.5 mb-5 md:mb-6 text-xs text-brand bg-brand/5 border border-brand-border/30 hover:border-brand/40 hover:bg-brand/10 rounded-full backdrop-blur-sm select-none hover:-translate-y-0.5 transition-all duration-300 group/badge cursor-pointer"
href={`${getLocalizedPath(locale, "/")}#platforms`}
class="animate-rise flex min-h-11 sm:min-h-0 items-center gap-2 max-w-full min-w-0 px-3 py-1.5 mb-5 md:mb-6 text-xs text-brand bg-brand/5 border border-brand-border/30 hover:border-brand/40 hover:bg-brand/10 rounded-full backdrop-blur-sm select-none hover:-translate-y-0.5 transition-all duration-300 group/badge cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand/40 focus-visible:ring-offset-2"
style="animation-delay: 0ms;"
>
<span class="relative flex h-2 w-2 shrink-0">
@@ -78,37 +76,9 @@ const agentPromptText = copy.agentPromptText;
</a>
</div>
<!-- Agent Terminal Prompt Pill (Pireel style) -->
<!-- Multi-Platform Client Badges -->
<div class="animate-rise mt-6 w-full max-w-full sm:max-w-lg z-30 relative" style="animation-delay: 240ms;">
<!-- Hidden Textarea for clean text copying -->
<textarea id="agent-prompt-textarea" class="sr-only" aria-hidden="true" readonly>{agentPromptText}</textarea>
<div class="flex flex-col gap-1.5 w-full max-w-full">
<button
type="button"
id="copy-agent-prompt"
aria-label={copy.agentInstall}
class="group relative flex items-center justify-between gap-2 w-full max-w-full rounded-2xl sm:rounded-full border border-slate-200/90 bg-white/90 backdrop-blur hover:border-emerald-500/60 p-2 sm:p-1.5 sm:pl-4 transition-all hover:shadow-md cursor-pointer text-left select-none z-30 min-w-0"
>
<div class="flex items-center gap-2 overflow-hidden pointer-events-none min-w-0 flex-1">
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="text-emerald-600 shrink-0"><path d="M12 19h8"></path><path d="m4 17 6-6-6-6"></path></svg>
<span class="font-mono text-[10.5px] sm:text-xs text-slate-700 font-medium truncate min-w-0 flex-1">
{copy.terminalCmd}
</span>
</div>
<span class="copy-icon-box grid h-7 w-7 shrink-0 place-items-center rounded-full bg-slate-100 text-slate-500 group-hover:bg-emerald-50 group-hover:text-emerald-700 transition-colors pointer-events-none">
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"></rect><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"></path></svg>
</span>
<span id="prompt-tooltip" class="absolute -top-10 right-2 sm:right-4 hidden rounded-lg bg-emerald-700 px-3 py-1.5 text-xs font-semibold text-white shadow-lg transition-opacity pointer-events-none z-50 flex items-center gap-1.5">
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"></polyline></svg>
<span>{copy.copySuccess}</span>
</span>
</button>
<span class="text-[10.5px] sm:text-[11.5px] text-slate-600 pl-2 sm:pl-4 font-medium select-none truncate max-w-full">{copy.terminalSub}</span>
</div>
<!-- Multi-Platform Client Badges -->
<div class="mt-5 pt-4 border-t border-slate-200/60 flex flex-wrap items-center gap-2">
<div class="pt-4 border-t border-slate-200/60 flex flex-wrap items-center gap-2">
<span class="text-[11px] font-semibold text-slate-500 mr-1 select-none">
{locale === "en-US" ? "Get Apps:" : "获取客户端:"}
</span>
@@ -116,7 +86,7 @@ const agentPromptText = copy.agentPromptText;
href="https://github.com/tianma-if/edgeever/releases"
target="_blank"
rel="noopener"
class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-lg bg-slate-100/90 hover:bg-emerald-50 hover:text-emerald-700 hover:border-emerald-300 border border-slate-200/80 text-[11px] font-medium text-slate-700 transition-all shadow-2xs"
class="inline-flex min-h-11 sm:min-h-0 items-center gap-1.5 px-2.5 py-1 rounded-lg bg-slate-100/90 hover:bg-emerald-50 hover:text-emerald-700 hover:border-emerald-300 border border-slate-200/80 text-[11px] font-medium text-slate-700 transition-all shadow-2xs"
>
<Icon name="bx:bxl-apple" class="w-3.5 h-3.5" />
<span>macOS</span>
@@ -125,7 +95,7 @@ const agentPromptText = copy.agentPromptText;
href="https://apps.apple.com/us/app/edgeever/id6792625631"
target="_blank"
rel="noopener"
class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-lg bg-slate-100/90 hover:bg-emerald-50 hover:text-emerald-700 hover:border-emerald-300 border border-slate-200/80 text-[11px] font-medium text-slate-700 transition-all shadow-2xs"
class="inline-flex min-h-11 sm:min-h-0 items-center gap-1.5 px-2.5 py-1 rounded-lg bg-slate-100/90 hover:bg-emerald-50 hover:text-emerald-700 hover:border-emerald-300 border border-slate-200/80 text-[11px] font-medium text-slate-700 transition-all shadow-2xs"
>
<Icon name="bx:bx-mobile" class="w-3.5 h-3.5" />
<span>iOS</span>
@@ -134,7 +104,7 @@ const agentPromptText = copy.agentPromptText;
href="https://play.google.com/store/apps/details?id=org.edgeever.mobile"
target="_blank"
rel="noopener"
class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-lg bg-slate-100/90 hover:bg-emerald-50 hover:text-emerald-700 hover:border-emerald-300 border border-slate-200/80 text-[11px] font-medium text-slate-700 transition-all shadow-2xs"
class="inline-flex min-h-11 sm:min-h-0 items-center gap-1.5 px-2.5 py-1 rounded-lg bg-slate-100/90 hover:bg-emerald-50 hover:text-emerald-700 hover:border-emerald-300 border border-slate-200/80 text-[11px] font-medium text-slate-700 transition-all shadow-2xs"
>
<Icon name="bx:bxl-android" class="w-3.5 h-3.5" />
<span>Android</span>
@@ -143,7 +113,7 @@ const agentPromptText = copy.agentPromptText;
href="https://chromewebstore.google.com/detail/edgeever-web-clipper/gjadpfmanienmlofajibkfkkpfdkclgo"
target="_blank"
rel="noopener"
class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-lg bg-slate-100/90 hover:bg-emerald-50 hover:text-emerald-700 hover:border-emerald-300 border border-slate-200/80 text-[11px] font-medium text-slate-700 transition-all shadow-2xs"
class="inline-flex min-h-11 sm:min-h-0 items-center gap-1.5 px-2.5 py-1 rounded-lg bg-slate-100/90 hover:bg-emerald-50 hover:text-emerald-700 hover:border-emerald-300 border border-slate-200/80 text-[11px] font-medium text-slate-700 transition-all shadow-2xs"
>
<Icon name="bx:bx-extension" class="w-3.5 h-3.5" />
<span>{locale === "en-US" ? "Clipper" : "剪藏插件"}</span>
@@ -191,78 +161,6 @@ const agentPromptText = copy.agentPromptText;
</div>
</main>
<script is:inline>
(function () {
function fallbackCopyText(text) {
var textarea = document.createElement("textarea");
textarea.value = text;
textarea.style.position = "fixed";
textarea.style.left = "-9999px";
textarea.style.top = "-9999px";
document.body.appendChild(textarea);
textarea.focus();
textarea.select();
var successful = false;
try {
successful = document.execCommand("copy");
} catch (err) {
console.error("execCommand copy error:", err);
}
document.body.removeChild(textarea);
return successful;
}
document.addEventListener("click", function (e) {
var btn = e.target && e.target.closest ? e.target.closest("#copy-agent-prompt") : null;
if (!btn) return;
e.preventDefault();
e.stopPropagation();
var textarea = document.getElementById("agent-prompt-textarea");
var textToCopy = textarea ? textarea.value : "";
if (!textToCopy) return;
var tooltip = document.getElementById("prompt-tooltip");
var iconContainer = btn.querySelector(".copy-icon-box");
function showSuccess() {
btn.classList.add("border-emerald-500", "bg-emerald-50");
if (tooltip) {
tooltip.classList.remove("hidden");
}
if (iconContainer) {
iconContainer.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="text-emerald-600"><polyline points="20 6 9 17 4 12"></polyline></svg>';
}
setTimeout(function () {
btn.classList.remove("border-emerald-500", "bg-emerald-50");
if (tooltip) {
tooltip.classList.add("hidden");
}
if (iconContainer) {
iconContainer.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"></rect><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"></path></svg>';
}
}, 2500);
}
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(textToCopy).then(function () {
showSuccess();
}).catch(function (err) {
console.warn("navigator.clipboard failed, fallback to execCommand", err);
if (fallbackCopyText(textToCopy)) {
showSuccess();
}
});
} else {
if (fallbackCopyText(textToCopy)) {
showSuccess();
}
}
});
})();
</script>
<style>
.hero-slogan {
font-family:
@@ -9,11 +9,11 @@ const copy = siteCopy[locale].marquee;
const doubleItems = [...copy.items, ...copy.items];
---
<section class="mt-12 md:mt-24 w-full overflow-hidden py-8 md:py-10 bg-slate-50/60 border-y border-slate-200/60">
<section id="platforms" class="mt-12 md:mt-24 w-full overflow-hidden py-8 md:py-10 bg-slate-50/60 border-y border-slate-200/60 scroll-mt-6">
<div class="max-w-4xl mx-auto text-center px-4 mb-6 md:mb-8">
<h3 class="text-xl sm:text-2xl md:text-3xl font-extrabold text-slate-900 tracking-tight">
<h2 class="text-xl sm:text-2xl md:text-3xl font-extrabold text-slate-900 tracking-tight">
{copy.title}
</h3>
</h2>
<p class="text-slate-500 text-xs sm:text-sm mt-1.5 md:mt-2 leading-relaxed">
{copy.subtitle}
</p>
@@ -22,8 +22,8 @@ const doubleItems = [...copy.items, ...copy.items];
<!-- Marquee Container with Side Gradient Fades -->
<div class="group relative mt-4 md:mt-6 w-full">
<div class="flex w-max gap-3 sm:gap-4 animate-site-marquee group-hover:[animation-play-state:paused]">
{doubleItems.map((item) => (
<div class={`relative w-64 sm:w-72 shrink-0 rounded-2xl border border-slate-200/80 bg-gradient-to-br ${item.color} p-4 sm:p-5 shadow-xs transition-all duration-300 hover:shadow-md hover:border-emerald-400 bg-white`}>
{doubleItems.map((item, index) => (
<div aria-hidden={index >= copy.items.length ? "true" : undefined} class={`relative w-64 sm:w-72 shrink-0 rounded-2xl border border-slate-200/80 bg-gradient-to-br ${item.color} p-4 sm:p-5 shadow-xs transition-all duration-300 hover:shadow-md hover:border-emerald-400 bg-white`}>
<div class="flex items-center justify-between mb-2.5 sm:mb-3">
<span class="px-2 py-0.5 text-[9.5px] sm:text-[10px] font-bold text-emerald-700 bg-emerald-100/80 rounded-md">
{item.tag}
+27 -12
View File
@@ -104,7 +104,9 @@ const menuitems = [
type="button"
id="mobile-nav-toggle"
aria-label="Toggle mobile menu"
class="lg:hidden p-2 rounded-xl border border-slate-200/80 bg-white/90 text-slate-700 hover:bg-slate-100 focus:outline-none transition-colors"
aria-controls="mobile-nav-menu"
aria-expanded="false"
class="lg:hidden min-h-11 min-w-11 p-2 rounded-xl border border-slate-200/80 bg-white/90 text-slate-700 hover:bg-slate-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand/40 focus-visible:ring-offset-2 transition-colors"
>
<svg id="hamburger-icon" class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M4 6h16M4 12h16M4 18h16" />
@@ -131,7 +133,7 @@ const menuitems = [
{item.children.map((child) => (
<a
href={child.path}
class="px-3 py-2 text-xs font-semibold text-slate-700 hover:text-emerald-700 hover:bg-emerald-50/70 rounded-xl transition-colors"
class="flex min-h-11 items-center px-3 py-2 text-xs font-semibold text-slate-700 hover:text-emerald-700 hover:bg-emerald-50/70 rounded-xl transition-colors"
>
{child.title}
</a>
@@ -142,7 +144,7 @@ const menuitems = [
<li>
<a
href={item.path}
class="block px-3 py-2 text-sm font-semibold text-slate-700 hover:text-emerald-700 hover:bg-emerald-50/70 rounded-xl transition-colors"
class="flex min-h-11 items-center px-3 py-2 text-sm font-semibold text-slate-700 hover:text-emerald-700 hover:bg-emerald-50/70 rounded-xl transition-colors"
>
{item.title}
</a>
@@ -180,19 +182,19 @@ const menuitems = [
var hamburgerIcon = document.getElementById("hamburger-icon");
var closeIcon = document.getElementById("close-icon");
function setMenuOpen(isOpen) {
if (!menu || !toggleBtn) return;
menu.classList.toggle("hidden", !isOpen);
toggleBtn.setAttribute("aria-expanded", String(isOpen));
if (hamburgerIcon) hamburgerIcon.classList.toggle("hidden", isOpen);
if (closeIcon) closeIcon.classList.toggle("hidden", !isOpen);
}
if (toggleBtn && menu) {
e.preventDefault();
e.stopPropagation();
var isHidden = menu.classList.contains("hidden");
if (isHidden) {
menu.classList.remove("hidden");
if (hamburgerIcon) hamburgerIcon.classList.add("hidden");
if (closeIcon) closeIcon.classList.remove("hidden");
} else {
menu.classList.add("hidden");
if (hamburgerIcon) hamburgerIcon.classList.remove("hidden");
if (closeIcon) closeIcon.classList.add("hidden");
}
setMenuOpen(isHidden);
}
// Close all open <details> menus when clicking outside
@@ -202,5 +204,18 @@ const menuitems = [
}
});
});
document.addEventListener("keydown", function (e) {
if (e.key !== "Escape") return;
var toggleBtn = document.getElementById("mobile-nav-toggle");
var menu = document.getElementById("mobile-nav-menu");
if (!toggleBtn || !menu || menu.classList.contains("hidden")) return;
menu.classList.add("hidden");
toggleBtn.setAttribute("aria-expanded", "false");
document.getElementById("hamburger-icon")?.classList.remove("hidden");
document.getElementById("close-icon")?.classList.add("hidden");
toggleBtn.focus();
});
})();
</script>
@@ -1,7 +1,7 @@
---
draft: false
title: "EdgeEver Cloudflare 部署指南:两种方案任选其一"
snippet: "推荐使用 AI Agent 在线部署,也可从 GitHub Fork 后手动完成 Cloudflare 配置。"
title: "Cloudflare 自托管笔记应用部署指南:EdgeEver AI 辅助与手动部署"
snippet: "使用 AI Agent 辅助部署 EdgeEver,或从 GitHub Fork 后手动完成 Cloudflare 配置。"
image: {
src: "/images/agent-deploy.jpg",
alt: "EdgeEver 的两种 Cloudflare 部署方案"
@@ -1,7 +1,7 @@
---
draft: false
title: "从印象笔记迁移到 EdgeEver 指南"
snippet: "通过 EdgeEver MCP、evernote-backup 和 ENEX 导入脚本,把你拥有的笔记资料迁移到自托管实例。"
title: "从印象笔记迁移到自托管笔记应用:EdgeEver ENEX 完整指南"
snippet: "通过 ENEX、evernote-backup 与 EdgeEver MCP,完整迁移笔记、附件、时间信息和嵌套笔记本。"
image: {
src: "/images/evernote-migration.jpg",
alt: "从印象笔记迁移到 EdgeEver"
@@ -1,7 +1,7 @@
---
draft: false
title: "Deploy EdgeEver to Cloudflare: choose one of two options"
snippet: "Deploy online with an AI Agent, or configure EdgeEver manually from a GitHub Fork in your own Cloudflare account."
title: "Deploy a self-hosted notes app on Cloudflare: EdgeEver AI-assisted and manual guide"
snippet: "Deploy EdgeEver with help from an AI Agent, or configure it manually from a GitHub Fork in your own Cloudflare account."
image: {
src: "/images/agent-deploy.jpg",
alt: "Two ways to deploy EdgeEver to Cloudflare"
@@ -1,7 +1,7 @@
---
draft: false
title: "Guide to migrating from Evernote to EdgeEver"
snippet: "Migrate notes you own into a self-hosted EdgeEver instance with EdgeEver MCP, evernote-backup, and the ENEX import script."
title: "How to migrate from Evernote to a self-hosted notes app: EdgeEver ENEX guide"
snippet: "Use ENEX, evernote-backup, and EdgeEver MCP to preserve notes, attachments, timestamps, and nested notebooks."
image: {
src: "/images/evernote-migration.jpg",
alt: "Migrating from Evernote to EdgeEver"
+27 -37
View File
@@ -1,12 +1,10 @@
import { deploymentPrompts } from "./deployment-prompts";
export type SiteLocale = "zh-CN" | "en-US";
export const defaultSiteLocale: SiteLocale = "zh-CN";
export const siteLocaleStorageKey = "edgeever.site.locale";
export const siteLocaleDataAttribute = "data-edgeever-site-locale";
export const siteTaglines = {
"zh-CN": "开源、原生支持 AI、自由部署(Cloudflare 零成本 / Docker)的自托管「印象笔记」替代方案",
"zh-CN": "开源、原生支持 AI、自由部署(Cloudflare 免费额度 / Docker)的自托管「印象笔记」替代方案",
"en-US": "Open-source, AI-native, self-hosted Evernote alternative with Cloudflare & Docker deployment.",
} as const satisfies Record<SiteLocale, string>;
@@ -30,7 +28,7 @@ export const siteCopy = {
"zh-CN": {
layout: {
defaultDescription:
"EdgeEver 是开源、原生支持 AI 的自托管笔记工作区。保留经典印象笔记三栏体验,支持 macOS、iOS、Android 原生端与浏览器剪藏,提供 Cloudflare 零成本免服务器与 Docker 一键自托管。",
"EdgeEver 是开源、原生支持 AI 的自托管笔记工作区。保留经典印象笔记三栏体验,覆盖 macOS、iOS、Android 与浏览器剪藏,支持在 Cloudflare 免费额度内运行或使用 Docker 一键自托管。",
defaultTitle: `EdgeEver - ${siteTaglines["zh-CN"]}`,
imageAlt: "EdgeEver 笔记应用截图",
ogLocale: "zh_CN",
@@ -59,15 +57,11 @@ export const siteCopy = {
},
hero: {
slogan: siteTaglines["zh-CN"],
popHighlight: "印象笔记 0 成本经典平替 · 全平台原生支持",
popHighlight: "印象笔记开源经典平替 · 全平台客户端覆盖",
demo: "在线演示",
agentInstall: "一键 AI 部署",
agentInstall: "AI 辅助部署",
imageAlt: "EdgeEver product preview",
badgeText: "💡 全平台覆盖:macOS、iOS、Android、浏览器剪藏 · Cloudflare 免费部署 & Docker 一键安装",
terminalCmd: "请在线完成 EdgeEver 部署:Fork https://github.com/tianma-if/edgeever",
terminalSub: "Agent 原生 · 复制 Prompt 粘贴给 Cursor / Claude Code / Antigravity 即可自动部署",
copySuccess: "部署 Prompt 已复制!粘贴给 AI 助手即可部署",
agentPromptText: deploymentPrompts["zh-CN"],
badgeText: "💡 全平台覆盖:macOS、iOS、Android、浏览器剪藏 · Cloudflare 免费额度 & Docker 一键安装",
},
bento: {
eyebrow: "WHY EDGEEVER",
@@ -102,11 +96,11 @@ export const siteCopy = {
},
card3: {
badge: "自由部署",
title: "0 成本免服务器,或一键 Docker 自托管",
desc: "可零成本运行在 Cloudflare 配额内(存 15 万笔记 + 5 万图片);也可一键脚本部署至 VPS、NAS 或家庭服务器,存储按需随心扩展。",
title: "Cloudflare 免费额度,或一键 Docker 自托管",
desc: "个人使用通常可运行在 Cloudflare 免费额度内(约 15 万笔记 + 5 万图片);也可一键脚本部署至 VPS、NAS 或家庭服务器,存储按需扩展。",
price: "¥0",
unit: "/ 月",
sub: "Cloudflare 终身免服务器",
sub: "Cloudflare 免费额度内运行",
metric: "150,000+",
metricSub: "免费笔记容量 (可Docker扩展)",
},
@@ -121,15 +115,15 @@ export const siteCopy = {
},
card5: {
badge: "全端主权",
title: "全平台原生客户端与无损 ZIP 归档",
desc: "拥有 macOS(Rust+SQLite)、iOS(SwiftUI)、Android 及剪藏插件;基于标准 SQLite 与无损 ZIP 导出,数据完全自主掌控。",
title: "全平台客户端与无损 ZIP 归档",
desc: "覆盖 macOS(Electron+Rust+SQLite)、原生 iOS(SwiftUI)、Android 及剪藏插件;基于标准 SQLite 与无损 ZIP 导出,数据完全自主掌控。",
archiveTitle: "edgeever-backup.zip",
archiveSub: "包含 Markdown、Front Matter、附件与历史版本",
},
},
marquee: {
title: "全平台原生覆盖、自由部署与 AI 智脑生态",
subtitle: "从 macOS、iOS、Android 原生客户端,到 Docker 一键自托管、微信公众号排版与 Remote MCP 协同",
title: "全平台客户端覆盖、自由部署与 AI 智脑生态",
subtitle: "从 macOS、原生 iOS、Android 客户端,到 Docker 一键自托管、微信公众号排版与 Remote MCP 协同",
items: [
{
tag: "macOS 桌面端",
@@ -210,7 +204,7 @@ export const siteCopy = {
title: "自由选择部署方式:Cloudflare Serverless 与 Docker",
summary: "同一套现代应用,既可免费运行于 Cloudflare Serverless,也可通过 Docker 一键部署到 VPS、NAS 或家庭服务器。",
points: [
"Cloudflare 零成本自托管:无需购买云服务器与维护 SSL 证书,免费额度可容纳约 15 万条短笔记和 5 万张图片。",
"Cloudflare 免费额度自托管:无需购买云服务器与维护 SSL 证书,个人使用通常可容纳约 15 万条短笔记和 5 万张图片。",
"Docker 一键脚本部署:单行 curl 命令极速启动,存储按需随心扩展,轻松承载百万级笔记与海量附件。",
"数据安全尽在掌握:无论选择哪种部署形态,所有数据均保存在您自己的账号或私有设备中,安全无忧。",
],
@@ -245,7 +239,7 @@ export const siteCopy = {
],
},
{
title: "全平台原生客户端与多端同步",
title: "全平台客户端与多端同步",
summary: "覆盖 macOS、iOS、Android、浏览器剪藏插件与 Web/PWA,摆脱商业软件的设备数限制。",
points: [
"不限设备登录数:自建专属 API,彻底打碎商业笔记“免费版仅限 2 台设备”的枷锁。",
@@ -295,7 +289,7 @@ export const siteCopy = {
"en-US": {
layout: {
defaultDescription:
"EdgeEver is an open-source, AI-native, self-hosted Evernote alternative. Enjoy a classic three-pane workspace across macOS, iOS, Android, and Web Clipper with free Cloudflare serverless or Docker deployment.",
"EdgeEver is an open-source, AI-native, self-hosted Evernote alternative. Enjoy a classic three-pane workspace across macOS, iOS, Android, and Web Clipper, running within Cloudflare's free tier or on Docker.",
defaultTitle: "Open-Source, Self-Hosted Evernote Alternative | EdgeEver",
imageAlt: "EdgeEver notes app screenshot",
ogLocale: "en_US",
@@ -324,15 +318,11 @@ export const siteCopy = {
},
hero: {
slogan: siteTaglines["en-US"],
popHighlight: "Free Evernote Alternative · All-Platform Native Apps",
popHighlight: "Open-Source Evernote Alternative · Apps Across Platforms",
demo: "Live demo",
agentInstall: "Deploy with AI",
agentInstall: "AI-Assisted Deploy",
imageAlt: "EdgeEver product preview",
badgeText: "💡 All Platforms: macOS, iOS, Android, Web Clipper · Free Cloudflare & 1-line Docker Deploy",
terminalCmd: "Deploy EdgeEver online: Fork https://github.com/tianma-if/edgeever",
terminalSub: "Agent Native · Copy prompt to Cursor / Claude Code / Antigravity to deploy automatically",
copySuccess: "Deployment Prompt copied! Paste into AI Assistant",
agentPromptText: deploymentPrompts["en-US"],
badgeText: "💡 All Platforms: macOS, iOS, Android, Web Clipper · Cloudflare Free Tier & 1-Line Docker Deploy",
},
bento: {
eyebrow: "WHY EDGEEVER",
@@ -367,11 +357,11 @@ export const siteCopy = {
},
card3: {
badge: "Flexible Deploy",
title: "Zero Cost Serverless, or 1-Line Docker Deploy",
desc: "Run 100% free on Cloudflare (up to 150k notes & 50k images), or deploy with Docker on your VPS, NAS, or private server with unlimited scalability.",
title: "Cloudflare Free Tier, or 1-Line Docker Deploy",
desc: "Personal use typically fits within Cloudflare's free tier (about 150k notes & 50k images), or deploy with Docker on your VPS, NAS, or private server and scale storage as needed.",
price: "$0",
unit: "/ mo",
sub: "Cloudflare Serverless Forever",
sub: "Within Cloudflare's Free Tier",
metric: "150,000+",
metricSub: "Free Note Capacity (Scalable with Docker)",
},
@@ -386,15 +376,15 @@ export const siteCopy = {
},
card5: {
badge: "Data Sovereignty",
title: "All-Platform Native Apps & Lossless ZIP Backup",
desc: "Available on macOS (Rust+SQLite), iOS (SwiftUI), Android (Google Play/APK), and Web Clipper. Lossless ZIP export and standard SQLite for full ownership.",
title: "Apps Across Platforms & Lossless ZIP Backup",
desc: "Available on macOS (Electron+Rust+SQLite), native iOS (SwiftUI), Android (Google Play/APK), and Web Clipper. Lossless ZIP export and standard SQLite provide full ownership.",
archiveTitle: "edgeever-backup.zip",
archiveSub: "Markdown + Attachments + Revision History",
},
},
marquee: {
title: "All-Platform Native Apps, Flexible Deploy & AI Synergy",
subtitle: "From macOS, iOS & Android native apps to Docker self-hosting, styled creator copying, and Remote MCP collaboration.",
title: "Apps Across Platforms, Flexible Deploy & AI Synergy",
subtitle: "From macOS, native iOS & Android apps to Docker self-hosting, styled creator copying, and Remote MCP collaboration.",
items: [
{
tag: "macOS Desktop",
@@ -475,7 +465,7 @@ export const siteCopy = {
title: "Flexible Deployment: Cloudflare Serverless & Docker",
summary: "The same modern application runs seamlessly on Cloudflare Serverless or on a VPS, NAS, or home server via Docker.",
points: [
"Zero-Cost Cloudflare Self-Hosting: No VPS rental or SSL certificates required. Free tier supports up to 150k notes and 50k images.",
"Cloudflare Free-Tier Self-Hosting: No VPS rental or SSL certificates required. Personal use typically supports about 150k notes and 50k images.",
"1-Line Docker Deployment: Quick deployment with a single curl command, scaling easily to millions of notes and large files.",
"Complete Data Privacy: Regardless of deployment method, all your data lives strictly within your own account or private hardware.",
],
@@ -510,7 +500,7 @@ export const siteCopy = {
],
},
{
title: "All-Platform Native Clients & Multi-Device Sync",
title: "Apps Across Platforms & Multi-Device Sync",
summary: "Available across macOS, iOS, Android, browser Web Clipper, and Web/PWA, freeing you from commercial device caps.",
points: [
"Unlimited Devices: Self-hosted API eliminates commercial restrictions like the '2-device login limit'.",
+1 -1
View File
@@ -32,7 +32,7 @@ const homeJsonLd = [
operatingSystem: "macOS, iOS, Android, Web, Chrome, Edge, Firefox",
isAccessibleForFree: true,
description:
"EdgeEver is an open-source, AI-native, self-hosted Evernote alternative with a classic three-pane workflow, all-platform native clients, REST API, OpenAPI schema, and MCP endpoint.",
"EdgeEver is an open-source, AI-native, self-hosted Evernote alternative with a classic three-pane workflow, apps across macOS, iOS, Android and browsers, plus a REST API, OpenAPI schema, and MCP endpoint.",
keywords: ["Evernote alternative", "open-source notes app", "self-hosted notes app", "AI notes app"],
},
];
+1 -1
View File
@@ -29,7 +29,7 @@ const homeJsonLd = [
operatingSystem: "macOS, iOS, Android, Web, Chrome, Edge, Firefox",
isAccessibleForFree: true,
description:
"EdgeEver 是开源、原生支持 AI 的自托管笔记工作区,保留经典印象笔记三栏体验,提供全平台原生客户端、REST API、OpenAPI schema 和 MCP endpoint。",
"EdgeEver 是开源、原生支持 AI 的自托管笔记工作区,保留经典印象笔记三栏体验,覆盖 macOS、iOS、Android 与浏览器插件,并提供 REST API、OpenAPI schema 和 MCP endpoint。",
},
];
---