网站存在度与SEO 是做什么的?
目的
Apple App Store和Google Play Store在允许提交应用前均要求提供URL:隐私政策、支持页面、账号删除,以及用于应用链接的.well-known文件。本技能构建一个小型、快速的静态网站,首先满足这些表单要求,然后使其可被发现(搜索引擎、链接预览、AI助手),且不包含追踪器、暗模式或应用无法支撑的数字。
请在商店清单和隐私表单(listing-and-aso、privacy-and-declarations)之前执行此操作:它们需要可访问的URL。
先决条件
- 您控制的域名,具有DNS访问权限(示例中使用Cloudflare;任何主机只要能设置标头且无重定向地提供文件即可)。
- 来自
identity-and-signing的最终应用标识符和签名数据(Team ID、Bundle ID、Package Name、Play 应用签名 SHA-256)。 - 来自代码/SDK扫描的隐私策略文本(
privacy-and-declarations)以及应用中真实存在的删除流程。 - 从商店读取的价格(
subscriptions-and-payments),切勿凭记忆输入。 - Node.js 18+ 用于scripts/中的脚本。
1. 商店要求的页面
每个商店字段到URL的清单:references/store-url-checklist.md。
| 页面 | 路径(建议) | 规则 |
|---|---|---|
| 隐私政策 | /privacy | 公开、无需登录、无地理封锁、HTML(非PDF)、包含应用名称、与商店隐私回答一致 |
| 服务条款 | /terms | 如果您销售订阅(Apple标准EULA或您自己的;在应用和清单中链接)则必需 |
| 支持/联系 | /support | 真实的联系方式(电子邮件或表单),不仅仅是常见问题解答 |
| 网页端账号删除 | /delete-account | Google Play要求此URL。包含与清单相同的应用名称,允许用户从页面本身请求删除,说明删除的内容、保留的内容及保留时间,并说明商店订阅必须单独取消 |
- Apple要求删除在应用内开始(准则5.1.1(v));网页页面不能替代此要求。Play要求应用内路径和网页URL两者兼备。文档:Apple账号删除,Play账号删除,Play隐私政策URL规则。
- 未登录状态且稳定。 无Cookie墙、无登录、无需JavaScript即可阅读文本。提交后不要重命名路径;如果必须重命名,请从旧路径保留301重定向。
- 每种语言独立。 每种语言一个URL(
/privacy、/de/privacy),附带hreflang;App Store Connect允许为每个本地化设置隐私URL。如果某页面未翻译,链接默认语言页面,而非返回404。 - 在法律页面上显示“最后更新”日期,并在版本控制中保留旧版本。
2. 应用链接托管
文件本身的模板位于identity-and-signing/templates/中。本节讲解如何提供服务。
https://<域名>/.well-known/apple-app-site-association和/.well-known/assetlinks.json:HTTP 200,Content-Type: application/json,无重定向(非http→https、非apex→www、非尾部斜杠)、无身份验证、无机器人挑战页面。- 决定使用apex还是
www。在权利/Intent过滤器中列出的每个主机上提供这些文件;仅对页面重定向其他主机,切勿对/.well-known/进行重定向。 - 静态主机通常将无扩展名的AASA以
application/octet-stream提供。通过Worker路由/.well-known/*(参见模板)或显式设置标头,然后使用scripts/check-site.mjs检查。 - 在声称该域名的应用构建之前部署
.well-known文件。Apple通过其CDN获取AASA,因此更改可能需要一段时间才能生效。
邀请/推荐页面(/i/<code>)
- Worker验证代码是否符合后端发布的精确字母表和长度,然后填充模板。URL中的其他任何内容都不会到达HTML。
- 如果应用已安装,通用链接/应用链接直接打开它(路径必须在AASA
components和Android Intent过滤器中)。如果未安装,页面显示两个商店按钮和一个“复制代码”按钮作为手动备选方案。 - Android:将代码附加到Play URL作为
&referrer=<url-encoded key=value>,并在应用中使用Play Install Referrer API读取。iOS没有安装引荐来源;要求用户粘贴代码,或仅在显式点击后从剪贴板预填。 - 标头:
X-Robots-Tag: noindex,Cache-Control: private, no-store,Referrer-Policy: no-referrer。保持/i/不在站点地图中。不要在robots.txt中Disallow它:无法抓取页面的爬虫永远看不到noindex。
3. 落地页
- 与商店截图相同的视觉语言(颜色、字体、相同的真实UI卡片)。从网站访问的访问者应能识别出商店页面。
- 商店徽章仅使用官方艺术作品,未经修改,并具有所需的间距和措辞;直接链接到清单。规则:Apple营销指南,Google Play徽章。
- 发布前:一行“即将在App Store和Google Play上线”,而非三个禁用的徽章。发布时(发布上线后):替换为真实的徽章链接,添加智能应用横幅meta(文档),更新
llms.txt和JSON-LD。将其保持为单个配置标志,以便只需更改一处。APPROVAL后才可切换。 - 诚实的定价。 价格来自从商店读取回的数据生成的文件。页面包含占位符(
%%PRICE_MONTHLY%%);Worker根据访问者所在国家(request.cf.country)填充它们,并对表格之外的国家显示“商店会以您的货币显示精确价格”。页面语言绝不决定货币。无划线“原价”、无虚假倒计时、无预选任何内容。 - 快速且可访问。 文本在HTML中(而非JS渲染),一个CSS文件,少量或不使用JS,自托管字体并设置
font-display: swap,主图像设置尺寸和fetchpriority="high"。目标:LCP < 2.5秒,CLS < 0.1,INP < 200毫秒(Web Vitals)。对比度和焦点状态符合WCAG 2.2;尊重prefers-reduced-motion。 - 分析。 优先选择无或服务器端/无Cookie计数(边缘日志、无标识符的隐私友好型分析)。如果您不设置Cookie且不加载第三方脚本,则无需Cookie横幅;不要“以防万一”显示一个。如果您添加任何追踪器,同意横幅、隐私政策和商店隐私回答必须同时更改。
4. 社交分享图像
- 每种语言一张Open Graph图像:1200×630 PNG/JPG,约1MB以下,文本足够大以在缩略图大小下阅读。在
og:image和twitter:image中使用绝对https://URL,外加og:image:width/height/alt、og:title、og:description、og:url、twitter:card=summary_large_image。规范:ogp.me,Meta共享指南。 - 消息应用会积极缓存预览。更改图像后,给它一个新的文件名(或
?v=2),然后在Sharing Debugger中重新抓取(“Scrape Again”)。WhatsApp和其他信使有自己的缓存,没有公共刷新工具,因此新的图像URL是可靠的修复方法;通过在新建聊天中发送链接进行测试。
5. 技术SEO
- 标题(约50-60字符,品牌+做什么)和meta描述(约150-160字符)每个页面和语言唯一。Title links,snippets。
- hreflang:每个语言版本列出所有版本包括自身,外加
x-default;配对必须互逆。Localized versions。 - Canonical:自引用、绝对URL、在最终(无重定向)URL上。Canonicalization。
- 站点地图:仅包含200、可索引、规范URL和真实的
<lastmod>(内容更改的日期,例如来自git,而非构建时间)。Template,docs。 - robots.txt:template,intro。robots.txt控制抓取,而非索引;使用
noindex处理必须排除在搜索结果之外的页面。 - 结构化数据(JSON-LD):Organization、WebSite、MobileApplication;仅当页面上可见FAQ时才使用FAQPage。示例和规则:references/structured-data.md。
- 非生产主机(预览、
*.workers.dev)发送X-Robots-Tag: noindex。
6. 发现
- Google Search Console:添加一个Domain属性,在apex添加
google-site-verificationTXT记录,验证,提交站点地图,请求主页的索引。Verify ownership。 - Bing Webmaster Tools:从Search Console导入,或使用Bing提供的DNS记录(CNAME)验证,然后提交站点地图。Add and verify。
- IndexNow(Bing、Yandex、Seznam、Naver等;不包括Google):托管包含密钥的
/<key>.txt文件,部署,然后运行node scripts/indexnow-ping.mjs(试运行)和--send。脚本首先检查密钥文件是否在线。Protocol。 - AI爬虫和llms.txt:决定每个机器人是否允许搜索/回答机器人和训练机器人(所有者的决定,APPROVAL)。机器人列表、目的和官方链接:references/ai-crawlers.md。添加一个简短的llms.txt,包含产品摘要和关键URL,不含价格。
DNS记录是共享基础设施:添加新记录;切勿编辑或删除现有的TXT/SPF/MX记录。APPROVAL后才可进行任何DNS更改。
7. 部署(Cloudflare Worker示例)
模板:templates/worker.example.js。它以正确的类型和无重定向提供.well-known文件,填充按国家/地区的价格占位符,渲染/i/<code>,添加安全标头,并在非生产主机上添加noindex。
两个存储选项:
- Workers Static Assets(最简单):在
wrangler.jsonc中添加"assets": { "directory": "./dist", "binding": "ASSETS", "run_worker_first": true };Worker调用env.ASSETS.fetch()。Docs。 - KV(内容寻址):构建在哈希下写入文件和一个
manifest.js(路径→哈希,类型);在部署Worker之前使用wrangler kv bulk put上传,这样新manifest不会指向缺失的文件。KV commands。
步骤:
node build.mjs→dist/(在缺少任何翻译键或除价格占位符外的未填充占位符时失败)。- 单元测试(
node --test):对模拟资产运行Worker的fetch。覆盖:AASA/assetlinks 200 +application/json+ 无重定向;仅对页面进行www/http重定向;/i/<bad>→ 404,/i/<good>→ noindex + no-store;每个价格区域填充所有占位符(无%%剩余);格式错误的百分号编码 → 404,而非500。 - 预览:
npx wrangler deploy --dry-run,或部署到预览主机并运行node scripts/check-site.mjs https://<preview-host>。 - APPROVAL——生产部署(
npx wrangler deploy)。在wrangler.jsonc中固定account_id、name和路由,以便命令无法定位共享帐户上的另一个项目。 - 部署后:
node scripts/check-site.mjs https://example.com --invite <sample code>,然后进行IndexNow推送。
需要人工审批的决策点
- 生产部署和DNS更改。
- 法律页面(隐私、条款、删除)的措辞;所有者批准任何更改。
- AI训练爬虫允许/拒绝。
- “即将上线” → “下载”切换以及网站上显示的任何价格。
- 添加分析、等待列表表单或任何收集个人数据的操作。
验证
node scripts/check-site.mjs https://example.com --paths /privacy,/terms,/support,/delete-account退出码0:必需页面在未登录状态返回200,AASA/assetlinks JSON无重定向,OG标签具有可访问的绝对图像,互逆的hreflang,站点地图URL全部返回200。- 商店URL清单中的每个URL在手机的私密窗口中打开。
- Rich Results Test和Schema Markup Validator无错误;PageSpeed Insights移动端LCP < 2.5秒。
- Search Console:站点地图“Success”;Bing:可见IndexNow提交。
常见陷阱
- 隐私URL重定向到登录页、PDF或从未提及应用名称的通用公司政策。
- 删除页面仅说明“在应用中删除”(Play要求页面上有请求路径)或忘记提及取消商店订阅。
- AASA通过apex→www重定向、作为
text/html或位于机器人挑战页面后面提供。 - robots.txt中
Disallow: /i/结合爬虫永远看不到的noindex标头。 - 按语言硬编码的价格(在瑞士访问者的德语页面上显示EUR)或在商店价格变更后保持过时数字。
- 为新应用虚构
aggregateRating,或使用仅在一个国家成立的价格的offers。 - OG图像
...
[已截断]