像产品一样构建文档
Building docs like a product

原始链接: https://emschwartz.me/building-docs-like-a-product/

## Scour 的交互式文档:通过实践学习 Scour 团队,一个个性化内容推送平台,最近重建了其文档,使其反映应用程序本身,并从 Stripe 备受赞誉的产品文档中汲取灵感。 Scour 的文档不是传统的说明书,而是*交互式*的——在指南中直接向用户提供可用的示例。 例如,为 Hacker News 用户提供的指南包含一个实时搜索栏,用于发现隐藏的精彩内容,而为 Reddit、Substack 和 arXiv 提供的指南则允许直接订阅信息流。 功能取代了解释:用户可以探索示例兴趣,接收个性化的主题推荐,甚至可以调整内容过滤设置——所有这些都可以在文档中完成。 重要的是,该文档使用了与 Scour 网站相同的组件,确保一致性,并通过 Rust 的类型系统和 `axum` 路由库避免了损坏的链接。 这种“演示,而非讲述”的方法旨在提供无缝且直观的学习体验,直接响应用户反馈,要求更深入地了解 Scour 的功能,包括其排名算法。 团队欢迎进一步的反馈,以继续完善文档。

黑客新闻 新 | 过去 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 像产品一样构建文档 (emschwartz.me) 17 分,由 emschwartz 1小时前发布 | 隐藏 | 过去 | 收藏 | 1 条评论 gregory144 1分钟前 [–] 这就像构建一个自定义的swagger实现。 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请YC | 联系 搜索:
相关文章

原文

Stripe is famous for having some of the best product docs, largely because they are "designed to feel like an application rather than a traditional user manual". I spent much of the last week building and writing the docs for Scour, and I am quite proud of the results.

Interactive Docs

Scour is a personalized content feed, not an SDK or API, so I started by asking myself what the equivalent of working code or copyable snippets is for this type of product. The answer: interactive pieces of the product, built right into the docs themselves.

Scouring Hacker News for Hidden Gems

The guide for Hacker News readers is one of the sections I'm most proud of. When describing Scour to people, I often start with the origin story of wanting a tool that could search for posts related to my interests from the thousands submitted to HN that never make it to the front page.

Built right into the guide is a live search bar that searches posts that have been submitted to HN, but that have not been on the front page. Try it out! You might find some hidden gems.

Screenshot 2026-01-29 at 13-59-31 For Hacker News Readers · Scour

The guides for Redditors, Substack readers, and arXiv readers also have interactive elements that let you easily search for subreddits or newsletters, or subscribe to any of arXiv's categories. Logged in users can subscribe to those feeds right from the docs.

Show, Don't Tell

Every time I went to explain some aspect of Scour, I first asked myself if there was a way to use a working example instead.

On the Interests page, I wanted to explain that the topics you add to Scour can be any free-form text you want. Every time you load the page, this snippet loads a random set of interests that people have added on Scour. You can click any of them to go to the page of content related to that topic and add that interest yourself.

Screenshot 2026-01-29 at 14-18-27 Interests · Scour

While explaining how Scour recommends other topics to you, I thought what if I just included an actual topic recommendation for logged in users? (Graphic Design was actually a Scour recommendation for me, and a good one at that!)

Screenshot 2026-01-29 at 14-06-35 Interests · Scour

On various docs pages, I wanted to explain the settings that exist. Instead of linking to the settings page or describing where to find it, logged in users can just change the settings from within the docs.

For example, on the Content Filtering page, you can toggle the setting to hide paywalled content right from the docs:

Screenshot 2026-01-29 at 16-03-55 Content Filtering · Scour

Use Real Components

There are numerous live examples throughout the docs. All of those use the same components as the actual Scour website. (Scour is built with the "MASH stack", so these are all maud components.)

The section explaining that you can show the feeds where any given post was found actually includes the recent post that was found in the most different feeds. (In the docs, you actually need to click the "..." button to show the feeds underneath the post, as shown below.)

Screenshot 2026-01-29 at 14-08-05 Feeds · Scour

Real Components, Even for Examples

While building this out, I had a number of cases where I needed to show an example of some component, but where I couldn't show a live component. For example, in the Interest Recommendations section described above, I needed a placeholder for users that aren't logged in.

I started building a separate component that looked like the normal interest component... and then stopped. This felt like the type of code that would eventually diverge from the original and I'd forget to update it. So, I went and refactored the original components so that they'd work for static examples too.

Example Interest

The last piece of building a documentation experience that I would be happy to use was ensuring that there would be no broken links. No broken links across docs sections, and no broken links from the docs to parts of the application.

Scour is built with the excellent axum HTTP routing library in Rust. The axum-extra crate has a useful, albeit slightly tedious TypedPath trait and derive macro. This lets you define HTTP routes as structs, which can be used by the router and anywhere else you might want to link to that page.

use axum::Router;
use axum_extra::routing::{TypedPath, RouterExt};
use serde::Deserialize;

#[derive(Deserialize, TypedPath)]
#[typed_path("/docs/interests")]
pub struct InterestsPath;

async fn interests(
	_path: InterestsPath
) { ... }

#[tokio::main]
pub async fn main() {
	let router = Router::new()
		.typed_get(interests);
}

Anywhere else we might want to link to the Interests docs, we can use the following to get the path:

use crate::docs::InterestsPath;

async fn other_docs() {
	let interests_path = InterestsPath.to_string();
}

This way, Rust's type system enforces that any link to those docs will stay updated, even if I later move the paths around.

Feedback Welcome!

I started working on these docs after a couple of users gave the feedback that they would love a page explaining how Scour works. There is now a detailed explanation of how Scour's ranking algorithm works, along with docs explaining everything else I could think of.

Please keep the feedback coming! If you still have questions after reading through any of the docs, please let me know so I can keep improving them.


Discuss on Hacker News or Lobsters.


#scour

联系我们 contact @ memedata.com