diff --git a/lib/routes/steam/curator.ts b/lib/routes/steam/curator.ts
new file mode 100644
index 00000000000000..a99329bc54edd2
--- /dev/null
+++ b/lib/routes/steam/curator.ts
@@ -0,0 +1,93 @@
+import { Route } from '@/types';
+import ofetch from '@/utils/ofetch';
+import { load } from 'cheerio';
+import { parseDate } from '@/utils/parse-date';
+import { getCurrentPath } from '@/utils/helpers';
+import path from 'node:path';
+import { art } from '@/utils/render';
+
+const __dirname = getCurrentPath(import.meta.url);
+
+export const route: Route = {
+ path: '/curator/:id/:routeParams?',
+ categories: ['game'],
+ example: '/steam/curator/34646096-80-Days',
+ parameters: {
+ id: "Steam curator id. It usually consists of a series of numbers and the curator's name.",
+ routeParams: {
+ description: `Extra parameters to filter the reviews. The following parameters are supported:
+| Key | Description | Accepts | Defaults to |
+| --------------- | --------------------------------------------------------------------------------------------- | ------------------------------------------ | ----------- |
+| \`curations\` | Review type to filter by. \`0\`: Recommended, \`1\`: Not Recommended, \`2\`: Informational | \`0\`/\`1\`/\`2\`/\`0,1\`/\`0,2\`/\`1,2\` | |
+| \`tagids\` | Tag to filter by. Details are provided below. | use comma to separate multiple tagid | |
+
+Note: There is a [‘Popular Tags’](https://store.steampowered.com/tag/browse) page where you can find many but not all of the tags. The tag’s ID is in the \`data-tagid\` attribute of the element.Steam does not currently provide a page that comprehensively lists all tags, and you may need to explore alternative ways to find them.
+
+Examples:
+* \`/steam/curator/34646096-80-Days/curations=&tagids=\`
+* \`/steam/curator/34646096-80-Days/curations=0&tagids=19\`
+* \`/steam/curator/34646096-80-Days/curations=0,2&tagids=19,21\`
+`,
+ },
+ },
+ radar: [
+ {
+ title: 'Latest Curator Reviews',
+ source: ['store.steampowered.com/curator/:id'],
+ target: '/curator/:id',
+ },
+ ],
+ description: 'The Latest reviews from a Steam Curator.',
+ name: 'Latest Curator Reviews',
+ maintainers: ['naremloa', 'fenxer'],
+ handler: async (ctx) => {
+ const { id, routeParams } = ctx.req.param();
+ const params = new URLSearchParams(routeParams);
+
+ const url = new URL(`https://store.steampowered.com/curator/${id}/ajaxgetfilteredrecommendations/?query&start=0&count=10&dynamic_data=&sort=recent&app_types=&reset=false&curations=&tagids=`);
+ for (const [key, value] of params) {
+ if (['curations', 'tagids'].includes(key)) {
+ url.searchParams.set(key, value || '');
+ }
+ }
+
+ const response = await ofetch(url.toString());
+ const $ = load(response.results_html ?? '');
+
+ const items = $('.recommendation')
+ .toArray()
+ .map((item) => {
+ const el = $(item);
+ const appImageEl = el.find('a.store_capsule img');
+ const appTitle = appImageEl.attr('alt')!;
+ const appImage = appImageEl.attr('src') ?? '';
+ const appLink = el.find('.recommendation_link').first().attr('href');
+ const reviewContent = el.find('.recommendation_desc').text().trim();
+ const reviewDateText = el.find('.curator_review_date').text().trim();
+
+ const notCurrentYearPattern = /,\s\b\d{4}\b$/;
+ const reviewPubDate = notCurrentYearPattern.test(reviewDateText) ? parseDate(reviewDateText) : parseDate(`${reviewDateText}, ${new Date().getFullYear()}`);
+
+ const description = art(path.join(__dirname, 'templates/curator-description.art'), { image: appImage, description: reviewContent });
+
+ return {
+ title: appTitle,
+ link: appLink,
+ description,
+ pubDate: reviewPubDate,
+ media: {
+ content: {
+ url: appImage,
+ medium: 'image',
+ },
+ },
+ };
+ });
+
+ return {
+ title: `Steam Curator ${id} Reviews`,
+ link: url.toString(),
+ item: items,
+ };
+ },
+};
diff --git a/lib/routes/steam/templates/curator-description.art b/lib/routes/steam/templates/curator-description.art
new file mode 100644
index 00000000000000..e77f842b8e8fb6
--- /dev/null
+++ b/lib/routes/steam/templates/curator-description.art
@@ -0,0 +1,4 @@
+{{ if image }}
+
+{{ /if }}
+
{{ description }}