From e86c679a9263e40765cf6894047329e5849158a2 Mon Sep 17 00:00:00 2001 From: Solitudinis Date: Fri, 20 Mar 2026 23:15:55 +0800 Subject: [PATCH] feat(route/cursor): support localized blog and changelog routes (#21390) --- lib/routes/cursor/blog.ts | 31 +++++++++++++++++++++---------- lib/routes/cursor/changelog.ts | 20 ++++++++++++-------- 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/lib/routes/cursor/blog.ts b/lib/routes/cursor/blog.ts index 6e93a30e8..11e7014b2 100644 --- a/lib/routes/cursor/blog.ts +++ b/lib/routes/cursor/blog.ts @@ -7,18 +7,16 @@ import ofetch from '@/utils/ofetch'; import { parseDate } from '@/utils/parse-date'; export const handler = async (ctx: Context): Promise => { - const { topic } = ctx.req.param(); + const { topic, locale } = ctx.req.param(); const limit: number = Number.parseInt(ctx.req.query('limit') ?? '10', 10); const baseUrl = 'https://cursor.com'; - const path = topic ? `/blog/topic/${topic}` : '/blog'; + const normalizedTopic = topic === 'all' ? undefined : topic; + const localeSegment = locale ? `/${locale}` : ''; + const path = normalizedTopic ? `${localeSegment}/blog/topic/${normalizedTopic}` : `${localeSegment}/blog`; const targetUrl = new URL(path, baseUrl).href; - const html = await ofetch(targetUrl, { - headers: { - cookie: 'NEXT_LOCALE=en', - }, - }); + const html = await ofetch(targetUrl); const $ = load(html); const main = $('#main').last(); // there are two main tags before hydration @@ -56,13 +54,14 @@ export const handler = async (ctx: Context): Promise => { }; export const route: Route = { - path: '/blog/:topic?', + path: '/blog/:topic?/:locale?', name: 'Blog', url: 'cursor.com', maintainers: ['johan456789'], example: '/cursor/blog', parameters: { - topic: 'Optional topic: product | research | company | news', + locale: 'Locale appended to the route path, e.g. `ja`', + topic: 'Topic: all | product | research | company | news', }, description: undefined, categories: ['blog'], @@ -77,9 +76,21 @@ export const route: Route = { }, radar: [ { - source: ['cursor.com/blog', 'cursor.com/blog/topic/:topic'], + source: ['cursor.com/blog'], + target: '/blog', + }, + { + source: ['cursor.com/blog/topic/:topic'], target: '/blog/:topic', }, + { + source: ['cursor.com/:locale/blog'], + target: '/blog/all/:locale', + }, + { + source: ['cursor.com/:locale/blog/topic/:topic'], + target: '/blog/:topic/:locale', + }, ], view: ViewType.Articles, handler, diff --git a/lib/routes/cursor/changelog.ts b/lib/routes/cursor/changelog.ts index cacbc9f09..fc7aadbbd 100644 --- a/lib/routes/cursor/changelog.ts +++ b/lib/routes/cursor/changelog.ts @@ -9,16 +9,14 @@ import ofetch from '@/utils/ofetch'; import { parseDate } from '@/utils/parse-date'; export const handler = async (ctx: Context): Promise => { + const locale = ctx.req.param('locale'); const limit: number = Number.parseInt(ctx.req.query('limit') ?? '100', 10); const baseUrl = 'https://cursor.com'; - const targetUrl: string = new URL('changelog', baseUrl).href; + const localeSegment = locale ? `/${locale}` : ''; + const targetUrl: string = new URL(`${localeSegment}/changelog`, baseUrl).href; - const response = await ofetch(targetUrl, { - headers: { - cookie: 'NEXT_LOCALE=en', - }, - }); + const response = await ofetch(targetUrl); const $: CheerioAPI = load(response); const language = ($('html').attr('lang') ?? 'en') as Language; @@ -75,13 +73,15 @@ export const handler = async (ctx: Context): Promise => { }; export const route: Route = { - path: '/changelog', + path: '/changelog/:locale?', name: 'Changelog', url: 'cursor.com', maintainers: ['p3psi-boo', 'nczitzk'], handler, example: '/cursor/changelog', - parameters: undefined, + parameters: { + locale: 'Locale appended to the route path, e.g. `ja`', + }, description: undefined, categories: ['program-update'], features: { @@ -98,6 +98,10 @@ export const route: Route = { source: ['cursor.com/changelog'], target: '/changelog', }, + { + source: ['cursor.com/:locale/changelog'], + target: '/changelog/:locale', + }, ], view: ViewType.Articles, };