7.9 KiB
Review guidelines
Route Configuration
-
Example Format: The
examplefield must start with/and be a working RSSHub route path (e.g.,/example/route), not a full URL or source website URL. -
Route Name: Do not repeat the namespace name in the route name. The namespace is already defined in
namespace.ts. -
Radar Source Format: Use relative paths without
https://prefix inradar[].source. Example:source: ['www.example.com/path']instead ofsource: ['https://www.example.com/path']. -
Radar Target: The
radar[].targetmay be empty. If present, it must match the route path and its parameters. -
Namespace URL: In
namespace.ts, theurlfield should not include thehttps://protocol prefix. -
Single Category: Provide only one category in the
categoriesarray, not multiple. -
Unnecessary Files: Do not create separate
README.mdorradar.tsfiles. Put descriptions inRoute['description']and radar rules inRoute['radar']. -
Features Accuracy: Set
requirePuppeteer: trueonly if your route actually uses browser automation (@/utils/playwright). Do not mismatch feature flags. -
Maintainer GitHub ID: The
maintainersfield must contain valid GitHub usernames. Verify that the username exists before adding it.
Code Style
-
Naming Convention: Use
camelCasefor variable names in JavaScript/TypeScript. Avoidsnake_case(e.g., usevideoUrlinstead ofvideo_url). -
Import Sorting: Keep imports sorted. Run autofix if linter reports import order issues.
-
Avoid Loading HTML Twice: Do not call
load()from cheerio multiple times on the same content. Reuse the initial$object. -
Async/Await in Close: When closing a Playwright page or context, use
await page.close(),await context.close(), orawait destroy()instead of non-awaited calls. -
No Explicit Null: No need to explicitly set a property to
nullif it does not exist - just omit it. -
Valid Item Properties: Only use properties defined in lib/types.ts. Custom properties like
avatar,biowill be ignored by RSSHub. -
String Methods: Use
startsWith()instead ofincludes()when checking if a string begins with a specific prefix.
Data Handling
-
Use Cache: Always cache the returned results when fetching article details in a loop using
cache.tryGet(). -
Description Content: The
descriptionfield should contain only the main article content. Do not includetitle,author,pubDate, or tags indescription- they have their own dedicated fields. -
Category Field: Extract tags/categories from articles and place them in the
categoryfield, not indescription. -
pubDate Field: Always include
pubDatewhen the source provides date/time information. Use theparseDateutility function. -
No Fake Dates: Do not use
new Date()as a fallback forpubDate. If no date is available, leave it undefined. See No Date documentation. -
No Title Trimming: Do not manually trim or truncate titles. RSSHub core handles title processing automatically.
-
Unique Links: Ensure each item's
linkis unique as it will be used asguid. Avoid fallback URLs that could cause duplicateguidvalues. -
Human-Readable Links: The feed
linkfield should point to a human-readable webpage URL, not an API endpoint URL.
API and Data Fetching
-
Prefer APIs Over Scraping: When the target website has an API (often found by scrolling pages or checking network requests), use the API endpoint instead of HTML scraping.
-
JSON Parsing: When using
ofetch,JSON.parseis automatically applied. Do not manually decode JSON escape sequences like\u003C. -
No Page Turning: RSS feeds should only request the first page of content. Do not implement pagination parameters for users.
-
Use Common Parameters: Use RSSHub's built-in common parameters like
limitinstead of implementing custom query parameters for limiting entries. -
No Custom Query Parameters: Avoid using querystring parameters for route configuration. Use path parameters (
:param) instead. -
No Custom Filtering: Do not implement custom tag/category filtering in routes. Users can apply filtering using common parameters.
-
Avoid Dynamic Hashes: If an API requires a hash that changes across builds, extract it dynamically from the webpage rather than hardcoding it.
Media and Enclosures
-
Valid MIME Types: The
enclosure_typemust be a valid MIME type as defined in RFC specifications. For example,video/youtubeis not valid - use actual video file URLs with proper types likevideo/mp4. -
Direct Media URLs:
enclosure_urlmust point directly to downloadable media files (e.g.,.mp4,.mp3), not to web pages containing media. -
Video Poster: Use the HTML5
<video>element'sposterattribute for video thumbnails instead of adding separate<img>elements. -
No Referrer Policy in Routes: Do not add
referrerpolicyattributes to images/videos - RSSHub middleware handles this automatically.
Browser Automation
-
Limit Request Types: Do not allow every type of request through the browser. Use
page.route()with an explicit allowlist of resource types (e.g.,document) and abort everything else. Do not use a blocklist that aborts only known types such as images or fonts. -
Use Selectors, Not Delays: Do not use fixed
setTimeoutdelays. Usepage.waitForSelector()instead to wait for specific elements. -
Avoid Multiple Sessions: Do not call
playwright()orgetPlaywrightPage()insidePromise.all()loops - this creates multiple browser sessions and dramatically increases resource usage. -
Do Not Bypass Empty Checks: Do not return empty arrays with custom messages to bypass RSSHub's internal checks for empty items. This makes it hard for users and maintainers to know if a feed is broken.
Default Values and Examples
-
Preserve Default Values: Do not change documented default values for existing route parameters unless the current default is broken.
-
Preserve Working Examples: Do not modify existing route examples unless they no longer work.
-
Route Parameters: The
parametersobject keys must match the actual path parameters defined in the route path. Do not add non-existent parameters.
Error Handling
-
Error Messages: Use clear, actionable error messages that help users understand what went wrong.
-
Resolve All Review Comments: Before requesting re-review, ensure all previous review comments are addressed, not just some of them.
Code Organization
-
Move Functions Up: Move function definitions to the highest possible scope. Avoid defining functions inside loops or callbacks when they can be defined at module level.
-
No Await in Loops: Avoid using
awaitinside loops when possible. UsePromise.all()with proper concurrency control instead. -
Check URL Validity: Before using URLs from config files or namespaces, verify they don't return 404 errors.
-
Comments Language: Write code comments in English for consistency and accessibility.
-
Parentheses in Arrow Functions: Always use parentheses around arrow function parameters, even for single parameters.
-
No Tests for Routes: Do not write test files for routes under
lib/routes/. Route tests only encode the author's assumptions about the target site and go stale when it changes. Routes are verified through automatic route testing on pull requests, which runs the route examples against the live site.