Directory SaaS 周末上线指南:200 个目录项、Stripe 支付与 SEO 页面

在一个周末交付 Directory SaaS:包含 200 个目录项、Stripe 订阅和 200 个程序化 SEO 页面。TanStack Ship 为你搞定枯燥的基础工作,立即开始。

Huifer
Huifer
May 20, 202610 min read
其他语言:Deutsch · English

本文由 Huifer 撰写,他是 TanStack Ship 的独立开发者兼维护者。 2026 年 5 月 16 日至 17 日的周末,我使用 TanStack Ship 模块(包括目录项数据表与 admin、Stripe 订阅、200 个程序化 SEO 页面、联系表单以及部署流水线)构建了一款面向独立 SaaS 工具的 directory SaaS 产品。总消耗的时间为 26 小时。API 总开销:$42。周二上午,第一笔付费目录项订单诞生了。本文是该周末的开发日志:分享了我拼装了哪些模块、跳过了哪些功能、阶梯定价怎么定,以及诚实复盘 3 种完全不适用“周末构建法”的业务场景。

参考来源: TanStack Start docs · Cloudflare D1 · Stripe Billing subscriptions · Stripe Connect · Stripe webhooks · Resend docs · Better Auth · Schema.org ItemList

最后更新:2026-05-20 · Changelog


太长不看 (TL;DR): 我用一个周末(26 小时),使用 TanStack Ship 上线了一款 directory SaaS。最终成品包含:200 个目录项、3 级阶梯 Stripe 订阅 ($0 / $29 / $99)、200 个程序化 SEO 页面、admin CRUD、Resend 邮件以及部署流水线。总 API 开销:$42。第一笔付费目录订单在周二早上 9:14 达成。周末共使用了 7 个 TanStack Ship 模块。这种方案注定失败的 3 种真实场景:B2B SaaS 目录(销售导向)、双边市场(应使用 Stripe Connect),以及规模超过 1 万个目录项的本地目录服务(需要截然不同的缓存机制)。


Directory SaaS 周末上线指南:200 个目录项、Stripe 支付与 SEO 页面

Directory SaaS 堪称完美的周末构建项目。它的产品规格非常明确,枯燥的基础组件(Auth,计费,部署,SEO)早已有脚手架解决了,而它的核心价值就在目录项数据本身。网上那些“周末上线”的口号大多是营销话术,但对于 directory SaaS 而言,这种节奏恰如其分。

本文记录了 5 月 16 日至 17 日这段周末的冲刺日志:分享了我拼装了哪些模块、跳过了哪些环节、促成首单付费的定价阶梯,以及三种完全不适用“周末构建法”的真实场景。

2026 年一款 Directory SaaS 的核心构成

每个 Directory 产品都需要具备的 5 大基础原语

剥离营销外衣,所有 directory SaaS 实际上都基于五个相同的基础原语:

  1. 目录项数据表 (Listings table):包含名称、slug、描述、标引标签、logo,以及每个目录项的 1-3 个直达链接。
  2. Admin CRUD 后台:让你能在后台直接完成批准、编辑、加精或删除操作,而不用手动去改数据库。
  3. 分层 Stripe 订阅(标准阶梯一般是 $0 / $29 / $99):能将订阅价格自动映射为目录项的展示位权重以及专属徽章。
  4. 程序化 SEO 页面:为 /{category} 及 /{category}/{slug} 独立规划落地页,每个页面带好结构化数据并提供 canonical 规范链接。
  5. 邮件闭环 (Email loop):在提交后发送确认信,审批通过后发通知,以及在高级席位续费时下发提醒。

如果你选择的脚手架可以在开箱时支持前四项,那么周末两天突击构建是可行的。如果不能,那就等着至少星期一以后才能发布了。

那些烧掉你周末时间的新手雷区

我也眼睁睁看着不少人在以下三个地方踩坑:

  1. 自己手搓 Auth 认证系统。 如果一款 directory SaaS 放着 Better Auth 这种现成方案不用,而是自己写表单登录,那你周六的大好时光就会被 session cookies、预防 CSRF 攻击、编写重置密码及验证邮件消耗掉。到了周日晚上,你的进展仅限于做出了一个能用的登录系统。
  2. 在设计 Schema 前先画 UI。 很多创始人上手的第一招就是:先搞首页卡片列表——然后就花四个小时死磕 hover 动画效果。正确的顺序应该是,在周五晚上先把 Schema 设计出来。
  3. 手工实现 Stripe Webhook 的幂等性。 纯靠手敲来防卫并发逻辑在没有脚手架类库的情况下至少会花掉你 8 小时。如果是作为模块来组装使用,这至少能帮你省下周六整个下午。

周末架构纪实:从 Ship 模块到 directory 产品

以下记录了 5 月 16 日至 17 日具体的模块拼装纪实。每个小节均将 TanStack Ship 特有模块与 directory 特化的配置逻辑展现如下。

模块 1:目录项数据表与 Admin CRUD

冲刺阶段的前 90 分钟用来设计 D1 schema。TanStack Ship 提供了一个数据库迁移运行工具(migration runner),我只加了一张用来存储目录信息的表 listings:

sql
-- migrations/2026-05-16-listings.sql
CREATE TABLE listings (
  id INTEGER PRIMARY KEY,
  slug TEXT UNIQUE NOT NULL,
  name TEXT NOT NULL,
  tagline TEXT NOT NULL,
  description TEXT NOT NULL,
  category TEXT NOT NULL,
  tags TEXT NOT NULL,             -- JSON 数组,例如 ["ai","analytics"]
  logo_url TEXT,
  website_url TEXT NOT NULL,
  twitter_url TEXT,
  tier TEXT NOT NULL DEFAULT 'free',  -- 'free' | 'pro' | 'featured'
  approved INTEGER NOT NULL DEFAULT 0,
  created_at INTEGER NOT NULL,
  updated_at INTEGER NOT NULL
);
CREATE INDEX idx_listings_category ON listings(category, approved);
CREATE INDEX idx_listings_tier ON listings(tier, approved);

CREATE TABLE listing_submissions (
  id INTEGER PRIMARY KEY,
  email TEXT NOT NULL,
  name TEXT NOT NULL,
  website TEXT NOT NULL,
  status TEXT NOT NULL DEFAULT 'pending', -- pending | approved | rejected
  created_at INTEGER NOT NULL
);

有了 approved 这个标志字段,处理 Admin CRUD 变得异常简单——在控制台敲一条 UPDATE listings SET approved = 1 WHERE id = ? 即可管理批准。借由 tier 列设定,Stripe 订阅能直接映射并在前端展现不同权重。基于这份 schema,Ship 的 admin 模块还能为你自动生成包含审批操作和等级切换功能的管理员操作台。正是得益于它,我在周六上午 11 点就已经拿到了一个顺利流转业务的操控面板。

模块 2:阶梯定价式 Stripe 订阅

该项目将 directory 设计了三个层级配置:Free(分类下的基础排位)、Pro(定价 $29/月,带标识 "Pro" 并保证在类目中优先展示以及享有 newsletter 曝光),最高层是 Featured($99/月选项,获得主页最佳英雄区广告位及每周推文宣传)。相关的对接选定了支持这三组带明确价格(price ID)项配置的 Stripe Billing 网关模块。

typescript
// app/routes/api/webhooks/stripe.ts
import { createFileRoute } from "@tanstack/react-router";
import Stripe from "stripe";
import { db } from "@/lib/db";

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);

export const Route = createFileRoute("/api/webhooks/stripe")({
  server: {
    handlers: {
      POST: async ({ request }) => {
        const sig = request.headers.get("stripe-signature")!;
        const body = await request.text();
        const event = stripe.webhooks.constructEvent(
          body, sig, process.env.STRIPE_WEBHOOK_SECRET!
        );

        if (event.type === "checkout.session.completed") {
          const session = event.data.object as Stripe.Checkout.Session;
          const listingId = Number(session.metadata?.listing_id);
          const tier = session.metadata?.tier as "pro" | "featured";
          await db
            .updateTable("listings")
            .set({ tier, updated_at: Date.now() })
            .where("id", "=", listingId)
            .execute();
        }

        if (event.type === "customer.subscription.deleted") {
          const sub = event.data.object as Stripe.Subscription;
          const listingId = Number(sub.metadata?.listing_id);
          await db
            .updateTable("listings")
            .set({ tier: "free", updated_at: Date.now() })
            .where("id", "=", listingId)
            .execute();
        }

        return new Response("ok");
      },
    },
  },
});

当逾期未续引发 customer.subscription.deleted 挂接事件后,这处回调会让该对象自动降级并跌落回基础的 Free 档!不设置此道清场兜底逻辑,那些过期的旧日 Featured 占有者会长期霸占黄金位置,最终把付费坑位变成无人打理的僵尸广告墙。得益于 TanStack Ship 已经封装好带有幂等应对和 Stripe 人工验签机制 的单一模块,实现这套处理流一共也只用了 30 分钟。

模块 3:程序化 SEO 页面(足足 200 个)

周末耗时最长的就是搭建程序化 SEO 页面的脚手架。对于 12 个类目板块和 200 个目录产品,最终的页面数量大概是:12 个分类页 + 200 个独立目录页 + 3 个营销页 = 共计 215 个能够被公开索引的页面。

Ship 的 route 支持体系可以通过如下的一份动态配置脚本解决这其中的 200 个页面:

typescript
// app/routes/$category/$slug.tsx
import { createFileRoute, notFound } from "@tanstack/react-router";
import { db } from "@/lib/db";

export const Route = createFileRoute("/$category/$slug")({
  loader: async ({ params }) => {
    const listing = await db
      .selectFrom("listings")
      .selectAll()
      .where("slug", "=", params.slug)
      .where("category", "=", params.category)
      .where("approved", "=", 1)
      .executeTakeFirst();
    if (!listing) throw notFound();
    return listing;
  },
  head: ({ loaderData }) => ({
    meta: [
      { title: `${loaderData.name} — ${loaderData.category} directory` },
      { name: "description", content: loaderData.tagline },
      { property: "og:title", content: loaderData.name },
      { property: "og:description", content: loaderData.tagline },
      { property: "og:image", content: loaderData.logo_url ?? "" },
    ],
    links: [
      {
        rel: "canonical",
        href: `https://example.com/${loaderData.category}/${loaderData.slug}`,
      },
    ],
    scripts: [
      {
        type: "application/ld+json",
        children: JSON.stringify({
          "@context": "https://schema.org",
          "@type": "SoftwareApplication",
          name: loaderData.name,
          description: loaderData.tagline,
          url: loaderData.website_url,
          applicationCategory: loaderData.category,
        }),
      },
    ],
  }),
  component: ListingPage,
});

一份文件即产出 200 张极为干净利索的 SEO 落地页。这里的每一页都会自动带上特有的 <title>、<meta description> 、以及面对社交分发协议的 Open Graph 设置。此外兼顾能加入 canonical 规范链接,更重要的是它依托于 Schema.org 的 SoftwareApplication 规范 自动注入了配合搜索引擎精读的 JSON-LD 数据。所有这些也伴随着整个系统的 Sitemap 实现了自主刷新和跟进。

第二天就能跑通业务的阶梯定价策略

3 级阶梯模型:Free / Pro / Featured

阶梯定价是 directory SaaS 中驱动营收的最大杠杆:

阶梯价格目录项获得权益你将获得
Free$0/月分类中的基础展示位约 80% 的目录项,构成基础供应
Pro$29/月"Pro" 徽章 + 优先排序 + newsletter 坑位约 15% 的目录项
Featured$99/月首页英雄区展示 + 每周推文宣传约 5% 的目录项

对于一个有 200 个目录项规模的平台而言,通过标准转化率将其推演,代表稳定后该平台大概能达成 $750 到 $3,700 的 MRR(月经常性收入)。这是在 200 这个规模下能实打实拿到的真实现金流。

什么时候不应该使用 Stripe Connect

如果你的程序产品属于对双边均为基础免费(比如人工社区维护驱动的推荐列表),那你完全不需要考虑 Stripe。如果你的目录平台仅向提交信息的人单向收费,那么这用基础的一套 Stripe Billing 系统便足矣——本文配置演示的就是走这条单向结款打通流路线。如果你的目录不仅仅是向目录所有者收费,而且还需要进行向下分发利润的分红结清(这也是真正意义上的双边大市场),那么这个时候请务必老实使用 Stripe Connect——尽管 TanStack Ship 的组件同时兼容这二者,但去对接连入 Connect 本来也就是会带来 4-6 个小时以上的额外精力成本,在一般没有抽水分发需求的普通业务上用这是属于杀鸡用牛刀。

针对拉长为期 4 周来推进统盘考虑的宏观排期攻略,可查阅 从零开始在 4 周内跑通 MVP。模块功能详单列表查询请见 功能页面;需获取相关产品资费和查询选项前往查看 产品定价。

3 个必败无疑的特殊场景(真实避坑指北)

周末跑刺上线的构建法,完全适配那些不超过 1 万量级且仅仅面向信息拥有方索要单边付费费用的产品。可当你的需求一旦是以下三种时,这么玩绝对没戏:

场景 1:销售导向型的 B2B SaaS 目录

B2B SaaS 目录(比如“为 $5 万+ ARR 年复营收额团队甄选的大型销售工具 30 强”)这类东西根本无法光凭随便甩一个网页自主自服型的 Stripe Checkout 结账系统链接就能打通。拍板此项购买业务的往往是销售主管或是营收负责人(RevOps),预算都是严格走着按季度进行的批示周期运作。最得当的思路应当是在定价展示页配挂上包含 /book-a-demo(预约产品演示说明)此等强功能行动按钮来进行线索收取导流,并将日程表抛进比如 Calendly 这类跟单运作环境系统并采取人力做单。至于 Stripe,它也就适合拿来作为敲定单子履约合作后到末端进行预付款下划付交所用的工具罢了。

场景 2:双边市场必然该集成 Stripe Connect 才行

只要服务挂出的人除了可以自己“掏钱买广告”,还能向找进来的终端购买客收取费用并进行订单款分流(例如专门让接活的自由人可在完成活赚有 80% 实单收益的大型找活名录),这就成了一个拥有正统全功能闭环且具有法定规范化义务特征的撮合双边市场。这时候你必须要对接开通给所有的这批目录归属主账户连通并绑定其下专属于这的 Stripe Connect Express 账号,还要去应付身份法务实名(KYC)身份鉴定验签和配置下放拨款日期与出款提结清流程计划列表了。仅仅 Connect 的这一项介入就可以多耗费拖垮 4-6 个小时周期并且直接从法务结构角度改变系统的责任认定结构(因为在此之后你变成了资金的合规受托法定的持有平台记录人)。请一定对这块进行专门评估并规划留案。

场景 3:>1 万+ 个目录项的大型本地目录站

对于按照城市范围作区隔区域覆盖性质细拆(例如区分当地这边的水管维修工、独立牙医诊断及餐饮商铺这种性质)的达到超过了 >1 万 个量级以上的大型站时,其在这时的整体 SEO 战略将会完全截然不同:每一类目录下属每个单独目录都必须具备特意人工手写独立专送撰写文字,如此才可能去能挤进其在这一地域区块内的搜索名次推荐本地包卡段排行;在承接处理面页面最终单规模数量更要升至将推算飙推涨多及 1 万到 10 万 级之上,此时缓存响应系统架构对冲策略必须跟着采取更换和应对转变(需要使用 stale-while-revalidate 策略的 Cloudflare Cache Reserve,而不是简单的 D1-on-request 实时访问)。基本上当体量越过 5000 个目录项,这套基于“短平快”周末上线的粗放打法在这里就不灵了、大概率会彻底崩溃失效。

FAQ (常见问题)

我真的能在一个周末成功把 directory SaaS 交付上线吗?

如果是做一款首发当日条目规模在 200 条左右的小体量、由展示者付费的单边目录页,答案是可以的。五月份这项目的冲刺用到了 7 种 TanStack Ship 模块一共度过了 26 小时的自然时间完成。如果在目录项大于 500 这个规模,或者属于双端结清类型那恐怕估计得需要至少留有大约 2 到 3 个周末才能解决问题。

搭建一款 directory SaaS 产品最便宜的技术栈组合是什么?

TanStack Ship 授权花费 $299 + Cloudflare Workers 免费档额度 + Stripe 流水随用随付 = 在应对 200 规模目录项体量下基本只需花费大约 $0–$50/月。买断脚手架的商用许可费是最大一笔实支开销;主机空间如果在其用户总流量月活没出超 10 万 MAU 这个水位以前那就相当于绝对不要钱的全免费阶段状态。

我必须连接个数据库还是随便拿 CMS 当下用也可以?

你非得上数据库不可。像 Sanity 或是 Contentful 一类的 CMS 平台当作写博客的素材支持管理确还可行,但在列表需要随时增删改查时或者面对和绑定映射 Stripe 阶梯层级这种场合这就太慢且糟糕了。在目前的这般等级之下,TanStack Ship 搭配了 Cloudflare D1,响应的 p99 延迟表现都通常在此规模被控制在 10ms 表现里内。

我该如何获得平台上那极其最初前的头 100 号目录项呢?

主动出击联系出去找(Outreach)。给 100 位创始人直接发一封包含“您想免费把产品挂到名录展示吗?”的邮件。会有大约 20–30 号项目进来。免费阶很好地解决了“到底是先有鸡还是先有蛋”的双边死循环困境;后续的 Pro 以及 Featured 层级成员将会在第 2 到 6 个月为你带来真实收益结清你的各种账单。

到底对接时该去选用 Stripe Billing 还是 Stripe Connect?

如果你向目录拥有者收费并由自己保留资金,使用标准的 Stripe Billing 就没问题——这也是本文配置连线的模式。如果你向目录拥有者收费并且将钱打下分发到给他们(真正的双边市场形态),请使用 Stripe Connect。绝大多数 directory SaaS 产品都是只有单向这端计费,Billing 足矣。

Directory SaaS 项目要多久才能做到 $1k MRR?

对于一个只有 200–500 号数据的单纯针对垂直细分的目录体系而言,在常规市场转换比的预估下这大概会花 3–6 个月时间(有 5% 买入 Pro 选项而大概有 2% 购买 Featured)。如果是不受限于垂直大盘子泛广范围铺量,能达到规模 1 万项的话,那可能 1–2 个月就能达成这个目标,但收集初始信息的耗时也因此必然会大大延长。

就在这个周末携手使用 TanStack Ship 让你的 directory SaaS 乘风起航 ——涵盖了目录框架搭建、Stripe 扣款系统、程序化 SEO 页面机制甚至一键部署流水线均已连通配置。 立即免费开启您的尝试之旅 →