Return the current batch of trending Xiaohongshu (RedNote) feed cards — each card's 1-line displayTitle, type, video duration, like count, author, and canonical note URL. Filter to short videos for the short-video use case.
Automate repetitive workflows and reduce manual effort
Example: Generate reports, summarize documents, draft communications
Save 3-5 hours per week on routine tasks
Learn new skills, understand complex topics, get expert guidance
Example: Explain concepts, provide examples, suggest learning resources
Accelerate learning and skill development by 2x
Enhance output quality through reviews, suggestions, and refinements
Example: Review drafts, suggest improvements, catch errors
Improve work quality by 30-40% with less effort
Time estimate: 15-45 minutes depending on use case complexity
Prerequisites
Submit your Claude Code skill and start earning
browse install xiaohongshu.com/get-trending-content-lrb8axCompatible with
Supported agents
| name | get-trending-content |
| title | Xiaohongshu Trending Short-Video Titles |
| description | >- Return the current batch of trending Xiaohongshu (RedNote) feed cards — each card's 1-line displayTitle, type, video duration, like count, author, and canonical note URL. Filter to short videos for the short-video use case. |
| website | xiaohongshu.com |
| category | social-media |
| tags | - xiaohongshu - rednote - trending - short-video - social-media - china |
| source | 'browserbase: agent-runtime 2026-05-18' |
| updated | '2026-05-18' |
| recommended_method | url-param |
| alternative_methods | - method: browser rationale: >- Only needed for pagination beyond the initial SSR batch. The internal /api/sns/web/v1/homefeed endpoint requires a client-generated X-S/X-T signature header that's heavily obfuscated and brittle — driving the page and reading window.__INITIAL_STATE__ on each navigation is the honest fallback. - method: api rationale: >- edith.xiaohongshu.com/api/sns/web/v1/homefeed exists but is gated by an X-S/X-T HMAC signature computed by minified browser JS. Confirmed not worth pursuing without a maintained signature library — the SSR shortcut returns the same hot batch with zero crypto. |
| verified | false |
| proxies | true |
Return the current batch of trending Xiaohongshu (RedNote, 小红书) feed cards from xiaohongshu.com/explore, with each card's 1-line title (displayTitle), content type (video vs image post), video duration in seconds, like count, author handle, note id, and canonical reader URL. Filter noteCard.type === "video" for the short-video subset. The same shape works for the algorithmic recommend feed (default) and for any of the ten category channels (fashion, food, beauty, fitness, etc.). Read-only — never likes, comments, follows, or posts.
__INITIAL_STATE__ blob beats a snapshot loop by ~50× and never needs the signed XHS API.The Xiaohongshu explore page is server-side rendered: every response embeds a full window.__INITIAL_STATE__ = {...} JSON dump whose state.feed.feeds[] array contains the 22–27 trending notes the homepage would have rendered. You do not need a real browser. One HTTP GET via Browserbase Fetch with a residential proxy returns the same data as opening the page in Chrome.
bb fetch "https://www.xiaohongshu.com/explore" \
--allow-redirects --proxies \
--output /tmp/xhs-explore.html
--proxies is mandatory. From a datacenter IP, Xiaohongshu returns a 10 KB anti-bot stub with no __INITIAL_STATE__. With residential, the response is ~580 KB and contains the full SSR feed. Status code is 200 in both cases — check the response body size or the presence of window.__INITIAL_STATE__, not the status, to detect the wall.
To scope to a category, append ?channel_id=<id>. The channel enum is published in the SSR payload itself (state.feed.channels.categories); copy below:
channel_id | Category (中文) | English label |
|---|---|---|
homefeed_recommend (default — no param) | 推荐 | Algorithmic recommend (mixed) |
homefeed.fashion_v3 | 穿搭 | Fashion |
homefeed.food_v3 | 美食 | Food |
homefeed.cosmetics_v3 | 彩妆 | Beauty / Makeup |
homefeed.movie_and_tv_v3 | 影视 | Movies & TV |
homefeed.career_v3 | 职场 | Career |
homefeed.love_v3 | 情感 | Relationships |
homefeed.household_product_v3 | 家居 | Home |
homefeed.gaming_v3 | 游戏 | Gaming |
homefeed.travel_v3 | 旅行 | Travel |
homefeed.fitness_v3 | 健身 | Fitness |
There are also two legacy/unlisted channels not in state.feed.channels.categories but still served: homefeed.video_feed and homefeed.video_v2_feed. They are not strict video filters — they return mixed content that simply leans heavier on video. Don't rely on them as a server-side video filter; filter client-side.
__INITIAL_STATE__ and decode the feedimport fs from "node:fs";
const html = fs.readFileSync("/tmp/xhs-explore.html", "utf8");
const m = html.match(/window\.__INITIAL_STATE__\s*=\s*(\{[\s\S]*?\})\s*<\/script>/);
// XHS emits `undefined` literals — replace before JSON.parse
const state = JSON.parse(m[1].replace(/:\s*undefined/g, ":null"));
const feeds = state.feed.feeds;
feeds is an array of { id, modelType, noteCard, xsecToken, trackId, ... }. Each noteCard has the fields you actually want:
| Field | Description |
|---|---|
noteCard.displayTitle | The 1-line title shown on the card. Can be very short (1–2 chars) or contain emoji — never strip non-ASCII. |
noteCard.type | "video" or "normal" (image post). Filter === "video" for the short-video subset. |
noteCard.video.capa.duration | Video length in seconds (integer). Present only when type === "video". Range observed: 7 s – 560 s. |
noteCard.interactInfo.likedCount | Pre-formatted Chinese number string: "5844", "2.9万" (29k), "10万+" (100k+). Don't try to parse to an int — keep the string. |
noteCard.user.nickName / user.nickname | Author display name. Both casings appear; prefer nickName, fall back to nickname. |
noteCard.user.userId | Author's user id. |
f.id | Note id (24-char hex). |
f.xsecToken | Per-request access token. Required to build the canonical URL — without it the reader page returns "笔记不见了" / 404. |
https://www.xiaohongshu.com/explore/{f.id}?xsec_token={f.xsecToken}&xsec_source=pc_feed
xsec_source=pc_feed is the source tag matching what the SSR page would set when you click through. Any other value (e.g. pc_search) will also work but the source attribution differs.
For the short-video use case:
const shortVideos = feeds
.filter(f => f.noteCard?.type === "video")
.map(f => ({
title: f.noteCard.displayTitle,
duration_sec: f.noteCard.video.capa.duration,
likes: f.noteCard.interactInfo.likedCount,
author: f.noteCard.user.nickName || f.noteCard.user.nickname,
note_id: f.id,
url: `https://www.xiaohongshu.com/explore/${f.id}?xsec_token=${f.xsecToken}&xsec_source=pc_feed`,
}));
A single request yields ~6–19 short videos depending on the channel (fitness_v3 is heaviest at ~70% video; fashion_v3 is lightest at ~25%). To collect more than one batch, re-fetch — every fresh GET returns a different batch (0% overlap between two consecutive default-channel fetches in the converged test). The feed is freshly resampled per request, not paginated by cursor.
The XHS internal endpoint https://edith.xiaohongshu.com/api/sns/web/v1/homefeed accepts {cursor_score, num, category, refresh_type} POST bodies but is gated by an X-S HMAC signature and X-T timestamp computed in obfuscated browser JS. The signature rotates per build and there is no maintained open-source library that tracks it reliably. Don't try to forge the signature. If you need more than the SSR batch, the honest path is to drive a real browser (Browserbase remote, --advanced-stealth --proxies), navigate to /explore, scroll, and re-extract window.__INITIAL_STATE__.feed.feeds after each scroll-triggered append.
# Mandatory: residential proxy + advanced stealth, both flags.
SID=$(bb sessions create --keep-alive --proxies --advanced-stealth | jq -r '.id')
browse --connect "$SID" open "https://www.xiaohongshu.com/explore"
browse --connect "$SID" wait selector ".note-item"
# Read the first batch from the rendered page
browse --connect "$SID" get html body > page-1.html
# Trigger more loads
for i in 1 2 3 4; do
browse --connect "$SID" scroll 600 400 0 1500
browse --connect "$SID" wait timeout 1500
done
browse --connect "$SID" get html body > page-deep.html
# Same regex on the rendered DOM yields the deeper appended cards.
Deduplicate by f.id across batches.
--proxies is required, full stop. Datacenter IPs receive a 10,352-byte HTML stub with no __INITIAL_STATE__, no feeds[], and only a formula-runtime JS bootstrap. Residential IPs receive ~579 KB with the full SSR payload. Both responses return HTTP 200, so don't gate on status code — gate on response body size (>100 KB) or on html.includes("__INITIAL_STATE__").undefined literals inside the JSON state, which JSON.parse rejects. Always run raw.replace(/:\s*undefined/g, ":null") (or equivalent) before parsing. The OpenSearch CSP-friendly value is null.xsec_token is per-request and required for canonical URLs. Reusing a token from yesterday's fetch will 404 the reader page. Either keep the token alongside the note id, or re-fetch immediately before navigating.displayTitle may be 1–2 characters or pure emoji ("练", "📷课代表上线"). Don't strip non-ASCII, don't drop short titles — those are real cards, often the most viral.likedCount is a pre-formatted Chinese display string, not an integer: "5844", "2.9万" (29,000), "10万+" (>100k). Decode formula: "X.Y万" = X.Y × 10000, "X万+" = >X × 10000. Keep the raw string in your output for fidelity; parse to a numeric only at sort/threshold time.homefeed.video_feed and homefeed.video_v2_feed are NOT strict video filters, despite the name. They return mixed content (15 video + 12 image in one observed run for video_feed; 7 video + 15 image for video_v2_feed). Always filter noteCard.type === "video" client-side regardless of channel./explore returned 23 and 27 cards with zero overlap by f.id. To collect a wider sample, loop the GET (with a short delay) and dedupe by id — don't try to find a ?page=2 param. None exist.X-S/X-T signature for the /api/sns/web/v1/homefeed POST endpoint. The hash is computed by minified, regularly-rotated browser JS and there is no maintained signature lib. Confirmed dead-end during testing — only reachable from a real browser context after the page boots.640c6b480000000027011016). The first 8 hex chars encode the post creation timestamp (Unix epoch in seconds) — parseInt(id.slice(0,8), 16) gives the creation time, useful for filtering "trending in the last 24h".www.xiaohongshu.com/en/newsroom/) but no English explore feed.A JSON object with success, the channel queried, the timestamp of capture, and an array of short-video items. Each item carries the title, type, duration, like count, author, and a clickable canonical URL.
{
"success": true,
"channel_id": "homefeed_recommend",
"fetched_at": "2026-05-18T21:19:14Z",
"total_cards": 23,
"short_videos": [
{
"title": "救命🆘这里有一只芭蕾小熊哇~",
"type": "video",
"duration_sec": 19,
"likes": "3.4万",
"author": "饭一碗",
"note_id": "640c6b480000000027011016",
"url": "https://www.xiaohongshu.com/explore/640c6b480000000027011016?xsec_token=ABDqV1xAR3SEoDdoB40_yD04rQV8-A8MpNSgFQSdePSyc=&xsec_source=pc_feed"
},
{
"title": "姐妹试这个中分丸子新扎法技巧 巨好看!",
"type": "video",
"duration_sec": 81,
"likes": "4.8万",
"author": "漫妮Fiona",
"note_id": "63e9d57e0000000014024b16",
"url": "https://www.xiaohongshu.com/explore/63e9d57e0000000014024b16?xsec_token=...&xsec_source=pc_feed"
},
{
"title": "练",
"type": "video",
"duration_sec": 75,
"likes": "10万+",
"author": "白敬亭",
"note_id": "6481cf3b000000001300a7a6",
"url": "https://www.xiaohongshu.com/explore/6481cf3b000000001300a7a6?xsec_token=...&xsec_source=pc_feed"
}
]
}
Failure shape when the anti-bot wall fires (datacenter IP, no --proxies):
{
"success": false,
"reason": "antibot_stub",
"detail": "Response body is 10352 bytes with no window.__INITIAL_STATE__ block — residential proxy was not applied. Re-issue with `bb fetch --proxies`."
}
Empty-channel shape (none of the canonical channels return empty in practice, but be defensive):
{
"success": true,
"channel_id": "homefeed.gaming_v3",
"fetched_at": "2026-05-18T21:19:14Z",
"total_cards": 22,
"short_videos": []
}
AI-first code editor with Composer
Before installing skills in Cursor, ensure your development environment meets these requirements:
node --versionget-trending-contentExecute the skills CLI command in your project's root directory to begin installation:
browse install xiaohongshu.com/get-trending-content-lrb8axFetches get-trending-content from xiaohongshu.com/get-trending-content-lrb8ax and configures it for Cursor.
The CLI shows a list of agents. Use arrow keys and space to select Cursor:
Confirm successful installation by checking the skill directory location:
.cursor/skills/get-trending-content
Restart Cursor to activate get-trending-content. Access via /get-trending-contentin your agent's command palette.
Learn more:View source on GitHubSkills CLI docsAbout CursorWhat are agent skills?
Steps
Common Pitfalls
✓ Do
✗ Don't
💡 Pro Tips
✓ Use when
Use when skill capabilities match your task, clear ROI on time saved, and you can validate outputs. Best for repetitive tasks, learning, and quality improvement.
✗ Avoid when
Avoid when task requires deep expertise you can't validate, involves sensitive decisions, or when learning process is more valuable than speed of completion.
xiaohongshu-skills
autoclaw-cc/xiaohongshu-skills · Productivity · tag: xiaohongshu
write-xiaohongshu
adjfks/corner-skills · Productivity · tag: xiaohongshu
rednote-skill
mrmao007/rednote-skills · Productivity · tag: rednote
xiaohongshu-images
iamzifei/xiaohongshu-images-skill · Productivity · tag: xiaohongshu
xiaohongshu-converter
z0gsh1u/oh-my-writing-skill · Productivity · tag: xiaohongshu
xiaohongshu
zhjiang22/openclaw-xhs · Productivity · tag: xiaohongshu
Registry listing for get-trending-content matched our evaluation — installs cleanly and behaves as described in the markdown.
get-trending-content is among the better-maintained entries we tried; worth keeping pinned for repeat workflows.
Useful defaults in get-trending-content — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
Keeps context tight: get-trending-content is the kind of skill you can hand to a new teammate without a long onboarding doc.
get-trending-content reduced setup friction for our internal harness; good balance of opinion and flexibility.
Useful defaults in get-trending-content — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
Keeps context tight: get-trending-content is the kind of skill you can hand to a new teammate without a long onboarding doc.
get-trending-content is among the better-maintained entries we tried; worth keeping pinned for repeat workflows.
We added get-trending-content from the explainx registry; install was straightforward and the SKILL.md answered most questions upfront.
get-trending-content reduced setup friction for our internal harness; good balance of opinion and flexibility.
showing 1-10 of 33