diff --git a/docs/blog.md b/docs/blog.md
index c53efe012a..6231c82aea 100644
--- a/docs/blog.md
+++ b/docs/blog.md
@@ -30,6 +30,19 @@ pageClass: routes
+## hashnode
+
+### 用户博客
+
+
+
+::: tip 提示
+
+username 为博主用户名,而非`xxx.hashnode.dev`中`xxx`所代表的 blog 地址。
+
+:::
+
+
## Hedwig.pub
### 博客
diff --git a/lib/v2/hashnode/blog.js b/lib/v2/hashnode/blog.js
new file mode 100644
index 0000000000..075bd1807d
--- /dev/null
+++ b/lib/v2/hashnode/blog.js
@@ -0,0 +1,62 @@
+const got = require('@/utils/got');
+const { art } = require('@/utils/render');
+const path = require('path');
+const { parseDate } = require('@/utils/parse-date');
+
+const baseApiUrl = 'https://api.hashnode.com';
+
+module.exports = async (ctx) => {
+ const username = ctx.params.username;
+ if (!username) {
+ return;
+ }
+
+ const query = `
+ {
+ user(username: "${username}") {
+ publication {
+ posts{
+ slug
+ title
+ brief
+ coverImage
+ dateAdded
+ }
+ }
+ }
+ }
+ `;
+
+ const userUrl = `https://${username}.hashnode.dev`;
+ const response = await got({
+ method: 'POST',
+ url: baseApiUrl,
+ headers: {
+ Referer: userUrl,
+ 'Content-type': 'application/json',
+ },
+ body: JSON.stringify({ query }),
+ });
+
+ const publication = response.data.data.user.publication;
+ if (!publication) {
+ return;
+ }
+
+ const list = publication.posts;
+ ctx.state.data = {
+ title: `Hashnode by ${username}`,
+ link: userUrl,
+ item: list
+ .map((item) => ({
+ title: item.title,
+ description: art(path.join(__dirname, 'templates/description.art'), {
+ image: item.coverImage,
+ brief: item.brief,
+ }),
+ pubDate: parseDate(item.dateAdded),
+ link: `${userUrl}/${item.slug}`,
+ }))
+ .filter((item) => item !== ''),
+ };
+};
diff --git a/lib/v2/hashnode/maintainer.js b/lib/v2/hashnode/maintainer.js
new file mode 100644
index 0000000000..bbcf4d5ad7
--- /dev/null
+++ b/lib/v2/hashnode/maintainer.js
@@ -0,0 +1,3 @@
+module.exports = {
+ '/blog/:username': ['hnrainll'],
+};
diff --git a/lib/v2/hashnode/radar.js b/lib/v2/hashnode/radar.js
new file mode 100644
index 0000000000..da656908fe
--- /dev/null
+++ b/lib/v2/hashnode/radar.js
@@ -0,0 +1,13 @@
+module.exports = {
+ 'hashnode.dev': {
+ _name: 'hashnode',
+ '.': [
+ {
+ title: 'Hashnode Blog',
+ docs: 'https://docs.rsshub.app/blog.html#hashnode',
+ source: '/',
+ target: '/hashnode/blog/:username',
+ },
+ ],
+ },
+};
diff --git a/lib/v2/hashnode/router.js b/lib/v2/hashnode/router.js
new file mode 100644
index 0000000000..5166bcb89a
--- /dev/null
+++ b/lib/v2/hashnode/router.js
@@ -0,0 +1,3 @@
+module.exports = (router) => {
+ router.get('/blog/:username', require('./blog'));
+};
diff --git a/lib/v2/hashnode/templates/description.art b/lib/v2/hashnode/templates/description.art
new file mode 100644
index 0000000000..ad6ebf4679
--- /dev/null
+++ b/lib/v2/hashnode/templates/description.art
@@ -0,0 +1,2 @@
+
+{{@ brief }}