Skip to content

Commit 4363ad0

Browse files
jhislop-designclaudeautofix-ci[bot]
authored
feat(partners): add dedicated Railway Gold partner landing page (#925)
* feat(partners): add dedicated Railway Gold partner landing page Replaces the generic `partners.$partner` template for Railway with a purpose-built landing route at `/partners/railway`, in line with the Gold-tier sponsorship agreement. The page is built almost entirely from existing tanstack.com primitives to stay visually and behaviorally consistent with the rest of the site: - `CodeBlock` (Shiki) for the config and terminal snippets (replaces a hand-rolled `<pre>` which inherited the global `text-black` rule and rendered invisible on dark backgrounds) - `Card` for feature, step, library-fit, pricing and testimonial panels - `Button` (`as="a"`) for every CTA, with brand-tinted overrides on the hero and dark CTA section - `Collapsible` / `CollapsibleTrigger` / `CollapsibleContent` for the FAQ accordion, controlled by a parent `openFaq` state so only one answer expands at a time - `seo()` for title/description/OG/Twitter Card meta - Existing `PartnerImage` and `railway-{black,white}.svg` brand marks for the hero SEO additions: - Page-specific title + description targeting "deploy tanstack to railway" and related queries - Two `application/ld+json` blocks in SSR: the existing partner `WebPage` schema plus a new `FAQPage` schema generated from the on-page FAQ for Google rich results + AI search agents Analytics: - Fires `partner_viewed` on mount with `placement: 'detail'` - Fires `partner_clicked` with `destination_host: 'railway.com'` on every outbound Railway CTA, matching the existing taxonomy in `analytics/events.ts` All outbound Railway links carry `utm_medium=sponsor&utm_source=tanstack&utm_campaign=partner-page`. The static `/partners/railway` route takes file-routing precedence over the parametric `/partners/$partner` template, so the legacy template is preserved untouched for every other partner. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ci: apply automated fixes * feat(partners/railway): polish copy + add mid-page CTAs Voice + conversion pass before shipping. The hero, feature cards, and section headings now match TanStack's restrained, pragmatic tone instead of echoing Railway's own marketing site. Copy changes: - Hero paragraph rewritten using the same framing as `partnerGuidance.railway` in `partner-pages.ts` (drop "all-in-one intelligent cloud platform trusted by 2M+ developers" — that's Railway's tagline, not TanStack's voice) - Feature card descriptions tightened to be outcome-focused ("No YAML to maintain.", "Test routing, data, and server logic before merging.") - Replace emoji feature icons with Lucide icons (Rocket, GitPullRequest, LineChart, Network, Undo2, ShieldCheck, Globe, Infinity) to match the site's icon language - Testimonial section heading "Teams are saving big on infrastructure" → "What teams say after switching" + a neutral framing line CTAs: The page previously had only the hero CTA + final CTA section, leaving ~6 content sections between them with no out-link. Added three mid-page CTA blocks and varied the labels so no two CTAs read the same: - Hero primary: "Deploy free in 2 minutes" (+ "No credit card · $5 in trial credits on signup" microcopy) - After how-it-works code blocks: "Try the Railway preset" + "Read the deployment guide" - After pricing tiers: "Start with $5 in credits" + "Estimate your costs" (new link to railway.com/pricing) - After testimonials: "Move your app to Railway" + per-second-billing microcopy - Final CTA: "Deploy your TanStack app" + "Open the docs" Outbound railway.com links: 4 → 9, all distinct labels, all carrying the partner-page UTM. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ci: apply automated fixes * fix(partners/railway): use the canonical @tanstack/cli scaffolder Step 01 was `npx create-tsrouter-app my-app`, which is the older router-only scaffolder. The TanStack Start docs recommend the unified CLI for new apps, so match the official getting-started instructions. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent b8b4cf2 commit 4363ad0

2 files changed

Lines changed: 833 additions & 0 deletions

File tree

src/routeTree.gen.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ import { Route as ShowcaseSubmitRouteImport } from './routes/showcase/submit'
5454
import { Route as ShowcaseIdRouteImport } from './routes/showcase/$id'
5555
import { Route as ShopSearchRouteImport } from './routes/shop.search'
5656
import { Route as ShopCartRouteImport } from './routes/shop.cart'
57+
import { Route as PartnersRailwayRouteImport } from './routes/partners.railway'
5758
import { Route as PartnersPartnerRouteImport } from './routes/partners.$partner'
5859
import { Route as OauthTokenRouteImport } from './routes/oauth/token'
5960
import { Route as OauthRegisterRouteImport } from './routes/oauth/register'
@@ -380,6 +381,11 @@ const ShopCartRoute = ShopCartRouteImport.update({
380381
path: '/cart',
381382
getParentRoute: () => ShopRoute,
382383
} as any)
384+
const PartnersRailwayRoute = PartnersRailwayRouteImport.update({
385+
id: '/railway',
386+
path: '/railway',
387+
getParentRoute: () => PartnersRoute,
388+
} as any)
383389
const PartnersPartnerRoute = PartnersPartnerRouteImport.update({
384390
id: '/$partner',
385391
path: '/$partner',
@@ -961,6 +967,7 @@ export interface FileRoutesByFullPath {
961967
'/oauth/register': typeof OauthRegisterRoute
962968
'/oauth/token': typeof OauthTokenRoute
963969
'/partners/$partner': typeof PartnersPartnerRoute
970+
'/partners/railway': typeof PartnersRailwayRoute
964971
'/shop/cart': typeof ShopCartRoute
965972
'/shop/search': typeof ShopSearchRoute
966973
'/showcase/$id': typeof ShowcaseIdRoute
@@ -1100,6 +1107,7 @@ export interface FileRoutesByTo {
11001107
'/oauth/register': typeof OauthRegisterRoute
11011108
'/oauth/token': typeof OauthTokenRoute
11021109
'/partners/$partner': typeof PartnersPartnerRoute
1110+
'/partners/railway': typeof PartnersRailwayRoute
11031111
'/shop/cart': typeof ShopCartRoute
11041112
'/shop/search': typeof ShopSearchRoute
11051113
'/showcase/$id': typeof ShowcaseIdRoute
@@ -1246,6 +1254,7 @@ export interface FileRoutesById {
12461254
'/oauth/register': typeof OauthRegisterRoute
12471255
'/oauth/token': typeof OauthTokenRoute
12481256
'/partners/$partner': typeof PartnersPartnerRoute
1257+
'/partners/railway': typeof PartnersRailwayRoute
12491258
'/shop/cart': typeof ShopCartRoute
12501259
'/shop/search': typeof ShopSearchRoute
12511260
'/showcase/$id': typeof ShowcaseIdRoute
@@ -1395,6 +1404,7 @@ export interface FileRouteTypes {
13951404
| '/oauth/register'
13961405
| '/oauth/token'
13971406
| '/partners/$partner'
1407+
| '/partners/railway'
13981408
| '/shop/cart'
13991409
| '/shop/search'
14001410
| '/showcase/$id'
@@ -1534,6 +1544,7 @@ export interface FileRouteTypes {
15341544
| '/oauth/register'
15351545
| '/oauth/token'
15361546
| '/partners/$partner'
1547+
| '/partners/railway'
15371548
| '/shop/cart'
15381549
| '/shop/search'
15391550
| '/showcase/$id'
@@ -1679,6 +1690,7 @@ export interface FileRouteTypes {
16791690
| '/oauth/register'
16801691
| '/oauth/token'
16811692
| '/partners/$partner'
1693+
| '/partners/railway'
16821694
| '/shop/cart'
16831695
| '/shop/search'
16841696
| '/showcase/$id'
@@ -2183,6 +2195,13 @@ declare module '@tanstack/react-router' {
21832195
preLoaderRoute: typeof ShopCartRouteImport
21842196
parentRoute: typeof ShopRoute
21852197
}
2198+
'/partners/railway': {
2199+
id: '/partners/railway'
2200+
path: '/railway'
2201+
fullPath: '/partners/railway'
2202+
preLoaderRoute: typeof PartnersRailwayRouteImport
2203+
parentRoute: typeof PartnersRoute
2204+
}
21862205
'/partners/$partner': {
21872206
id: '/partners/$partner'
21882207
path: '/$partner'
@@ -3051,11 +3070,13 @@ const BuilderRouteWithChildren =
30513070

30523071
interface PartnersRouteChildren {
30533072
PartnersPartnerRoute: typeof PartnersPartnerRoute
3073+
PartnersRailwayRoute: typeof PartnersRailwayRoute
30543074
PartnersIndexRoute: typeof PartnersIndexRoute
30553075
}
30563076

30573077
const PartnersRouteChildren: PartnersRouteChildren = {
30583078
PartnersPartnerRoute: PartnersPartnerRoute,
3079+
PartnersRailwayRoute: PartnersRailwayRoute,
30593080
PartnersIndexRoute: PartnersIndexRoute,
30603081
}
30613082

0 commit comments

Comments
 (0)