├── .github ├── dependabot.yml └── workflows │ └── ci.yml ├── .gitignore ├── .node-version ├── .vitepress ├── config │ ├── data.ts │ ├── index.ts │ ├── shared.ts │ └── zh.ts └── theme │ ├── components │ ├── Banner.vue │ ├── CopyButton.vue │ ├── InstanceList.vue │ ├── Route.vue │ ├── Site.vue │ └── Sponsors.vue │ ├── index.ts │ ├── style.css │ └── types.ts ├── README.md ├── package.json ├── pnpm-lock.yaml └── src ├── contributors.md ├── deploy ├── config.md └── index.md ├── ecosystem.md ├── guide ├── api.md ├── faqs.md ├── index.md ├── instances.md ├── parameters.md └── troubleshooting.md ├── index.md ├── joinus ├── advanced │ ├── advanced-feed.md │ ├── debug.md │ ├── pub-date.md │ ├── script-standard.md │ └── use-cache.md ├── index.md └── new-rss │ ├── before-start.md │ ├── prerequisites.md │ ├── start-code.md │ └── submit-route.md ├── public ├── favicon.ico ├── img │ ├── android-chrome-192x192.png │ ├── android-chrome-384x384.png │ ├── apple-touch-icon.png │ ├── logo.png │ ├── readable-douban.png │ ├── readable-twitter.png │ ├── readable-weibo.png │ └── safari-pinned-tab.svg └── logo.png ├── routes ├── anime.md ├── bbs.md ├── blog.md ├── design.md ├── finance.md ├── forecast.md ├── game.md ├── government.md ├── journal.md ├── live.md ├── multimedia.md ├── new-media.md ├── other.md ├── picture.md ├── popular.md ├── program-update.md ├── programming.md ├── reading.md ├── shopping.md ├── social-media.md ├── study.md ├── traditional-media.md ├── travel.md └── university.md └── zh ├── contributors.md ├── deploy ├── config.md └── index.md ├── ecosystem.md ├── guide ├── api.md ├── faqs.md ├── index.md ├── instances.md ├── parameters.md └── troubleshooting.md ├── index.md ├── joinus ├── advanced │ ├── advanced-feed.md │ ├── debug.md │ ├── pub-date.md │ ├── script-standard.md │ └── use-cache.md ├── index.md └── new-rss │ ├── before-start.md │ ├── prerequisites.md │ ├── start-code.md │ └── submit-route.md └── routes ├── anime.md ├── bbs.md ├── blog.md ├── design.md ├── finance.md ├── forecast.md ├── game.md ├── government.md ├── journal.md ├── live.md ├── multimedia.md ├── new-media.md ├── other.md ├── picture.md ├── popular.md ├── program-update.md ├── programming.md ├── reading.md ├── shopping.md ├── social-media.md ├── study.md ├── traditional-media.md ├── travel.md └── university.md /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: '/' 5 | schedule: 6 | interval: daily 7 | open-pull-requests-limit: 10 8 | labels: 9 | - dependencies 10 | 11 | - package-ecosystem: 'github-actions' 12 | directory: '/' 13 | schedule: 14 | interval: daily 15 | open-pull-requests-limit: 10 16 | labels: 17 | - dependencies 18 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | push: 4 | branches: ['main'] 5 | pull_request: 6 | branches: ['main'] 7 | 8 | permissions: 9 | contents: read 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | timeout-minutes: 10 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@v4 18 | - name: Install pnpm 19 | uses: pnpm/action-setup@v4 20 | - name: Use Node.js Active LTS 21 | uses: actions/setup-node@v4 22 | with: 23 | node-version: lts/* 24 | cache: 'pnpm' 25 | - name: Install dependencies 26 | run: pnpm i 27 | - name: Build docs 28 | run: pnpm run docs:build 29 | 30 | automerge: 31 | if: github.triggering_actor == 'dependabot[bot]' && github.event_name == 'pull_request' 32 | needs: build 33 | runs-on: ubuntu-latest 34 | permissions: 35 | pull-requests: write 36 | contents: write 37 | steps: 38 | - uses: fastify/github-action-merge-dependabot@v3 39 | with: 40 | github-token: ${{ secrets.GITHUB_TOKEN }} 41 | target: minor 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | cache -------------------------------------------------------------------------------- /.node-version: -------------------------------------------------------------------------------- 1 | lts/* 2 | -------------------------------------------------------------------------------- /.vitepress/config/data.ts: -------------------------------------------------------------------------------- 1 | export const categories = [ 2 | { 3 | icon: '🌟', 4 | link: '/routes/popular', 5 | en: 'Popular', 6 | zh: '热门', 7 | }, 8 | { 9 | icon: '💬', 10 | link: '/routes/social-media', 11 | en: 'Social Media', 12 | zh: '社交媒体', 13 | }, 14 | { 15 | icon: '📱', 16 | link: '/routes/new-media', 17 | en: 'New media', 18 | zh: '新媒体', 19 | }, 20 | { 21 | icon: '📰', 22 | link: '/routes/traditional-media', 23 | en: 'Traditional media', 24 | zh: '传统媒体', 25 | }, 26 | { 27 | icon: '💬️', 28 | link: '/routes/bbs', 29 | en: 'BBS', 30 | zh: '论坛', 31 | }, 32 | { 33 | icon: '🖊️️', 34 | link: '/routes/blog', 35 | en: 'Blog', 36 | zh: '博客', 37 | }, 38 | { 39 | icon: '💻', 40 | link: '/routes/programming', 41 | en: 'Programming', 42 | zh: '编程', 43 | }, 44 | { 45 | icon: '🎨️', 46 | link: '/routes/design', 47 | en: 'Design', 48 | zh: '设计', 49 | }, 50 | { 51 | icon: '🎥', 52 | link: '/routes/live', 53 | en: 'Live', 54 | zh: '直播', 55 | }, 56 | { 57 | icon: '🔊', 58 | link: '/routes/multimedia', 59 | en: 'Multimedia', 60 | zh: '音视频', 61 | }, 62 | { 63 | icon: '🖼️', 64 | link: '/routes/picture', 65 | en: 'Picture', 66 | zh: '图片', 67 | }, 68 | { 69 | icon: '🎨️', 70 | link: '/routes/anime', 71 | en: 'ACG', 72 | zh: '二次元', 73 | }, 74 | { 75 | icon: '🔄', 76 | link: '/routes/program-update', 77 | en: 'Application Updates', 78 | zh: '程序更新', 79 | }, 80 | { 81 | icon: '🎓', 82 | link: '/routes/university', 83 | en: 'University', 84 | zh: '大学通知', 85 | }, 86 | { 87 | icon: '❗️', 88 | link: '/routes/forecast', 89 | en: 'Forecast and Alerts', 90 | zh: '预报预警', 91 | }, 92 | { 93 | icon: '🛫', 94 | link: '/routes/travel', 95 | en: 'Travel', 96 | zh: '出行旅游', 97 | }, 98 | { 99 | icon: '🛍️', 100 | link: '/routes/shopping', 101 | en: 'Shopping', 102 | zh: '购物', 103 | }, 104 | { 105 | icon: '🎮', 106 | link: '/routes/game', 107 | en: 'Gaming', 108 | zh: '游戏', 109 | }, 110 | { 111 | icon: '📚', 112 | link: '/routes/reading', 113 | en: 'Reading', 114 | zh: '阅读', 115 | }, 116 | { 117 | icon: '📢', 118 | link: '/routes/government', 119 | en: 'Government', 120 | zh: '政务消息', 121 | }, 122 | { 123 | icon: '📖', 124 | link: '/routes/study', 125 | en: 'Study', 126 | zh: '学习', 127 | }, 128 | { 129 | icon: '🔬', 130 | link: '/routes/journal', 131 | en: 'Scientific Journal', 132 | zh: '科学期刊', 133 | }, 134 | { 135 | icon: '💰', 136 | link: '/routes/finance', 137 | en: 'Finance', 138 | zh: '金融', 139 | }, 140 | { 141 | icon: '🔍', 142 | link: '/routes/other', 143 | en: 'Uncategorized', 144 | zh: '其他', 145 | }, 146 | ]; 147 | -------------------------------------------------------------------------------- /.vitepress/config/index.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitepress' 2 | import { shared } from './shared' 3 | import { zh } from './zh' 4 | 5 | export default defineConfig({ 6 | ...shared, 7 | locales: { 8 | root: { label: 'English', lang: 'en' }, 9 | zh: { label: '简体中文', ...zh }, 10 | } 11 | }) -------------------------------------------------------------------------------- /.vitepress/config/shared.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig, type DefaultTheme } from 'vitepress' 2 | import { categories } from './data' 3 | 4 | const telegramLogo = ` 5 | 6 | 7 | 8 | Artboard 9 | Created with Sketch. 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | ` 22 | 23 | export const shared = defineConfig({ 24 | title: "RSSHub", 25 | description: "Everything is RSSible 🧡", 26 | srcDir: 'src', 27 | lastUpdated: true, 28 | ignoreDeadLinks: true, 29 | cleanUrls: true, 30 | markdown: { 31 | theme: { 32 | light: 'github-light', 33 | dark: 'github-dark', 34 | }, 35 | }, 36 | 37 | head: [ 38 | ['meta', { property: 'og:image', content: 'https://docs.rsshub.app/logo.png' }], 39 | ['meta', { property: 'og:type', content: 'website' }], 40 | ['meta', { property: 'twitter:domain', content: 'rsshub.app' }], 41 | ['meta', { property: 'twitter:image', content: 'https://docs.rsshub.app/logo.png' }], 42 | ['meta', { property: 'twitter:card', content: 'summary_large_image' }], 43 | ['link', { rel: 'shortcut icon', href: '/favicon.ico' }], 44 | ['script', { 45 | src: 'https://umami.diygod.dev/script.js', 46 | 'data-website-id': 'be1761be-7547-49d5-91b8-5c97c8f7cec7', 47 | defer: '' 48 | }] 49 | ], 50 | 51 | themeConfig: { 52 | logo: '/logo.png', 53 | carbonAds: { 54 | code: 'CEAI653E', 55 | placement: 'docsrsshubapp' 56 | }, 57 | outline: { 58 | level: [2, 3], 59 | }, 60 | search: { 61 | provider: 'local', 62 | options: { 63 | miniSearch: { 64 | options: { 65 | extractField: (document, fieldName) => { 66 | if (fieldName !== 'text' || document.id.includes('/routes/')) { 67 | return document[fieldName] 68 | } 69 | }, 70 | }, 71 | searchOptions: { 72 | boost: { title: 1, text: 0.1, titles: 1 } 73 | } 74 | } 75 | } 76 | }, 77 | 78 | // https://vitepress.dev/reference/default-theme-config 79 | nav: [ 80 | { text: 'Home', link: '/' }, 81 | { text: 'Guide', link: '/guide/' }, 82 | { text: 'Develop', link: '/joinus/' }, 83 | { text: 'Deploy', link: '/deploy/' }, 84 | { text: 'Ecosystem', link: '/ecosystem' }, 85 | { text: 'Contributors', link: '/contributors' }, 86 | ], 87 | 88 | socialLinks: [ 89 | { icon: 'github', link: 'https://github.com/DIYgod/RSSHub' }, 90 | { icon: { svg: telegramLogo }, link: 'https://t.me/rsshub' }, 91 | { icon: { svg: telegramLogo }, link: 'https://t.me/awesomeRSSHub' }, 92 | { icon: 'x', link: 'https://x.com/intent/follow?screen_name=_RSSHub' }, 93 | ], 94 | editLink: { 95 | pattern: 'https://github.com/DIYgod/RSSHub-Docs/edit/main/src/:path', 96 | text: 'Edit this page on GitHub', 97 | }, 98 | 99 | footer: { 100 | message: 'Released under the MIT License.', 101 | copyright: `© ${new Date().getFullYear()}. An Open project.` 102 | }, 103 | 104 | sidebar: { 105 | '/joinus/': [ 106 | { 107 | text: 'Develop', 108 | items: [ 109 | { text: 'Quick Start', link: '/joinus/' }, 110 | { text: 'Development Environment', link: '/joinus/new-rss/prerequisites' }, 111 | { text: 'Just before you start', link: '/joinus/new-rss/before-start' }, 112 | { text: 'Create Route', link: '/joinus/new-rss/start-code' }, 113 | { text: 'Submit your route', link: '/joinus/new-rss/submit-route' }, 114 | ], 115 | }, 116 | { 117 | text: 'Advanced', 118 | items: [ 119 | { text: 'RSS Feed Fundamentals', link: '/joinus/advanced/advanced-feed' }, 120 | { text: 'Script Standard', link: '/joinus/advanced/script-standard' }, 121 | { text: 'Using Cache', link: '/joinus/advanced/use-cache' }, 122 | { text: 'Date Handling', link: '/joinus/advanced/pub-date' }, 123 | { text: 'Debugging', link: '/joinus/advanced/debug' }, 124 | ] 125 | } 126 | ], 127 | '/deploy/': [ 128 | { 129 | text: 'Deploy', 130 | items: [ 131 | { text: 'Deployment', link: '/deploy/' }, 132 | { text: 'Configuration', link: '/deploy/config' }, 133 | ], 134 | } 135 | ], 136 | '/guide/': sidebarGuide(), 137 | '/routes/': sidebarGuide(), 138 | }, 139 | }, 140 | }) 141 | 142 | function sidebarGuide(): DefaultTheme.SidebarItem[] { 143 | return [ 144 | { 145 | text: 'Guide', 146 | items: [ 147 | { text: 'Getting Started', link: '/guide/' }, 148 | { text: 'Public Instances', link: '/guide/instances' }, 149 | { text: 'FAQs', link: '/guide/faqs' }, 150 | { text: 'Troubleshooting', link: '/guide/troubleshooting' }, 151 | { text: 'Parameters', link: '/guide/parameters' }, 152 | { text: 'API', link: '/guide/api' }, 153 | ], 154 | }, 155 | { 156 | text: 'Routes', 157 | items: categories.map((category) => ({ 158 | text: `${category.icon} ${category.en}`, 159 | link: category.link, 160 | })), 161 | }, 162 | ] 163 | } 164 | -------------------------------------------------------------------------------- /.vitepress/config/zh.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig, type DefaultTheme } from 'vitepress' 2 | import { categories } from './data' 3 | 4 | export const zh = defineConfig({ 5 | lang: 'zh-Hans', 6 | description: "万物皆可 RSS 🧡", 7 | 8 | themeConfig: { 9 | nav: [ 10 | { text: '首页', link: '/zh/' }, 11 | { text: '食用指南', link: '/zh/guide/' }, 12 | { text: '开发路由', link: '/zh/joinus/' }, 13 | { text: '部署', link: '/zh/deploy/' }, 14 | { text: '生态系统', link: '/zh/ecosystem' }, 15 | { text: '贡献者', link: '/zh/contributors' }, 16 | ], 17 | 18 | editLink: { 19 | pattern: 'https://github.com/DIYgod/RSSHub-Docs/edit/main/src/:path', 20 | text: '在 GitHub 上编辑此页面', 21 | }, 22 | 23 | footer: { 24 | message: '基于 MIT 许可发布', 25 | copyright: `版权所有 © 2018-${new Date().getFullYear()} DIYgod` 26 | }, 27 | 28 | docFooter: { 29 | prev: '上一页', 30 | next: '下一页' 31 | }, 32 | 33 | outline: { 34 | level: [2, 3], 35 | label: '页面导航' 36 | }, 37 | 38 | lastUpdated: { 39 | text: '最后更新于', 40 | formatOptions: { 41 | dateStyle: 'short', 42 | timeStyle: 'medium' 43 | } 44 | }, 45 | 46 | langMenuLabel: '多语言', 47 | returnToTopLabel: '回到顶部', 48 | sidebarMenuLabel: '菜单', 49 | darkModeSwitchLabel: '主题', 50 | lightModeSwitchTitle: '切换到浅色模式', 51 | darkModeSwitchTitle: '切换到深色模式', 52 | 53 | sidebar: { 54 | '/zh/joinus/': [ 55 | { 56 | text: '开发路由', 57 | items: [ 58 | { text: '快速开始', link: '/zh/joinus/' }, 59 | { text: '开发环境', link: '/zh/joinus/new-rss/prerequisites' }, 60 | { text: '开始之前', link: '/zh/joinus/new-rss/before-start' }, 61 | { text: '制作路由', link: '/zh/joinus/new-rss/start-code' }, 62 | { text: '提交路由', link: '/zh/joinus/new-rss/submit-route' }, 63 | ], 64 | }, 65 | { 66 | text: '高级用法', 67 | items: [ 68 | { text: 'RSS 基础', link: '/zh/joinus/advanced/advanced-feed' }, 69 | { text: '路由规范', link: '/zh/joinus/advanced/script-standard' }, 70 | { text: '使用缓存', link: '/zh/joinus/advanced/use-cache' }, 71 | { text: '日期处理', link: '/zh/joinus/advanced/pub-date' }, 72 | { text: '调试', link: '/zh/joinus/advanced/debug' }, 73 | ] 74 | } 75 | ], 76 | '/zh/deploy/': [ 77 | { 78 | text: '部署', 79 | items: [ 80 | { text: '部署', link: '/zh/deploy/' }, 81 | { text: '配置', link: '/zh/deploy/config' }, 82 | ], 83 | } 84 | ], 85 | '/zh/guide/': sidebarGuide(), 86 | '/zh/routes/': sidebarGuide(), 87 | }, 88 | }, 89 | }) 90 | 91 | function sidebarGuide(): DefaultTheme.SidebarItem[] { 92 | return [ 93 | { 94 | text: '指南', 95 | items: [ 96 | { text: '开始食用', link: '/zh/guide/' }, 97 | { text: '公共实例', link: '/zh/guide/instances' }, 98 | { text: '常见问题', link: '/zh/guide/faqs' }, 99 | { text: '故障排除', link: '/zh/guide/troubleshooting' }, 100 | { text: '通用参数', link: '/zh/guide/parameters' }, 101 | { text: 'API', link: '/zh/guide/api' }, 102 | ], 103 | }, 104 | { 105 | text: '路由', 106 | items: categories.map((category) => ({ 107 | text: `${category.icon} ${category.zh}`, 108 | link: '/zh' + category.link, 109 | })), 110 | }, 111 | ] 112 | } 113 | -------------------------------------------------------------------------------- /.vitepress/theme/components/Banner.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 25 | 26 | -------------------------------------------------------------------------------- /.vitepress/theme/components/CopyButton.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | -------------------------------------------------------------------------------- /.vitepress/theme/components/InstanceList.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 132 | 133 | 174 | -------------------------------------------------------------------------------- /.vitepress/theme/components/Route.vue: -------------------------------------------------------------------------------- 1 | 122 | 123 | -------------------------------------------------------------------------------- /.vitepress/theme/components/Site.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 25 | 26 | -------------------------------------------------------------------------------- /.vitepress/theme/components/Sponsors.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 18 | 19 | 54 | -------------------------------------------------------------------------------- /.vitepress/theme/index.ts: -------------------------------------------------------------------------------- 1 | // https://vitepress.dev/guide/custom-theme 2 | import { h } from 'vue' 3 | import type { Theme } from 'vitepress' 4 | import DefaultTheme from 'vitepress/theme' 5 | import './style.css' 6 | import Route from './components/Route.vue' 7 | import Site from './components/Site.vue' 8 | import Sponsors from './components/Sponsors.vue' 9 | import InstanceList from './components/InstanceList.vue' 10 | import CopyButtonVue from './components/CopyButton.vue' 11 | import Banner from './components/Banner.vue' 12 | 13 | export default { 14 | extends: DefaultTheme, 15 | Layout: () => { 16 | return h(DefaultTheme.Layout, null, { 17 | // https://vitepress.dev/guide/extending-default-theme#layout-slots 18 | }) 19 | }, 20 | enhanceApp({ app, router, siteData }) { 21 | // ... 22 | app.component('Route', Route) 23 | app.component('Site', Site) 24 | app.component('Sponsors', Sponsors) 25 | app.component('InstanceList', InstanceList) 26 | app.component('CopyButton', CopyButtonVue) 27 | app.component('Banner', Banner) 28 | } 29 | } satisfies Theme 30 | -------------------------------------------------------------------------------- /.vitepress/theme/style.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Customize default theme styling by overriding CSS variables: 3 | * https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css 4 | */ 5 | 6 | /** 7 | * Colors 8 | * 9 | * Each colors have exact same color scale system with 3 levels of solid 10 | * colors with different brightness, and 1 soft color. 11 | * 12 | * - `XXX-1`: The most solid color used mainly for colored text. It must 13 | * satisfy the contrast ratio against when used on top of `XXX-soft`. 14 | * 15 | * - `XXX-2`: The color used mainly for hover state of the button. 16 | * 17 | * - `XXX-3`: The color for solid background, such as bg color of the button. 18 | * It must satisfy the contrast ratio with pure white (#ffffff) text on 19 | * top of it. 20 | * 21 | * - `XXX-soft`: The color used for subtle background such as custom container 22 | * or badges. It must satisfy the contrast ratio when putting `XXX-1` colors 23 | * on top of it. 24 | * 25 | * The soft color must be semi transparent alpha channel. This is crucial 26 | * because it allows adding multiple "soft" colors on top of each other 27 | * to create a accent, such as when having inline code block inside 28 | * custom containers. 29 | * 30 | * - `default`: The color used purely for subtle indication without any 31 | * special meanings attched to it such as bg color for menu hover state. 32 | * 33 | * - `brand`: Used for primary brand colors, such as link text, button with 34 | * brand theme, etc. 35 | * 36 | * - `tip`: Used to indicate useful information. The default theme uses the 37 | * brand color for this by default. 38 | * 39 | * - `warning`: Used to indicate warning to the users. Used in custom 40 | * container, badges, etc. 41 | * 42 | * - `danger`: Used to show error, or dangerous message to the users. Used 43 | * in custom container, badges, etc. 44 | * -------------------------------------------------------------------------- */ 45 | 46 | :root { 47 | --vp-c-default-1: var(--vp-c-gray-1); 48 | --vp-c-default-2: var(--vp-c-gray-2); 49 | --vp-c-default-3: var(--vp-c-gray-3); 50 | --vp-c-default-soft: var(--vp-c-gray-soft); 51 | 52 | --vp-c-brand-1: #ff894c; 53 | --vp-c-brand-2: #ff752e; 54 | --vp-c-brand-3: #ff2900; 55 | --vp-c-brand-soft: var(--vp-c-indigo-soft); 56 | 57 | --vp-c-tip-1: var(--vp-c-brand-1); 58 | --vp-c-tip-2: var(--vp-c-brand-2); 59 | --vp-c-tip-3: var(--vp-c-brand-3); 60 | --vp-c-tip-soft: var(--vp-c-brand-soft); 61 | 62 | --vp-c-warning-1: var(--vp-c-yellow-1); 63 | --vp-c-warning-2: var(--vp-c-yellow-2); 64 | --vp-c-warning-3: var(--vp-c-yellow-3); 65 | --vp-c-warning-soft: var(--vp-c-yellow-soft); 66 | 67 | --vp-c-danger-1: var(--vp-c-red-1); 68 | --vp-c-danger-2: var(--vp-c-red-2); 69 | --vp-c-danger-3: var(--vp-c-red-3); 70 | --vp-c-danger-soft: var(--vp-c-red-soft); 71 | } 72 | 73 | /** 74 | * Component: Button 75 | * -------------------------------------------------------------------------- */ 76 | 77 | :root { 78 | --vp-button-brand-border: transparent; 79 | --vp-button-brand-text: var(--vp-c-white); 80 | --vp-button-brand-bg: var(--vp-c-brand-3); 81 | --vp-button-brand-hover-border: transparent; 82 | --vp-button-brand-hover-text: var(--vp-c-white); 83 | --vp-button-brand-hover-bg: var(--vp-c-brand-2); 84 | --vp-button-brand-active-border: transparent; 85 | --vp-button-brand-active-text: var(--vp-c-white); 86 | --vp-button-brand-active-bg: var(--vp-c-brand-1); 87 | } 88 | 89 | /** 90 | * Component: Home 91 | * -------------------------------------------------------------------------- */ 92 | 93 | :root { 94 | --vp-home-hero-name-color: transparent; 95 | --vp-home-hero-name-background: -webkit-linear-gradient( 96 | 120deg, 97 | #ff2900 5%, 98 | #ff752e 99 | ); 100 | 101 | --vp-home-hero-image-background-image: linear-gradient( 102 | 45deg, 103 | #ff2900 40%, 104 | #ffd6a6 40% 105 | ); 106 | --vp-home-hero-image-filter: blur(44px); 107 | } 108 | 109 | @media (min-width: 960px) { 110 | .VPHomeHero .VPImage, 111 | .VPHomeHero .image-bg { 112 | max-width: 280px; 113 | max-height: 280px; 114 | } 115 | } 116 | 117 | .VPHomeHero .image-container { 118 | transform: translate(0, -5px); 119 | } 120 | 121 | @media (min-width: 640px) { 122 | :root { 123 | --vp-home-hero-image-filter: blur(56px); 124 | } 125 | } 126 | 127 | @media (min-width: 960px) { 128 | :root { 129 | --vp-home-hero-image-filter: blur(68px); 130 | } 131 | } 132 | 133 | /** 134 | * Component: Custom Block 135 | * -------------------------------------------------------------------------- */ 136 | 137 | :root { 138 | --vp-custom-block-tip-border: transparent; 139 | --vp-custom-block-tip-text: var(--vp-c-text-1); 140 | --vp-custom-block-tip-bg: var(--vp-c-brand-soft); 141 | --vp-custom-block-tip-code-bg: var(--vp-c-brand-soft); 142 | } 143 | 144 | /** 145 | * Component: Algolia 146 | * -------------------------------------------------------------------------- */ 147 | 148 | .DocSearch { 149 | --docsearch-primary-color: var(--vp-c-brand-1) !important; 150 | } 151 | 152 | :root { 153 | --vp-c-text-1: #000; 154 | --vp-c-text-2: #454545; 155 | --vp-badge-tip-text: var(--vp-c-green-1); 156 | --vp-badge-tip-bg: var(--vp-c-green-soft); 157 | --vp-code-color: var(--vp-c-text-1); 158 | --vp-button-brand-bg: var(--vp-c-brand-2); 159 | --vp-button-brand-hover-bg: var(--vp-c-brand-1); 160 | --vp-badge-info-text: white; 161 | --vp-badge-info-bg: var(--vp-c-brand-1); 162 | } 163 | 164 | .dark { 165 | --vp-c-text-1: rgba(255, 255, 245, 0.86); 166 | --vp-c-text-2: rgba(235, 235, 245, 0.6); 167 | } 168 | 169 | .example img { 170 | vertical-align: text-bottom; 171 | margin-left: 10px; 172 | } 173 | .example .copy { 174 | vertical-align: text-bottom; 175 | margin-left: 10px; 176 | } 177 | .routeBlock ul { 178 | padding-left: 35px; 179 | } 180 | 181 | .VPDocOutlineItem.root > li > a { 182 | font-weight: 600; 183 | } 184 | 185 | .VPDocOutlineItem.nested a { 186 | font-size: 10px; 187 | line-height: 20px; 188 | } 189 | 190 | .VPDocAsideCarbonAds { 191 | position: sticky; 192 | bottom: 0px; 193 | z-index: 2; 194 | /* order: -1; */ 195 | } 196 | 197 | .VPHomeFeatures .item:nth-child(1), 198 | .VPHomeFeatures .item:nth-child(2) { 199 | width: 50%; 200 | } 201 | .VPHomeFeatures .item:nth-child(3), 202 | .VPHomeFeatures .item:nth-child(4), 203 | .VPHomeFeatures .item:nth-child(5) { 204 | width: calc(100% / 3); 205 | } 206 | @media (max-width: 640px) { 207 | .VPHomeFeatures .item:nth-child(1), 208 | .VPHomeFeatures .item:nth-child(2), 209 | .VPHomeFeatures .item:nth-child(3), 210 | .VPHomeFeatures .item:nth-child(4), 211 | .VPHomeFeatures .item:nth-child(5) { 212 | width: 100%; 213 | } 214 | } 215 | 216 | img { 217 | display: inline-block; 218 | } 219 | 220 | select { 221 | -webkit-appearance: auto; 222 | border: 1px solid #e2e8f0; 223 | padding: 2px 4px; 224 | } 225 | -------------------------------------------------------------------------------- /.vitepress/theme/types.ts: -------------------------------------------------------------------------------- 1 | import type { Context } from 'hono'; 2 | 3 | // Make sure it's synchronise with scripts/workflow/data.ts 4 | // and lib/routes/rsshub/routes.ts 5 | type Category = 6 | | 'popular' 7 | | 'social-media' 8 | | 'new-media' 9 | | 'traditional-media' 10 | | 'bbs' 11 | | 'blog' 12 | | 'programming' 13 | | 'design' 14 | | 'live' 15 | | 'multimedia' 16 | | 'picture' 17 | | 'anime' 18 | | 'program-update' 19 | | 'university' 20 | | 'forecast' 21 | | 'travel' 22 | | 'shopping' 23 | | 'game' 24 | | 'reading' 25 | | 'government' 26 | | 'study' 27 | | 'journal' 28 | | 'finance' 29 | | 'other'; 30 | 31 | // rss 32 | export type DataItem = { 33 | title: string; 34 | description?: string; 35 | pubDate?: number | string | Date; 36 | link?: string; 37 | category?: string[]; 38 | author?: 39 | | string 40 | | { 41 | name: string; 42 | url?: string; 43 | avatar?: string; 44 | }[]; 45 | doi?: string; 46 | guid?: string; 47 | id?: string; 48 | content?: { 49 | html: string; 50 | text: string; 51 | }; 52 | image?: string; 53 | banner?: string; 54 | updated?: number | string | Date; 55 | language?: Language; 56 | enclosure_url?: string; 57 | enclosure_type?: string; 58 | enclosure_title?: string; 59 | enclosure_length?: number; 60 | itunes_duration?: number | string; 61 | itunes_item_image?: string; 62 | media?: Record>; 63 | attachments?: { 64 | url: string; 65 | mime_type: string; 66 | title?: string; 67 | size_in_bytes?: number; 68 | duration_in_seconds?: number; 69 | }[]; 70 | 71 | _extra?: Record & { 72 | links?: { 73 | url: string; 74 | type: string; 75 | content_html?: string; 76 | }[]; 77 | }; 78 | }; 79 | 80 | export type Data = { 81 | title: string; 82 | description?: string; 83 | link?: string; 84 | item?: DataItem[]; 85 | allowEmpty?: boolean; 86 | image?: string; 87 | author?: string; 88 | language?: Language; 89 | feedLink?: string; 90 | lastBuildDate?: string; 91 | itunes_author?: string; 92 | itunes_category?: string; 93 | itunes_explicit?: string | boolean; 94 | id?: string; 95 | icon?: string; 96 | logo?: string; 97 | atomlink?: string; 98 | ttl?: number; 99 | }; 100 | 101 | type Language = 102 | | 'af' 103 | | 'sq' 104 | | 'eu' 105 | | 'be' 106 | | 'bg' 107 | | 'ca' 108 | | 'zh-CN' 109 | | 'zh-TW' 110 | | 'zh-HK' 111 | | 'hr' 112 | | 'cs' 113 | | 'ar-DZ' 114 | | 'ar-SA' 115 | | 'ar-MA' 116 | | 'ar-IQ' 117 | | 'ar-KW' 118 | | 'ar-TN' 119 | | 'da' 120 | | 'nl' 121 | | 'nl-be' 122 | | 'nl-nl' 123 | | 'en' 124 | | 'en-au' 125 | | 'en-bz' 126 | | 'en-ca' 127 | | 'en-ie' 128 | | 'en-jm' 129 | | 'en-nz' 130 | | 'en-ph' 131 | | 'en-za' 132 | | 'en-tt' 133 | | 'en-gb' 134 | | 'en-us' 135 | | 'en-zw' 136 | | 'et' 137 | | 'fo' 138 | | 'fi' 139 | | 'fr' 140 | | 'fr-be' 141 | | 'fr-ca' 142 | | 'fr-fr' 143 | | 'fr-lu' 144 | | 'fr-mc' 145 | | 'fr-ch' 146 | | 'gl' 147 | | 'gd' 148 | | 'de' 149 | | 'de-at' 150 | | 'de-de' 151 | | 'de-li' 152 | | 'de-lu' 153 | | 'de-ch' 154 | | 'el' 155 | | 'haw' 156 | | 'hu' 157 | | 'is' 158 | | 'in' 159 | | 'ga' 160 | | 'it' 161 | | 'it-it' 162 | | 'it-ch' 163 | | 'ja' 164 | | 'ko' 165 | | 'mk' 166 | | 'no' 167 | | 'pl' 168 | | 'pt' 169 | | 'pt-br' 170 | | 'pt-pt' 171 | | 'ro' 172 | | 'ro-mo' 173 | | 'ro-ro' 174 | | 'ru' 175 | | 'ru-mo' 176 | | 'ru-ru' 177 | | 'sr' 178 | | 'sk' 179 | | 'sl' 180 | | 'es' 181 | | 'es-ar' 182 | | 'es-bo' 183 | | 'es-cl' 184 | | 'es-co' 185 | | 'es-cr' 186 | | 'es-do' 187 | | 'es-ec' 188 | | 'es-sv' 189 | | 'es-gt' 190 | | 'es-hn' 191 | | 'es-mx' 192 | | 'es-ni' 193 | | 'es-pa' 194 | | 'es-py' 195 | | 'es-pe' 196 | | 'es-pr' 197 | | 'es-es' 198 | | 'es-uy' 199 | | 'es-ve' 200 | | 'sv' 201 | | 'sv-fi' 202 | | 'sv-se' 203 | | 'tr' 204 | | 'uk' 205 | | 'ne' 206 | | 'other'; 207 | 208 | // namespace 209 | interface NamespaceItem { 210 | /** 211 | * The human-readable name of the namespace, should be the same as the secondary domain of the main website, 212 | * which will be used as the level 2 heading in the documentation 213 | */ 214 | name: string; 215 | 216 | /** 217 | * The website URL without protocol that corresponds 218 | */ 219 | url?: string; 220 | 221 | /** 222 | * The classification of the namespace, which will be written into the corresponding classification document 223 | */ 224 | categories?: Category[]; 225 | 226 | /** 227 | * Hints and additional explanations for users using this namespace, it will be inserted into the documentation 228 | */ 229 | description?: string; 230 | 231 | /** 232 | * Main Language of the namespace 233 | */ 234 | lang?: Language; 235 | } 236 | 237 | interface Namespace extends NamespaceItem { 238 | /** Documentation in languages other than English, it will be used to generate multilingual documents */ 239 | ja?: NamespaceItem; 240 | /** Documentation in languages other than English, it will be used to generate multilingual documents */ 241 | zh?: NamespaceItem; 242 | /** Documentation in languages other than English, it will be used to generate multilingual documents */ 243 | 'zh-TW'?: NamespaceItem; 244 | } 245 | 246 | export type { Namespace }; 247 | 248 | export enum ViewType { 249 | Articles = 0, 250 | SocialMedia = 1, 251 | Pictures = 2, 252 | Videos = 3, 253 | Audios = 4, 254 | Notifications = 5, 255 | } 256 | 257 | // route 258 | interface RouteItem { 259 | /** 260 | * The route path, using [Hono routing](https://hono.dev/api/routing) syntax 261 | */ 262 | path: string | string[]; 263 | 264 | /** 265 | * The human-readable name of the route, which will be used as the level 3 heading in the documentation 266 | * and radar rule title (can be overridden by `RadarRule[].title`) 267 | */ 268 | name: string; 269 | 270 | /** 271 | * The website URL without protocol that corresponds 272 | */ 273 | url?: string; 274 | 275 | /** 276 | * The GitHub handle of the people responsible for maintaining this route 277 | */ 278 | maintainers: string[]; 279 | 280 | /** 281 | * The handler function of the route 282 | */ 283 | handler: (ctx: Context) => Promise | Data | null; 284 | 285 | /** 286 | * An example URL of the route 287 | */ 288 | example: string; 289 | 290 | /** 291 | * The description of the route parameters 292 | */ 293 | parameters?: Record< 294 | string, 295 | | string 296 | | { 297 | description: string; 298 | default?: string; 299 | options?: { 300 | value: string; 301 | label: string; 302 | }[]; 303 | } 304 | >; 305 | 306 | /** 307 | * Hints and additional explanations for users using this route, it will be appended after the route component, supports markdown 308 | */ 309 | description?: string; 310 | 311 | /** 312 | * The classification of the route, which will be written into the corresponding classification documentation 313 | */ 314 | categories?: Category[]; 315 | 316 | /** 317 | * Special features of the route, such as what configuration items it depends on, whether it is strict anti-crawl, whether it supports a certain function and so on 318 | */ 319 | features?: { 320 | /** The extra configuration items required by the route */ 321 | requireConfig?: 322 | | { 323 | /** The environment variable name */ 324 | name: string; 325 | /** Whether the environment variable is optional */ 326 | optional?: boolean; 327 | /** The description of the environment variable */ 328 | description: string; 329 | }[] 330 | | false; 331 | 332 | /** set to `true` if the feed uses puppeteer */ 333 | requirePuppeteer?: boolean; 334 | 335 | /** set to `true` if the target website has an anti-crawler mechanism */ 336 | antiCrawler?: boolean; 337 | 338 | /** set to `true` if the feed has a radar rule */ 339 | supportRadar?: boolean; 340 | 341 | /** Set to `true` if the feed supports BitTorrent */ 342 | supportBT?: boolean; 343 | 344 | /** Set to `true` if the feed supports podcasts */ 345 | supportPodcast?: boolean; 346 | 347 | /** Set to `true` if the feed supports Sci-Hub */ 348 | supportScihub?: boolean; 349 | }; 350 | 351 | /** 352 | * The [RSSHub-Radar](https://github.com/DIYgod/RSSHub-Radar) rule of the route 353 | */ 354 | radar?: RadarItem[]; 355 | 356 | /** 357 | * The [Follow](https://github.com/RSSNext/follow) default view of the route, default to `ViewType.Articles` 358 | */ 359 | view?: ViewType; 360 | } 361 | 362 | export interface Route extends RouteItem { 363 | ja?: RouteItem; 364 | zh?: RouteItem; 365 | 'zh-TW'?: RouteItem; 366 | } 367 | 368 | // radar 369 | export type RadarItem = { 370 | /** 371 | * The overwriting title of the radar rule 372 | */ 373 | title?: string; 374 | 375 | /** 376 | * The URL path to the corresponding documentation 377 | */ 378 | docs?: string; 379 | 380 | /** 381 | * The source URL path of the radar rule 382 | * @see https://docs.rsshub.app/joinus/new-radar#source 383 | */ 384 | source: string[]; 385 | 386 | /** 387 | * The target RSSHub subscription URL path of the radar rule 388 | * 389 | * Will use RouteItem.path if not specified 390 | * @see https://docs.rsshub.app/joinus/new-radar#target 391 | * 392 | * Using `target` as a function is deprecated in RSSHub-Radar 2.0.19 393 | * @see https://github.com/DIYgod/RSSHub-Radar/commit/5a97647f900bb2bca792787a322b2b1ca512e40b#diff-f84e3c1e16af314bc4ed7c706d7189844663cde9b5142463dc5c0db34c2e8d54L10 394 | * @see https://github.com/DIYgod/RSSHub-Radar/issues/692 395 | */ 396 | target?: 397 | | string 398 | | (( 399 | /** The parameters matched from the `source` field */ 400 | params: any, 401 | /** The current webpage URL string */ 402 | url: string, 403 | /** @deprecated Temporary removed @see https://github.com/DIYgod/RSSHub-Radar/commit/e6079ea1a8c96e89b1b2c2aa6d13c7967788ca3b */ 404 | document: Document 405 | ) => string); 406 | }; 407 | 408 | export type RadarDomain = { 409 | _name: string; 410 | } & { 411 | [subdomain: string]: RadarItem[]; 412 | }; 413 | 414 | export interface APIRoute { 415 | /** 416 | * The route path, using [Hono routing](https://hono.dev/api/routing) syntax 417 | */ 418 | path: string; 419 | 420 | /** 421 | * The GitHub handle of the people responsible for maintaining this route 422 | */ 423 | maintainers: string[]; 424 | 425 | /** 426 | * The handler function of the route 427 | */ 428 | handler: (ctx: Context) => 429 | | Promise<{ 430 | code: number; 431 | message?: string; 432 | data?: any; 433 | }> 434 | | { 435 | code: number; 436 | message?: string; 437 | data?: any; 438 | }; 439 | 440 | /** 441 | * The description of the route parameters 442 | */ 443 | parameters?: Record< 444 | string, 445 | { 446 | description: string; 447 | default?: string; 448 | options?: { 449 | value: string; 450 | label: string; 451 | }[]; 452 | } 453 | >; 454 | 455 | /** 456 | * Hints and additional explanations for users using this route, it will be appended after the route component, supports markdown 457 | */ 458 | description?: string; 459 | } 460 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RSSHub Docs 2 | 3 | [![Netlify Status](https://api.netlify.com/api/v1/badges/92bcc389-7411-432b-a119-74ca8d6b0d90/deploy-status)](https://app.netlify.com/sites/rsshub-docs-next/deploys) 4 | 5 | > [!WARNING] 6 | > The route document is automatically generated and uploaded from the RSSHub repository. If you want to modify the route document, please directly modify the corresponding route file in RSSHub. 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "scripts": { 4 | "docs:build": "vitepress build", 5 | "docs:dev": "vitepress dev", 6 | "docs:preview": "vitepress preview" 7 | }, 8 | "devDependencies": { 9 | "markdown-it": "14.1.0", 10 | "vitepress": "1.6.3", 11 | "vue": "3.5.16" 12 | }, 13 | "packageManager": "pnpm@10.11.1+sha512.e519b9f7639869dc8d5c3c5dfef73b3f091094b0a006d7317353c72b124e80e1afd429732e28705ad6bfa1ee879c1fce46c128ccebd3192101f43dd67c667912", 14 | "pnpm": { 15 | "onlyBuiltDependencies": [ 16 | "esbuild" 17 | ] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/contributors.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar: auto 3 | layout: home 4 | --- 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/deploy/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar: auto 3 | --- 4 | 5 | # Deployment 6 | 7 | RSSHub provides a painless deployment process if you are equipped with basic programming knowledge, you may open an [issue](https://github.com/DIYgod/RSSHub/issues/new/choose) if you believe you have encountered a problem not listed [here](https://github.com/DIYgod/RSSHub/issues), the community will try to sort it out asap. 8 | 9 | The deployment may involve the followings: 10 | 11 | 1. Command line interface 12 | 2. [Git](https://git-scm.com/) 13 | 3. [Node.js](https://nodejs.org/) 14 | 4. [npm](https://www.npmjs.com/get-npm) or [yarn](https://yarnpkg.com/zh-Hans/docs/install) 15 | 16 | Deploy for public access may require: 17 | 18 | 1. [Nginx](https://www.nginx.com/resources/wiki/start/topics/tutorials/install/) 19 | 2. [Docker](https://www.docker.com/get-started) or [docker-compose](https://docs.docker.com/compose/install/) 20 | 3. [Redis](https://redis.io/download) 21 | 4. [Heroku](https://devcenter.heroku.com/articles/getting-started-with-nodejs) 22 | 5. [Google App Engine](https://cloud.google.com/appengine/) 23 | 6. [Fly.io](https://fly.io/) 24 | 7. [Zeabur](https://zeabur.com) 25 | 8. [Sealos](https://sealos.io) 26 | 27 | ## Docker Image 28 | 29 | The following two registries are supported: 30 | 31 | - Docker Hub: [`diygod/rsshub`](https://hub.docker.com/r/diygod/rsshub) 32 | 33 | - GitHub: [`ghcr.io/diygod/rsshub`](https://github.com/DIYgod/RSSHub/pkgs/container/rsshub) 34 | 35 | Supported architectures include: 36 | 37 | - `linux/amd64` 38 | 39 | - `linux/arm64` 40 | 41 | ~~- `linux/arm/v7`~~ (Dropped support since `2025-04-22`) 42 | 43 | There are several tags available: 44 | 45 | | Tag | Description | Puppeteer Supported | Example | 46 | | --- | --- | --- | --- | 47 | | `latest` | Latest version | No | `latest` | 48 | | `chromium-bundled` | Latest version with Chromium bundled in | Yes | `chromium-bundled`| 49 | | `{YYYY-MM-DD}` | Specific date of the release | No | `2021-06-18` | 50 | | `chromium-bundled-{YYYY-MM-DD}` | Specific date of the release with Chromium bundled in | Yes | `chromium-bundled-2021-06-18` | 51 | | `{commit hash}` | Specific commit | No | `e7c233b1df982fae10684a11c9df57892e96940a` | 52 | 53 | While supporting puppeteer may consume more resources, it also supports a wider range of routes. 54 | 55 | ## Docker Compose Deployment (Recommended) 56 | 57 | ### Install 58 | 59 | Download [docker-compose.yml](https://github.com/DIYgod/RSSHub/blob/master/docker-compose.yml) 60 | 61 | ```bash 62 | $ wget https://raw.githubusercontent.com/DIYgod/RSSHub/master/docker-compose.yml 63 | ``` 64 | 65 | Check if any configuration needs to be changed 66 | 67 | ```bash 68 | $ vi docker-compose.yml # or your favorite editor 69 | ``` 70 | 71 | Launch 72 | 73 | ```bash 74 | $ docker-compose up -d 75 | ``` 76 | 77 | Open `http://{Server IP}:1200` in your browser, enjoy it! ✅ 78 | 79 | ### Update 80 | 81 | **Automatic Update** 82 | 83 | Use [watchtower](https://github.com/containrrr/watchtower) 84 | 85 | **Manual Update** 86 | 87 | Update image 88 | 89 | ```bash 90 | $ docker-compose pull 91 | ``` 92 | 93 | Restart container 94 | 95 | ```bash 96 | $ docker-compose up -d 97 | ``` 98 | 99 | ### Configuration 100 | 101 | Edit `environment` in [docker-compose.yml](https://github.com/DIYgod/RSSHub/blob/master/docker-compose.yml) 102 | 103 | ## Docker Deployment 104 | 105 | :::warning 106 | 107 | This deployment method does not include browserless and redis dependencies. If needed, please switch to the Docker Compose deployment method or deploy external dependencies yourself. 108 | 109 | ::: 110 | 111 | ### Install 112 | 113 | Execute the following command to pull RSSHub's docker image. 114 | 115 | No puppeteer dependency 116 | 117 | ```bash 118 | $ docker run -d --name rsshub -p 1200:1200 diygod/rsshub 119 | ``` 120 | 121 | With puppeteer dependency 122 | 123 | ```bash 124 | $ docker run -d --name rsshub -p 1200:1200 diygod/rsshub:chromium-bundled 125 | ``` 126 | 127 | Open `http://{Server IP}:1200` in your browser, enjoy it! ✅ 128 | 129 | ### Update 130 | 131 | **Automatic Update** 132 | 133 | Use [watchtower](https://github.com/containrrr/watchtower) 134 | 135 | **Manual Update** 136 | 137 | Remove the old container 138 | 139 | ```bash 140 | $ docker stop rsshub 141 | $ docker rm rsshub 142 | ``` 143 | 144 | Then repeat the installation steps 145 | 146 | ### Configuration 147 | 148 | The simplest way to configure RSSHub container is via system environment variables. 149 | 150 | For example, adding `-e CACHE_EXPIRE=3600` will set the cache time to 1 hour. 151 | 152 | ```bash 153 | $ docker run -d --name rsshub -p 1200:1200 -e CACHE_EXPIRE=3600 -e GITHUB_ACCESS_TOKEN=example diygod/rsshub 154 | ``` 155 | 156 | This deployment method does not include puppeteer (unless using `diygod/rsshub:chromium-bundled` instead) and Redis dependencies. Use the Docker Compose deployment method or deploy external dependencies yourself if you need it. 157 | 158 | To configure more options please refer to [Configuration](#configuration). 159 | 160 | ## Manual Deployment 161 | 162 | The most direct way to deploy `RSSHub`, you can follow the steps below to deploy`RSSHub` on your computer, server or anywhere. 163 | 164 | ### Install 165 | 166 | Execute the following commands to download the source code 167 | 168 | ```bash 169 | $ git clone https://github.com/DIYgod/RSSHub.git 170 | $ cd RSSHub 171 | ``` 172 | 173 | Execute the following commands to install dependencies 174 | 175 | ::: code-group 176 | 177 | ```bash [pnpm] 178 | pnpm i 179 | ``` 180 | 181 | ```bash [yarn] 182 | yarn i 183 | ``` 184 | 185 | ```bash [npm] 186 | npm install 187 | ``` 188 | 189 | ::: 190 | 191 | ### Build 192 | 193 | ::: code-group 194 | 195 | ```bash [pnpm] 196 | pnpm build 197 | ``` 198 | 199 | ```bash [yarn] 200 | yarn build 201 | ``` 202 | 203 | ```bash [npm] 204 | npm run build 205 | ``` 206 | 207 | ::: 208 | 209 | ### Launch 210 | 211 | Under `RSSHub`'s root directory, execute the following commands to launch 212 | 213 | ::: code-group 214 | 215 | ```bash [pnpm] 216 | pnpm start 217 | ``` 218 | 219 | ```bash [yarn] 220 | yarn start 221 | ``` 222 | 223 | ```bash [npm] 224 | npm run start 225 | ``` 226 | 227 | ```bash [pm2] 228 | pm2 start lib/index.ts --name rsshub 229 | ``` 230 | 231 | ::: 232 | 233 | Open `http://{Server IP}:1200` in your browser, enjoy it! ✅ 234 | 235 | ### Configuration 236 | 237 | :::tip 238 | 239 | On arm/arm64, this deployment method does not include puppeteer dependencies. To enable puppeteer, install Chromium from your distribution repositories first, then set `CHROMIUM_EXECUTABLE_PATH` to its executable path. 240 | 241 | Debian: 242 | 243 | ```bash 244 | $ apt install chromium 245 | $ echo >> .env 246 | $ echo 'CHROMIUM_EXECUTABLE_PATH=chromium' >> .env 247 | ``` 248 | 249 | Ubuntu/Raspbian: 250 | 251 | ```bash 252 | $ apt install chromium-browser 253 | $ echo >> .env 254 | $ echo 'CHROMIUM_EXECUTABLE_PATH=chromium-browser' >> .env 255 | ``` 256 | 257 | ::: 258 | 259 | RSSHub can be configured by setting environment variables. 260 | 261 | Create a `.env` file in the root directory of your project. Add environment-specific variables on new lines in the form of `NAME=VALUE`. For example: 262 | 263 | ```shell 264 | CACHE_TYPE=redis 265 | CACHE_EXPIRE=600 266 | ``` 267 | 268 | Please notice that it will not override already existed environment variables, more rules please refer to [dotenv](https://github.com/motdotla/dotenv) 269 | 270 | This deployment method does not include Redis dependencies. Use the Docker Compose deployment method or deploy external dependencies yourself if you need it. 271 | 272 | To configure more options please refer to [Configuration](#configuration). 273 | 274 | ### Update 275 | 276 | Under `RSSHub`'s directory, execute the following commands to pull the latest source code for `RSSHub` 277 | 278 | ```bash 279 | $ git pull 280 | ``` 281 | 282 | Then repeat the installation steps. 283 | 284 | ### A tip for Nix users 285 | 286 | To install nodejs, yarn and jieba (to build documentation) you can use the following `nix-shell` configuration script. 287 | 288 | ```nix 289 | let 290 | pkgs = import {}; 291 | node = pkgs.nodejs-12_x; 292 | in pkgs.stdenv.mkDerivation { 293 | name = "nodejs-yarn-jieba"; 294 | buildInputs = [node pkgs.yarn pkgs.pythonPackages.jieba]; 295 | } 296 | ``` 297 | 298 | ## Kubernetes(Helm) Deployment 299 | 300 | RSSHub can be installed in Kubernetes using the Helm Chart from [RSSHub Helm Chart](https://github.com/NaturalSelectionLabs/helm-charts/tree/main/charts/rsshub) 301 | 302 | Ensure that the following requirements are met: 303 | 304 | - Kubernetes 1.16+ 305 | - Helm version 3.9+ is [installed](https://helm.sh/docs/intro/install/) 306 | 307 | ### Install 308 | 309 | Add NaturalSelection Labs chart repository to Helm: 310 | 311 | ```bash 312 | helm repo add nsl https://naturalselectionlabs.github.io/helm-charts 313 | ``` 314 | 315 | You can update the chart repository by running: 316 | 317 | ```bash 318 | helm repo update 319 | ``` 320 | 321 | And install it with the `helm` command line: 322 | 323 | ```bash 324 | helm install my-release nsl/rsshub 325 | ``` 326 | 327 | ### Update 328 | 329 | To upgrade the my-release RSSHub deployment: 330 | 331 | ```bash 332 | helm upgade my-release nsl/rsshub 333 | ``` 334 | 335 | ### Uninstall 336 | 337 | To uninstall/delete the my-release RSSHub deployment: 338 | 339 | ```bash 340 | helm delete my-release 341 | ``` 342 | 343 | ### Installing with custom values 344 | 345 | ::: code-group 346 | 347 | ```bash [Using Helm CLI] 348 | helm install my-release nsl/rsshub \ 349 | --set="image.tag=2023-12-04" \ 350 | --set="replicaCount=2" 351 | ``` 352 | 353 | ```yaml [With a custom values file] 354 | # File custom-values.yml 355 | ## Install with "helm install my-release nsl/rsshub -f ./custom-values.yml 356 | image: 357 | tag: "2023-12-04" 358 | replicaCount: 2 359 | ``` 360 | 361 | ::: 362 | 363 | ### Install with HA mode 364 | 365 | ::: code-group 366 | 367 | ```yaml [HA mode without autoscaling] 368 | replicaCount: 3 369 | 370 | puppeteer: 371 | replicaCount: 2 372 | ``` 373 | 374 | ```yaml [HA mode with autoscaling] 375 | autoscaling: 376 | enabled: true 377 | minReplicas: 3 378 | 379 | puppeteer: 380 | autoscaling: 381 | enabled: true 382 | minReplicas: 2 383 | ``` 384 | 385 | ::: 386 | 387 | ### Install with external Redis 388 | 389 | ```yaml 390 | redis: 391 | # -- Disable internal redis 392 | enabled: false 393 | env: 394 | # -- other env -- 395 | REDIS_URL: redis://external-redis:6379/ 396 | ``` 397 | 398 | To configure more values please refer to [RSSHub Helm Chart](https://github.com/NaturalSelectionLabs/helm-charts/tree/main/charts/rsshub). 399 | 400 | ## Ansible Deployment 401 | 402 | This Ansible playbook includes RSSHub, Redis, browserless (uses Docker) and Caddy 2 403 | 404 | Currently only support Ubuntu 20.04 405 | 406 | Requires sudo privilege and virtualization capability (Docker will be automatically installed) 407 | 408 | ### Install 409 | 410 | ```bash 411 | sudo apt update 412 | sudo apt install ansible 413 | git clone https://github.com/DIYgod/RSSHub.git ~/RSSHub 414 | cd ~/RSSHub/scripts/ansible 415 | sudo ansible-playbook rsshub.yaml 416 | # When prompt to enter a domain name, enter the domain name that this machine/VM will use 417 | # For example, if your users use https://rsshub.example.com to access your RSSHub instance, enter rsshub.example.com (remove the https://) 418 | ``` 419 | 420 | ### Update 421 | 422 | ```bash 423 | cd ~/RSSHub/scripts/ansible 424 | sudo ansible-playbook rsshub.yaml 425 | # When prompt to enter a domain name, enter the domain name that this machine/VM will use 426 | # For example, if your users use https://rsshub.example.com to access your RSSHub instance, enter rsshub.example.com (remove the https://) 427 | ``` 428 | 429 | ## Deploy to Railway 430 | 431 | Automatic updates are included. 432 | 433 | [![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/template/QxW__f?referralCode=9wT3hc) 434 | 435 | ## Deploy to Heroku 436 | 437 | ### Instant deploy (without automatic update) 438 | 439 | [![Deploy to Heroku](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https%3A%2F%2Fgithub.com%2FDIYgod%2FRSSHub) 440 | 441 | ### Automatic deploy upon update 442 | 443 | 1. [Fork RSSHub](https://github.com/DIYgod/RSSHub/fork) to your GitHub account. 444 | 2. Deploy your fork to Heroku: `https://heroku.com/deploy?template=URL`, where `URL` is your fork address (_e.g._ `https://github.com/USERNAME/RSSHub`). 445 | 3. Configure `automatic deploy` in Heroku app to follow the changes to your fork. 446 | 4. Install [Pull](https://github.com/apps/pull) app to keep your fork synchronized with RSSHub. 447 | 448 | ## Deploy to Zeabur 449 | 450 | 1. [Sign up for Zeabur](https://dash.zeabur.com) 451 | 2. Create a new project. 452 | 3. Create a new service in the project, select deploying from the **marketplace**. 453 | 4. Add a domain name, if you use a custom domain name, you can refer to [Zeabur's domain name binding document](https://docs.zeabur.com/deploy/domain-binding). 454 | 455 | [![Deploy on Zeabur](https://zeabur.com/button.svg)](https://zeabur.com/templates/X46PTP) 456 | 457 | ## Deploy to Vercel 458 | 459 | ### Instant deploy (without automatic update) 460 | 461 | [![Deploy to Vercel](https://vercel.com/button)](https://vercel.com/import/project?template=https://github.com/DIYgod/RSSHub) 462 | 463 | ### Automatic deploy upon update 464 | 465 | 1. [Fork RSSHub](https://github.com/DIYgod/RSSHub/fork) to your GitHub account. 466 | 2. Deploy your fork to Vercel: Login Vercel with your GitHub account, create and deploy [new Vercel project](https://vercel.com/new/) with your RSSHub repository. 467 | 3. Install [Pull](https://github.com/apps/pull) app to keep your fork synchronized with RSSHub. 468 | 469 | ## Deploy to Fly.io 470 | 471 | ### Method 1: Fork 472 | 473 | 1. [Fork RSSHub](https://github.com/DIYgod/RSSHub/fork) to your GitHub account; 474 | 2. Clone the source code from your fork 475 | 476 | ```bash 477 | $ git clone https://github.com//RSSHub.git 478 | $ cd RSSHub 479 | ``` 480 | 481 | 3. [Sign up for Fly.io](https://fly.io/app/sign-up) and install the [flyctl CLI](https://fly.io/docs/hands-on/install-flyctl/); 482 | 4. Run `fly launch` and choose a unique name and region to deploy; 483 | 5. Use `fly secrets set KEY=VALUE` to [configure some modules](config#route-specific-configurations); 484 | 6. [Set up automatic deployment via GitHub Actions](https://fly.io/docs/app-guides/continuous-deployment-with-github-actions/); 485 | 7. (Optional) Use `fly certs add your domain` to configure a custom domain, and follow the instructions to configure the related domain resolution at your DNS service provider (you can check the domain configuration status on the Dashboard Certificate page). 486 | 487 | Upgrade: On the homepage of your Forked repository, click "Sync fork - Update Branch" to manually update to the latest official master branch, or install the [Pull](https://github.com/apps/pull) GitHub app to keep your fork synchronized with upstream. 488 | 489 | ### Method 2: Maintain fly.toml by yourself 490 | 491 | 1. [Sign up for Fly.io](https://fly.io/app/sign-up) and install the [flyctl CLI](https://fly.io/docs/hands-on/install-flyctl/); 492 | 2. Create a new empty directory locally, run `fly launch` in it, and choose a unique name and instance region; 493 | 3. Edit the generated fly.toml file, add 494 | 495 | ```toml 496 | [build] 497 | image = "diygod/rsshub:latest" 498 | ``` 499 | 500 | Depending on the actual situation, you may want to use other image tags, please read the relevant content of [Docker Image](#docker-image); 501 | 4. Modify the `[env]` section in fly.toml or use `fly secrets set KEY=VALUE` to [configure some modules](config#route-specific-configurations); 502 | 5. Execute `fly deploy` to start the application; 503 | 6. (Optional) Use `fly certs add your domain` to configure a custom domain, and follow the instructions to configure the related domain resolution at your DNS service provider (you can check the domain configuration status on the Dashboard Certificate page). 504 | 505 | Upgrade: Enter the directory where you saved the `fly.toml` file and execute `fly deploy` to trigger the steps of pulling the latest image and starting the upgraded application. 506 | 507 | ### Configure built-in Upstash Redis as cache 508 | 509 | Run in the `RSSHub` folder 510 | 511 | ```bash 512 | $ flyctl redis create 513 | ``` 514 | 515 | to create a new Redis database. Choose the same region as when you created the RSSHub app above, and it is recommended to enable [eviction](https://redis.io/docs/reference/eviction/). After creation, a string in the form of `redis://default:@.upstash.io` will be printed. 516 | 517 | Due to [a bug in a dependency](https://github.com/luin/ioredis/issues/1576), you currently need to append the `family=6` parameter to the URL provided by Fly.io, i.e., use `redis://default:@.upstash.io/?family=6` as the connection URL. 518 | 519 | Then configure the `[env]` section in fly.toml or run 520 | 521 | ```bash 522 | $ fly secrets set CACHE_TYPE=redis REDIS_URL='' 523 | ``` 524 | 525 | and execute `fly deploy` (if use the second install method) to trigger a redeployment to complete the configuration. 526 | 527 | ## Deploy to Sealos(use Redis as cache) 528 | 529 | Automatic updates are included. 530 | 531 | [![Deploy to Sealos](https://raw.githubusercontent.com/labring-actions/templates/main/Deploy-on-Sealos.svg)](https://template.cloud.sealos.io/deploy?templateName=rsshub) 532 | 533 | ## Deploy to PikaPods 534 | 535 | Run RSSHub from just $1/month. Includes automatic updates and $5 free starting credit. 536 | 537 | [![Run on PikaPods](https://www.pikapods.com/static/run-button.svg)](https://www.pikapods.com/pods?run=rsshub) 538 | 539 | ## Deploy to Google App Engine(GAE) 540 | 541 | ### Before You Begin 542 | 543 | Follow the [official guide](https://cloud.google.com/appengine/docs/flexible/nodejs/quickstart) for completing your GCP account settings, creating a new Node project, adding billing information (required), installing git and initializing gcloud([link](https://cloud.google.com/sdk/gcloud/)). Node.js is not required if you don't plan to debug RSSHub locally. 544 | 545 | Please note, GAE free tier doesn't support Flexible Environment, please check the pricing plan prior to deployment. 546 | 547 | Node.js standard environment is still under beta, unknown or unexpected errors might be encountered during the deployment. 548 | 549 | Execute `git clone https://github.com/DIYgod/RSSHub.git` to pull the latest code 550 | 551 | ### app.yaml Settings 552 | 553 | #### Deploy to Flexible Environment 554 | 555 | Under RSSHub's root directory, create a file `app.yaml` with the following content: 556 | 557 | ```yaml 558 | # [START app_yaml] 559 | runtime: custom 560 | env: flex 561 | 562 | # This sample incurs costs to run on the App Engine flexible environment. 563 | # The settings below are to reduce costs during testing and are not appropriate 564 | # for production use. For more information, see: 565 | # https://cloud.google.com/appengine/docs/flexible/nodejs/configuring-your-app-with-app-yaml 566 | manual_scaling: 567 | instances: 1 568 | # app engine resources, adjust to suit your needs, the required disk space is 10 GB 569 | resources: 570 | cpu: 1 571 | memory_gb: 0.5 572 | disk_size_gb: 10 573 | network: 574 | forwarded_ports: 575 | - 80:1200 576 | - 443:1200 577 | # environment variables section, refer to Settings 578 | env_variables: 579 | CACHE_EXPIRE: '300' 580 | # [END app_yaml] 581 | ``` 582 | 583 | #### Deploy to standard environment 584 | 585 | Under RSSHub's root directory, create a file `app.yaml` with the following content: 586 | 587 | ```yaml 588 | # [START app_yaml] 589 | runtime: nodejs8 590 | 591 | network: 592 | forwarded_ports: 593 | - 80:1200 594 | - 443:1200 595 | # environment variables section, refer to Settings 596 | env_variables: 597 | CACHE_EXPIRE: '300' 598 | # [END app_yaml] 599 | ``` 600 | 601 | ### Install 602 | 603 | Under RSSHub's root directory, execute the following commands to launch RSSHub 604 | 605 | ```bash 606 | gcloud app deploy 607 | ``` 608 | 609 | For changing the deployment project id or version id, please refer to `Deploying a service` section [here](https://cloud.google.com/appengine/docs/flexible/nodejs/testing-and-deploying-your-app). 610 | 611 | You can access your `Google App Engine URL` to check the deployment status 612 | 613 | ## Play with Docker 614 | 615 | If you would like to test routes or avoid IP limits, etc., you may build your own RSSHub for free by clicking the button below. 616 | 617 | [![Try in PWD](https://raw.githubusercontent.com/play-with-docker/stacks/master/assets/images/button.png)](https://labs.play-with-docker.com/?stack=https://raw.githubusercontent.com/DIYgod/RSSHub/master/docker-compose.yml) 618 | 619 | :::warning 620 | 621 | - [DockerHub](https://hub.docker.com) account required 622 | - [Play with Docker](https://labs.play-with-docker.com/) instance will last for 4 hours at most. It should only be used for testing purpose 623 | - If deploy success but port cannot be auto-deteced,please click the `open port` button on the top and type `1200` 624 | - Sometimes PWD won't work as expected. If you encounter blank screen after `Start`, or some error during initialization, please retry 625 | 626 | ::: 627 | -------------------------------------------------------------------------------- /src/ecosystem.md: -------------------------------------------------------------------------------- 1 | # Ecosystem 2 | 3 | ## Radar 4 | 5 | - [RSSHub Radar](https://github.com/DIYgod/RSSHub-Radar): Browser extension that simplifies finding and subscribing RSS and RSSHub 6 | 7 | - [RSSBud](https://github.com/Cay-Zhang/RSSBud): An RSS feed discovery app for iOS/macOS that works particularly well with RSSHub, a popular feed generation service. 8 | 9 | - [RSSAid](https://github.com/LeetaoGoooo/RSSAid): RSSAid is a complementary app for RSSHub built with Flutter 10 | 11 | - [Easy-to-RSS](https://github.com/idealclover/Easy-to-RSS): Chrome/Firefox Extension to retreive RSS feeds URLs from WebSite, RSSHub supported 12 | 13 | ## Integration 14 | 15 | - [ELF_RSS](https://github.com/Quan666/ELF_RSS): QQ机器人 RSS订阅 插件 16 | 17 | - [rsshub.js](https://github.com/SevenOutman/rsshub.js): JavaScript library for RSSHub 18 | 19 | - [rsshub-zhihu-helper](https://github.com/laike9m/rsshub-zhihu-helper): 如果你希望通过 RSSHub 浏览知乎,那么这个项目或许可以帮到你。 20 | 21 | - [actionsflow-trigger-rsshub](https://github.com/theowenyoung/actionsflow-trigger-rsshub): Actionsflow trigger for rsshub 22 | 23 | - [rsshub2qzone](https://github.com/Ice-Hazymoon/rsshub2qzone): 同步rsshub到QQ空间 24 | 25 | - [gatsby-source-rsshub](https://www.gatsbyjs.com/plugins/gatsby-source-rsshub/): Create a rss xml from rsshub for your Gatsby site. 26 | 27 | ## Deployment 28 | 29 | Please refer to [deployment](/deploy/) for details. 30 | 31 | - [Docker Hub](https://hub.docker.com/r/diygod/rsshub) 32 | 33 | - [GitHub Docker Package](https://github.com/DIYgod/RSSHub/pkgs/container/rsshub) 34 | 35 | - [npm package](https://www.npmjs.com/package/rsshub) 36 | 37 | - [Railway](https://railway.app/template/QxW__f) 38 | 39 | - [Heroku](https://heroku.com/deploy?template=https%3A%2F%2Fgithub.com%2FDIYgod%2FRSSHub) 40 | 41 | - [Sealos](https://template.cloud.sealos.io/deploy?templateName=rsshub) 42 | 43 | - [Vercel](https://vercel.com/import/project?template=https://github.com/DIYgod/RSSHub) 44 | 45 | - [PikaPods](https://www.pikapods.com/pods?run=rsshub) 46 | 47 | - [Zeabur](https://zeabur.com/templates/X46PTP) 48 | 49 | - [TrueCharts](https://truecharts.org/charts/stable/rsshub/): Community Helm Chart Repository 50 | 51 | - [HomelabOS](https://homelabos.com/docs/software/rsshub/): Your very own offline-first privacy-centric open-source data-center! 52 | 53 | - [Artifact Hub](https://artifacthub.io/packages/helm/gabe565/rsshub): Find, install and publish Kubernetes packages 54 | 55 | - [矿神群晖SPK套件源](https://spk7.imnks.com/) 56 | 57 | ## Other implementations 58 | 59 | - [RSSHub-python](https://github.com/hillerliao/RSSHub-python): A RSSHub for Pythonista 60 | 61 | - [RSSHub PHP Ver.](https://github.com/LynMoe/RSSHub): RSSHub for PHPers. 62 | 63 | - [RSSWorker](https://github.com/TheresaQWQ/RSSWorker): 一个能运行在 Cloudflare worker 上面的rss订阅源生成器 64 | -------------------------------------------------------------------------------- /src/guide/api.md: -------------------------------------------------------------------------------- 1 | # API 2 | 3 | :::warning 4 | 5 | The API is under active development and is subject to change. All suggestions are welcome! 6 | 7 | ::: 8 | 9 | RSSHub provides the following APIs: 10 | 11 | [https://rsshub.app/api/reference](https://rsshub.app/api/reference) 12 | -------------------------------------------------------------------------------- /src/guide/faqs.md: -------------------------------------------------------------------------------- 1 | # FAQs 2 | 3 | **Q: How does RSSHub work?** 4 | 5 | **A:** When a request is received, RSSHub fetches the corresponding data from the original site, the resulting contents will be outputted in RSS format. Caching is implemented to avoid requesting original sites for content. And of course, we throw in a little magic 🎩. 6 | 7 | **Q: How does RSSHub Radar work?** 8 | 9 | **A:** When entering a new page, RSSHub Radar first [searches](https://github.com/DIYgod/RSSHub-Radar/blob/2f63cfe6eedec8c9e116dcfde3325089e6cda371/src/lib/rss.ts#L67) for the page's built-in RSS through the page's link tags, then looks for applicable RSSHub routes for the current page and website based on remotely updated [rules](https://github.com/DIYgod/RSSHub-Radar/blob/2f63cfe6eedec8c9e116dcfde3325089e6cda371/src/lib/radar-rules.ts); and adds a little bit of magic. 10 | 11 | **Q: Can I use the demo instance?** 12 | 13 | **A:** [rsshub.app](https://rsshub.app) is the demo instance provided, running the latest build of RSSHub from master branch, the cache is set 120 minutes and it's free to use. However, if you see an badge 🚨 Strict anti-crawling for route, this means popular websites such as Facebook etc. may pose a request quota on individual IP address, which means it can get unreliable from time to time for the demo instance. You are encouraged to [host your own RSSHub instance](/deploy/) to get a better usability. 14 | 15 | **Q: Why are images/videos not loading in some RSSHub routes?** 16 | 17 | **A:** RSSHub fetches and respects the original image/video URLs from original sites, in which some are behind anti-hotlink filters. `referrerpolicy="no-referrer"` attribute is added to all images to solve the issues caused by cross-domain requests. Third party RSS service providers such as Feedly and Inoreader, strip this attribute off, resulting in cross-domain requests being blocked. Meanwhile, the attribute is not available for videos yet, resulting in most RSS readers unable to pass the anti-hotlink check. Here are some workarounds: 18 | 19 | 1. Migrate to RSS readers that do not send Referer,such as [Inoreader for Web](https://www.inoreader.com/) with a [user script disabling Referer](https://greasyfork.org/en/scripts/376884), [fix-image-error at inoreader](https://greasyfork.org/scripts/463461-fix-image-error-at-inoreader), [RSS to Telegram Bot](https://github.com/Rongronggg9/RSS-to-Telegram-Bot), etc. If your RSS reader can bypass the anti-hotlink check successfully and play embedded videos, it's an RSS reader that do not send Referer. Please consider adding it to the documentation to help more people. 20 | 2. Set up a reverse proxy, refer to [Parameters->Multimedia processing](/guide/parameters#multimedia-processing) for more details. 21 | 3. Navigate back to the original site. 22 | 23 | **Q: The website I want is not supported QAQ** 24 | 25 | **A:** If you are a JavaScript developer, please follow [this guide](/joinus/#quick-start) for submitting a pull request, otherwise, follow the issue template to [submit a new issue](https://github.com/DIYgod/RSSHub/issues/new?template=rss_request_en.md), and patiently wait for Santa Claus. For priority responses, consider [sponsoring us](/sponsor). 26 | 27 | **Q: Where do I get the changelog for RSSHub?** 28 | 29 | **A:** Subscribe our RSS here: [RSSHub added a new route](/routes/program-update#rsshub). 30 | -------------------------------------------------------------------------------- /src/guide/index.md: -------------------------------------------------------------------------------- 1 | # Getting Started 2 | 3 | ## Generate a Feed 4 | 5 | For example, if you want to subscribe to the content of the channel [@awesomeRSSHub](https://t.me/awesomeRSSHub) on Telegram. 6 | 7 | According to the [Telegram route](/routes/social-media#telegram) documentation, the route is `/telegram/channel/:username/:routeParams?`, where username is a required parameter and routeParams is an optional parameter. Replace `:username` with the channel id awesomeRSSHub to get the path `/telegram/channel/awesomeRSSHub`, then add the instance domain `https://rsshub.app`, a subscription source is generated: `https://rsshub.app/telegram/channel/awesomeRSSHub`. 8 | 9 | Then you can add `https://rsshub.app/telegram/channel/awesomeRSSHub` to any RSS reader for use. 10 | 11 | The instance domain `https://rsshub.app` can be replaced with your [self-hosted instance](/deploy) or any [public instance](/guide/instances). 12 | 13 | In addition, RSSHub supports many useful parameters, such as content filtering, full-text output, etc., refer to [Parameters](/guide/parameters) for details. 14 | 15 | ## Contribute a New Route 16 | 17 | Our thriving community is the key to RSSHub's success, we invite everyone to join us and [contribute new routes](/joinus/#quick-start) for all kinds of interesting sources. 18 | 19 | ## Use as a npm Package 20 | 21 | Apart from serving as an information source hub, RSSHub is also made compatible with all Node.js projects as an npm Package. 22 | 23 | ### Install 24 | 25 | ::: code-group 26 | 27 | ```sh [npm] 28 | $ npm install rsshub --save 29 | ``` 30 | 31 | ```sh [pnpm] 32 | $ pnpm add rsshub 33 | ``` 34 | 35 | ```sh [yarn] 36 | $ yarn add rsshub 37 | ``` 38 | 39 | ```sh [bun] 40 | $ bun add rsshub 41 | ``` 42 | 43 | ::: 44 | 45 | ### Usage 46 | 47 | ```js 48 | import RSSHub from 'rsshub'; 49 | 50 | RSSHub.init({ 51 | // config 52 | }); 53 | 54 | RSSHub.request('/youtube/user/JFlaMusic') 55 | .then((data) => { 56 | console.log(data); 57 | }) 58 | .catch((e) => { 59 | console.log(e); 60 | }); 61 | ``` 62 | 63 | For supported configs please refer to the [Configuration Section](/deploy/config). 64 | 65 | A short example for disabling caching can be written as: 66 | 67 | ```js 68 | { 69 | CACHE_TYPE: null, 70 | } 71 | ``` 72 | 73 | ## Radar 74 | 75 | RSSHub also provides a Radar function, which is used to map website addresses to RSSHub addresses. 76 | 77 | ### Rules 78 | 79 | You can use the API of the instance to obtain the Radar rules supported by the current instance, such as the rules of official instance https://rsshub.app/api/radar/rules . 80 | 81 | ### Usage 82 | 83 | You need to use supported browser extensions, mobile apps, RSS readers, or other tools to use the Radar feature. Please refer to the documentation of the corresponding tool for specific usage instructions. 84 | 85 | - RSS Reader: [Folo](https://github.com/RSSNext/Folo) 86 | - Browser extension: [RSSHub Radar](https://github.com/DIYgod/RSSHub-Radar) 87 | - iOS app: [RSSBud](https://github.com/Cay-Zhang/RSSBud) 88 | - Android app: [RSSAid](https://github.com/LeetaoGoooo/RSSAid) 89 | -------------------------------------------------------------------------------- /src/guide/instances.md: -------------------------------------------------------------------------------- 1 | # Public Instances 2 | 3 | Although the official instances are already stable enough, in order to achieve decentralization, we encourage users to host their own RSSHub instances or use other public RSSHub instances. 4 | 5 | If you are willing to contribute your own instance for others to use, please edit [this file](https://github.com/RSSNext/rsshub-docs/edit/main/.vitepress/theme/components/InstanceList.vue) and submit a PR to add your instance to the list. 6 | 7 | ## Official 8 | 9 | | URL | Location | Maintainer | Online | 10 | | --- | --- | --- | --- | 11 | | [rsshub.app](https://rsshub.app) | 🇺🇸 | [DIYgod](https://diygod.cc) | ![](https://img.shields.io/website.svg?label=&url=https://rsshub.app/test/cache) | 12 | 13 | ## Folo 14 | 15 | [Folo](https://github.com/RSSNext/Folo) offers numerous user-shared instances that you can switch between and use with just one click. However, these instances are not compatible with external readers. Additionally, you can share your own instances on Folo to earn tokens. 16 | 17 | ![img](https://i.imgur.com/HZKrUSd.png) 18 | 19 | ## Public 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/guide/parameters.md: -------------------------------------------------------------------------------- 1 | # Parameters 2 | 3 | :::tip 4 | 5 | Parameters here are actually URI query and can be linked together with `&` to generate a complex feed. 6 | 7 | Parameters here need to be placed after the route path. Some routes may have **custom route parameters** and **parameters here** need to be placed after them. 8 | 9 | E.g., 10 | https://rsshub.app/twitter/user/durov/**readable=1&includeRts=0**?**brief=100&limit=5** 11 | 12 | 13 | 14 | ::: 15 | 16 | ## Filtering 17 | 18 | :::warning 19 | 20 | Please make sure you've [fully URL-encoded](https://gchq.github.io/CyberChef/#recipe=URL_Encode(true)) the parameters. Do not rely on the browser's automatic URL encoding. Some characters, such as `+`, `&`, will not be automatically encoded, resulting in the final parsing result not being correct. 21 | 22 | ::: 23 | 24 | :::warning 25 | 26 | filter supports Regex, and due to the fact that some Regex are vulnerable to DoS (ReDoS), default engine `re2` blocks some of these functionalities available in node `Regexp`. These two engines also behaves a bit different in some corner cases. [Details](https://github.com/uhop/node-re2#limitations-things-re2-does-not-support) 27 | 28 | If you need to use a different engine, please refer to [Deploy->Features->FILTER_REGEX_ENGINE](/deploy/#configuration-features). 29 | 30 | ::: 31 | 32 | The following URL query parameters are supported, Regex support is built-in. 33 | 34 | Set `filter` to include the content 35 | 36 | - `filter`: filter `title` and description 37 | 38 | - `filter_title`: filter `title` only 39 | 40 | - `filter_description`: filter `description` only 41 | 42 | - `filter_author`: filter `author` only 43 | 44 | - `filter_category`: filter `category` only 45 | 46 | - `filter_time`: filter `pubDate`, in seconds, return specified time range. Item without `pubDate` will not be filtered. 47 | 48 | E.g. [https://rsshub.app/dribbble/popular?filter=Blue|Yellow|Black](https://rsshub.app/dribbble/popular?filter=Blue|Yellow|Black) 49 | 50 | Set `filterout` to exclude unwanted content. 51 | 52 | - `filterout`: filter `title` and description 53 | 54 | - `filterout_title`: filter `title` only 55 | 56 | - `filterout_description`: filter `description` only 57 | 58 | - `filterout_author`: filter `author` only 59 | 60 | - `filterout_category`: filter `category` only 61 | 62 | E.g. [https://rsshub.app/dribbble/popular?filterout=Blue|Yellow|Black](https://rsshub.app/dribbble/popular?filterout=Blue|Yellow|Black) 63 | 64 | Set `filter_case_sensitive` to determine whether the filtering keywords should be case sensitive. The parameter would apply to both `filter` and `filterout`. 65 | 66 | Default: `true` 67 | 68 | E.g. [https://rsshub.app/dribbble/popular?filter=BluE|yeLLow|BlaCK&filter_case_sensitive=false](https://rsshub.app/dribbble/popular?filter=BluE|yeLLow|BlaCK&filter_case_sensitive=false) 69 | 70 | ## Limit Entries 71 | 72 | Set `limit` to limit the number of articles in the feed. 73 | 74 | E.g. Dribbble Popular Top 10 [https://rsshub.app/dribbble/popular?limit=10](https://rsshub.app/dribbble/popular?limit=10) 75 | 76 | ## Sorted 77 | 78 | Set `sorted` to control whether to sort the output by the publish date (`pubDate`). This is useful for some feeds that pin some entries at the top. Default to `true` i.e. the output is sorted. 79 | 80 | E.g. NJU Undergraduate Bulletin Board [https://rsshub.app/nju/jw/ggtz?sorted=false](https://rsshub.app/nju/jw/ggtz?sorted=false) 81 | 82 | ## Fulltext 83 | 84 | Enable fulltext via `mode` parameter. 85 | 86 | E.g. Bilibili article [https://rsshub.app/bilibili/user/article/334958638?mode=fulltext](https://rsshub.app/bilibili/user/article/334958638?mode=fulltext) 87 | 88 | ## Access Control 89 | 90 | Set `key` or `code` to grant access to requests. See [Access Control Configuration](/deploy/config#access-control-configurations). 91 | 92 | ## Telegram Instant View 93 | 94 | Replace website link with Telegram's Instant View link. 95 | 96 | Enable Telegram Instant View requires a page template, it can be obtained from Telegram's [Instant View page](https://instantview.telegram.org/) 97 | 98 | - `tgiv`: template hash, obtained from the link of template page generated(the string after `&rhash=`) 99 | 100 | E.g. [https://rsshub.app/novel/biquge/94_94525?tgiv=bd3c42818a7f7e](https://rsshub.app/novel/biquge/94_94525?tgiv=bd3c42818a7f7e) 101 | 102 | ## Sci-hub link 103 | 104 | Output Sci-hub link in scientific journal routes, this supports major journals or routes that output DOIs. 105 | 106 | - `scihub`: set to any value 107 | 108 | E.g. [https://rsshub.app/pnas/latest?scihub=1](https://rsshub.app/pnas/latest?scihub=1) 109 | 110 | ## Conversion between Traditional and Simplified Chinese 111 | 112 | - `opencc`: `s2t` (Simplified Chinese to Traditional Chinese)、`t2s` (Traditional Chinese to Simplified Chinese), other optional values refer to [simplecc-wasm - Configurations](https://github.com/fengkx/simplecc-wasm#%E9%85%8D%E7%BD%AE-configurations) 113 | 114 | E.g. [https://rsshub.app/theinitium/channel/latest/zh-hans?opencc=t2s](https://rsshub.app/theinitium/channel/latest/zh-hans?opencc=t2s) 115 | 116 | ## Multimedia processing 117 | 118 | :::warning 119 | 120 | This is an experimental API 121 | 122 | `image_hotlink_template` and `multimedia_hotlink_template` allow users to supply templates to replace media URLs. Certain routes plus certain RSS readers may result in users needing these features, but it's not very common. Vulnerable characters will be escaped automatically, making XSS attack impossible. The scope of URL replacement is limited to media elements, making any script URL unable to load and unable to cause XSS. As a result, users can only take the control of "where are the media from". These features are commonly side-effect-free. To enable these two parameters, please set `ALLOW_USER_HOTLINK_TEMPLATE` to `true` 123 | 124 | ::: 125 | 126 | - `image_hotlink_template`: replace image URL in the description to avoid anti-hotlink protection, leave it blank to disable this function. Usage reference [#2769](https://github.com/DIYgod/RSSHub/issues/2769). You may use any property listed in [URL](https://developer.mozilla.org/en-US/docs/Web/API/URL#Properties) (suffixing with `_ue` results in URL encoding), format of JS template literal. e.g. `${protocol}//${host}${pathname}`, `https://i3.wp.com/${host}${pathname}`, `https://images.weserv.nl?url=${href_ue}` 127 | - `multimedia_hotlink_template`: the same as `image_hotlink_template` but apply to audio and video. Note: the service must follow redirects, allow reverse-proxy for audio and video, and must drop the `Referer` header when reverse-proxying. [Here is an easy-to-deploy project that fits these requirements](https://github.com/Rongronggg9/rsstt-img-relay). The project accepts simple URL concatenation, e.g. `https://example.com/${href}`, in which `example.com` should be replaced with the domain name of the service you've deployed 128 | - `wrap_multimedia_in_iframe`: wrap audio and video in `