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.
Works with
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:
Fetches 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:
Restart Cursor to activate get-trending-content. Access via /get-trending-content in your agent's command palette.
We perform automated surface-level scans (Gen AI Scanner, Socket, Snyk) during installation. These checks detect common vulnerabilities but do not guarantee complete security. Always review skill source code and verify the publisher's reputation before production use.
Skills execute code in your environment. Always review source, verify the publisher, and test in isolation before production.
Submit your Claude Code skill and start earning
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
0
total installs
0
this week
0
upvotes
Run in your terminal
0
installs
0
this week
—
stars
| 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": []
}
Prerequisites
Time Estimate
15-45 minutes depending on use case complexity
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.
autoclaw-cc/xiaohongshu-skills
adjfks/corner-skills
mrmao007/rednote-skills
z0gsh1u/oh-my-writing-skill
softbread/xiaohongshu-doctor
zhjiang22/openclaw-xhs
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