Skip to content

Commit e1e9f76

Browse files
committed
Update React pages
1 parent 3432e26 commit e1e9f76

File tree

7 files changed

+673
-140
lines changed

7 files changed

+673
-140
lines changed

MyApp/Pages/React/Index.cshtml

Lines changed: 410 additions & 125 deletions
Large diffs are not rendered by default.

MyApp/_pages/react/overview.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,15 @@ These components are ideal for rapidly building backend management interfaces, f
6464

6565
## Modern React Project Templates
6666

67-
We're introducing three production-ready React templates, each optimized for different use cases:
67+
We're introducing production-ready React templates, each optimized for different use cases:
6868

69+
<react-template
70+
name="next-rsc"
71+
description="The cutting edge of React. Leverage the full uncompromising power of Next.js React Server Components to access .NET APIs directly on the server, reducing bundle size and improving performance."></react-template>
72+
73+
<react-template
74+
name="next-static"
75+
description="The ultimate solution for public-facing websites. Combines the SEO and performance of Static Site Generation (SSG) with a dynamic .NET API. Ideal for marketing sites, landing pages, blogs, and content-focused sites that benefit from SEO."></react-template>
6976

7077
<react-template
7178
name="react-static"

MyApp/_pages/templates/react.md

Lines changed: 65 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,23 +63,77 @@ Less code means fewer opportunities for errors. ServiceStack's high-productivity
6363

6464
These components are ideal for rapidly building backend management interfaces, freeing developers to focus on differentiating customer-facing features.
6565

66+
### Seamless fusion of .NET APIs, Razor Pages and React UIs
6667

67-
## Modern React Project Templates
68+
Another benefit of this architecture of the .NET App handling all Requests and only proxying unknown requests to the Node server is that it enables a seamless fusion of .NET Razor Pages and React UIs. As many customers have customized Identity Auth flows we've included the
69+
[Tailwind Identity Auth Razor Pages](https://github.com/NetCoreTemplates/react-static/tree/main/MyApp/Areas/Identity/Pages) from the [razor](https://github.com/NetCoreTemplates/razor) template into all new .NET React Templates.
6870

69-
We're introducing three production-ready React templates, each optimized for different use cases:
71+
This ability to seamlessly integrate React components within Razor Pages enables a gradual migration strategy, allowing teams to incrementally modernize legacy ASP.NET websites by progressively replacing individual pages or sections with React UIs without requiring a complete rewrite or disrupting existing functionality.
7072

73+
### .NET React Templates with Static Exports
7174

72-
<react-template
73-
name="react-static"
74-
description="A lightweight foundation built with React + Vite + TypeScript + Tailwind CSS—the ideal blank slate starting point for AI-generated UIs."></react-template>
75+
All existing SPA Templates have only used **static exports**, where at deployment a production build of the Node App is generated and published together with the .NET App in its `/wwwroot` folder, utilizing static file serving to render its UI:
7576

76-
<react-template
77-
name="react-spa"
78-
description="A comprehensive single-page application with deep ServiceStack integration and ASP.NET Core Identity Auth, perfect for full-featured web applications."></react-template>
77+
![](https://docs.servicestack.net/img/pages/react/info/react-static-prod.svg)
7978

80-
<react-template
81-
name="nextjs"
82-
description="A Next.js template with TypeScript and Tailwind CSS, offering server-side rendering and optimized performance with complete ServiceStack integration."></react-template>
79+
This continues to be the case for **4/5 of the .NET React Templates**, starting with 2x new `react-static` and `next-static` minimal starting templates - perfect base for your next Vibe Coding project, starting with the simplest template:
80+
81+
## Vibe Codable .NET React Templates
82+
83+
<vibe-template
84+
template="react-static"
85+
title="React Static"
86+
description="Minimal foundation for a classic Single Page Application (SPA) statically generated by Vite. Perfect for dashboards, internal tools, admin panels, and highly interactive apps where SEO isn't a priority."
87+
href="https://react-templates.net/docs/templates/react-static"
88+
screenshot="https://github.com/ServiceStack/docs.servicestack.net/blob/main/MyApp/wwwroot/img/pages/react/react-static.webp?raw=true"
89+
github-template="https://github.com/new?template_name=react-static&template_owner=NetCoreTemplates"></vibe-template>
90+
91+
When your App needs the features from a full-featured Web Framework like Next.js with file-based routing and SEO you choose from the Next.js templates starting with:
92+
93+
<vibe-template
94+
template="next-static"
95+
title="Next.js Static"
96+
description="The ultimate solution for public-facing websites. Combines the SEO and performance of Static Site Generation (SSG) with a dynamic .NET API. Ideal for marketing sites, landing pages, blogs, and content-focused sites that benefit from SEO."
97+
href="https://react-templates.net/docs/templates/next-static"
98+
screenshot="https://github.com/ServiceStack/docs.servicestack.net/blob/main/MyApp/wwwroot/img/pages/react/next-static.webp?raw=true"
99+
github-template="https://github.com/new?template_name=next-static&template_owner=NetCoreTemplates"></vibe-template>
100+
101+
Like React Static, Next.js Static is a static export of a Next.js App, but what about when you need the full power of Next.js? For that you can use:
102+
103+
<vibe-template
104+
template="next-rsc"
105+
title="Next.js RSC"
106+
description="The cutting edge of React. Leverage the full uncompromising power of Next.js React Server Components to access .NET APIs directly on the server, reducing bundle size and improving performance."
107+
href="https://react-templates.net/docs/templates/next-rsc"
108+
screenshot="/img/pages/react/next-rsc.webp"
109+
github-template="https://github.com/new?template_name=next-rsc&template_owner=NetCoreTemplates"></vibe-template>
110+
111+
112+
### Next.js in Production
113+
114+
Using full Next.js does mean we also need to have a Next.js runtime at production, which looks like:
115+
116+
![](https://docs.servicestack.net/img/pages/react/info/next-rsc-prod.svg)
117+
118+
Fortunately Docker simplifies managing both .NET and Node servers as a single deployable unit, with the next-rsc custom [Dockerfile](https://github.com/NetCoreTemplates/next-rsc/blob/main/Dockerfile) handling the orchestration.
119+
120+
### Full-Featured React Templates
121+
122+
In addition to the minimal starting templates above, we've also created 2 full-featured React Templates providing a good reference implementation for integrating several React features including Blog, MDX, Todos and shadcn/ui components alongside .NET features like API Keys, AI Chat & Swagger UI.
123+
124+
<vibe-template
125+
template="react-spa"
126+
title="React SPA"
127+
description="A feature-rich React Single Page Application powered by Vite. Includes Blog functionality, Todos, shadcn/ui components, API Keys management, AI Chat capabilities, and Swagger UI - all integrated with a robust .NET backend."
128+
href="https://react-templates.net/docs/templates/react-spa"
129+
screenshot="https://github.com/ServiceStack/docs.servicestack.net/blob/main/MyApp/wwwroot/img/pages/react/react-spa.webp?raw=true"></vibe-template>
130+
131+
<vibe-template
132+
template="nextjs"
133+
title="Next.js"
134+
description="A comprehensive Next.js template showcasing the full power of integrating React with .NET. Features a complete Blog with MDX, Todos implementation, shadcn/ui components, API Keys management, AI Chat integration, and Swagger UI for API exploration."
135+
href="/docs/templates/nextjs"
136+
screenshot="https://github.com/ServiceStack/docs.servicestack.net/blob/main/MyApp/wwwroot/img/pages/react/nextjs.webp?raw=true"></vibe-template>
83137

84138

85139
## Comprehensive React Component Library
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
export default {
2+
template:`
3+
<section class="not-prose py-20">
4+
<div class="w-full">
5+
<div class="relative overflow-hidden rounded-2xl bg-gradient-to-br from-slate-900 via-blue-950 to-cyan-900 shadow-xl ring-1 ring-white/10">
6+
7+
<!-- React Logo Watermark -->
8+
<svg class="absolute -right-20 -top-20 h-[400px] w-[400px] text-cyan-500/10 animate-[spin_60s_linear_infinite]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1">
9+
<circle cx="12" cy="12" r="2"></circle>
10+
<ellipse rx="10" ry="4.5" transform="rotate(60 12 12)"></ellipse>
11+
<ellipse rx="10" ry="4.5" transform="rotate(120 12 12)"></ellipse>
12+
<ellipse rx="10" ry="4.5"></ellipse>
13+
</svg>
14+
15+
<div class="relative px-6 py-10 sm:px-10 lg:px-12">
16+
<h2 class="text-2xl sm:text-3xl font-bold tracking-tight text-white">
17+
AI-Ready React templates <span class="text-cyan-400">on a robust .NET backend</span>
18+
</h2>
19+
<p class="mt-4 max-w-2xl text-blue-100/80 text-sm sm:text-base">
20+
Combine the React ecosystem with ServiceStack's feature-rich backend.
21+
Experience end-to-end type safety and declarative APIs in a frictionless environment.
22+
</p>
23+
24+
<dl class="mt-8 grid gap-6 sm:grid-cols-3">
25+
<!-- Item 1 -->
26+
<div class="flex flex-col bg-white/5 p-5 rounded-xl border border-white/5 backdrop-blur-sm hover:bg-white/10 transition-colors">
27+
<dt class="font-semibold text-white">
28+
<span class="block text-cyan-400 font-mono text-xs mb-1 opacity-70">01</span>
29+
AI Ready
30+
</dt>
31+
<dd class="mt-2 text-sm text-blue-100/70 leading-relaxed">
32+
Start from well-known React templates tuned for rich, data-driven and AI-assisted user interfaces.
33+
</dd>
34+
</div>
35+
36+
<!-- Item 2 -->
37+
<div class="flex flex-col bg-white/5 p-5 rounded-xl border border-white/5 backdrop-blur-sm hover:bg-white/10 transition-colors">
38+
<dt class="font-semibold text-white">
39+
<span class="block text-cyan-400 font-mono text-xs mb-1 opacity-70">02</span>
40+
End-to-end Type Safety
41+
</dt>
42+
<dd class="mt-2 text-sm text-blue-100/70 leading-relaxed">
43+
Share DTOs between .NET and React for confident refactors without context switching.
44+
</dd>
45+
</div>
46+
47+
<!-- Item 3 -->
48+
<div class="flex flex-col bg-white/5 p-5 rounded-xl border border-white/5 backdrop-blur-sm hover:bg-white/10 transition-colors">
49+
<dt class="font-semibold text-white">
50+
<span class="block text-cyan-400 font-mono text-xs mb-1 opacity-70">03</span>
51+
Zero-Ambiguity APIs
52+
</dt>
53+
<dd class="mt-2 text-sm text-blue-100/70 leading-relaxed">
54+
Consistent API integrations eliminates guesswork, giving AI the perfect context to generate accurate features.
55+
</dd>
56+
</div>
57+
</dl>
58+
59+
<div class="mt-8 flex flex-wrap gap-3">
60+
<a href="https://react.servicestack.net"
61+
class="inline-flex items-center justify-center rounded-md bg-cyan-500 px-4 py-2 text-sm font-bold text-blue-950 shadow-sm hover:bg-cyan-400 transition-colors">
62+
React Component Gallery
63+
</a>
64+
<a href="https://react-templates.net/docs"
65+
class="inline-flex items-center justify-center rounded-md bg-blue-950/50 px-4 py-2 text-sm font-semibold text-cyan-100 ring-1 ring-inset ring-cyan-500/30 hover:bg-blue-900 hover:ring-cyan-500/50 transition-all">
66+
Read the Docs
67+
</a>
68+
</div>
69+
</div>
70+
</div>
71+
</div>
72+
</section>
73+
`,
74+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import Icons from './Icons.mjs'
2+
3+
export default {
4+
name: 'ProjectTemplateSelector',
5+
data() {
6+
return {
7+
templates: [
8+
{
9+
id: 'vite',
10+
name: 'React Vite SPA',
11+
description: 'Empty SPA, fast development UX with Vite. Best for pure client-side apps.',
12+
url: 'https://github.com/new?template_name=react-static&template_owner=NetCoreTemplates',
13+
// Tailwind Colors
14+
colorBg: 'bg-blue-500',
15+
colorText: 'text-blue-500',
16+
hoverBorder: 'group-hover:border-blue-500/50',
17+
hoverText: 'group-hover:text-blue-600',
18+
iconXml: Icons.ReactNative,
19+
},
20+
{
21+
id: 'next',
22+
name: 'Next.js Static',
23+
description: 'Full-stack React framework using App Router configured for SSG static exports, SEO optimization built-in.',
24+
url: 'https://github.com/new?template_name=nextjs&template_owner=NetCoreTemplates',
25+
// Tailwind Colors
26+
colorBg: 'bg-slate-900',
27+
colorText: 'text-slate-900',
28+
hoverBorder: 'group-hover:border-slate-900/50',
29+
hoverText: 'group-hover:text-slate-900',
30+
iconXml: Icons.NextjsNative,
31+
},
32+
]
33+
}
34+
},
35+
template: `
36+
<div class="max-w-5xl mx-auto px-6 py-12 font-sans">
37+
<!-- Header Section -->
38+
<div class="text-center mb-12 space-y-4">
39+
<div class="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-indigo-50 border border-indigo-100 text-indigo-600 text-xs font-medium uppercase tracking-wide">
40+
<svg class="size-4" viewBox="0 0 24 24" fill="currentColor">
41+
<path d="M23.922 16.992c-.861 1.495-5.859 5.023-11.922 5.023-6.063 0-11.061-3.528-11.922-5.023A.641.641 0 0 1 0 16.736v-2.869a.841.841 0 0 1 .053-.22c.372-.935 1.347-2.292 2.605-2.656.167-.429.414-1.055.644-1.517a10.195 10.195 0 0 1-.052-1.086c0-1.331.282-2.499 1.132-3.368.397-.406.89-.717 1.474-.952 1.399-1.136 3.392-2.093 6.122-2.093 2.731 0 4.767.957 6.166 2.093.584.235 1.077.546 1.474.952.85.869 1.132 2.037 1.132 3.368 0 .368-.014.733-.052 1.086.23.462.477 1.088.644 1.517 1.258.364 2.233 1.721 2.605 2.656a.832.832 0 0 1 .053.22v2.869a.641.641 0 0 1-.078.256ZM12.172 11h-.344a4.323 4.323 0 0 1-.355.508C10.703 12.455 9.555 13 7.965 13c-1.725 0-2.989-.359-3.782-1.259a2.005 2.005 0 0 1-.085-.104L4 11.741v6.585c1.435.779 4.514 2.179 8 2.179 3.486 0 6.565-1.4 8-2.179v-6.585l-.098-.104s-.033.045-.085.104c-.793.9-2.057 1.259-3.782 1.259-1.59 0-2.738-.545-3.508-1.492a4.323 4.323 0 0 1-.355-.508h-.016.016Zm.641-2.935c.136 1.057.403 1.913.878 2.497.442.544 1.134.938 2.344.938 1.573 0 2.292-.337 2.657-.751.384-.435.558-1.15.558-2.361 0-1.14-.243-1.847-.705-2.319-.477-.488-1.319-.862-2.824-1.025-1.487-.161-2.192.138-2.533.529-.269.307-.437.808-.438 1.578v.021c0 .265.021.562.063.893Zm-1.626 0c.042-.331.063-.628.063-.894v-.02c-.001-.77-.169-1.271-.438-1.578-.341-.391-1.046-.69-2.533-.529-1.505.163-2.347.537-2.824 1.025-.462.472-.705 1.179-.705 2.319 0 1.211.175 1.926.558 2.361.365.414 1.084.751 2.657.751 1.21 0 1.902-.394 2.344-.938.475-.584.742-1.44.878-2.497Z"></path><path d="M14.5 14.25a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0v-2a1 1 0 0 1 1-1Zm-5 0a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0v-2a1 1 0 0 1 1-1Z"></path>
42+
</svg>
43+
GitHub Copilot Ready
44+
</div>
45+
<h2 class="text-4xl font-extrabold text-slate-900 tracking-tight">
46+
Jumpstart your project with Copilot
47+
</h2>
48+
<p class="text-lg text-slate-600 max-w-2xl mx-auto">
49+
Select a React .NET template to instantly scaffold a new repository with Copilot.
50+
Describe what you want to build, and Copilot will generate the initial implementation and open a pull request.
51+
</p>
52+
</div>
53+
54+
<!-- Grid Section -->
55+
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
56+
<a
57+
v-for="template in templates"
58+
:key="template.id"
59+
:href="template.url"
60+
rel="noopener noreferrer"
61+
class="group relative flex flex-col bg-white rounded-2xl p-6 border border-slate-200 shadow-sm hover:shadow-xl transition-all duration-300 ease-out hover:-translate-y-1"
62+
:class="template.hoverBorder"
63+
>
64+
<!-- Top Decoration Line -->
65+
<div
66+
class="absolute top-0 left-0 w-full h-1.5 rounded-t-2xl opacity-0 group-hover:opacity-100 transition-opacity duration-300"
67+
:class="template.colorBg"
68+
></div>
69+
70+
<div class="flex items-start justify-between mb-4">
71+
<!--
72+
Icon Container
73+
Note: [&>svg] selectors force the pasted SVG to be 32x32px
74+
-->
75+
<div
76+
class="p-3 bg-slate-50 rounded-xl group-hover:bg-white group-hover:scale-110 transition-all duration-300 border border-slate-100 [&>svg]:w-8 [&>svg]:h-8"
77+
:class="template.colorText"
78+
v-html="template.iconXml"
79+
>
80+
</div>
81+
82+
<!-- External Link Icon -->
83+
<span class="text-slate-300 group-hover:text-slate-500 transition-colors">
84+
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
85+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"></path>
86+
</svg>
87+
</span>
88+
</div>
89+
90+
<h3
91+
class="text-xl font-bold text-slate-900 mb-2 transition-colors"
92+
:class="template.hoverText"
93+
>
94+
{{ template.name }}
95+
</h3>
96+
97+
<p class="text-slate-500 text-sm leading-relaxed flex-grow">
98+
{{ template.description }}
99+
</p>
100+
101+
<div class="mt-6 pt-4 border-t border-slate-100 flex items-center text-sm font-semibold opacity-0 -translate-x-2 group-hover:opacity-100 group-hover:translate-x-0 transition-all duration-300"
102+
:class="template.colorText">
103+
Use Template <span class="ml-1">&rarr;</span>
104+
</div>
105+
</a>
106+
</div>
107+
</div>
108+
`
109+
}

MyApp/wwwroot/pages/components/Templates.mjs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,24 @@ export function template(repo, name, icon, tags, demo, mix) {
88

99
export const Index = [
1010
template('web', 'Web', 'ServiceStack', ['empty']),
11+
template('nextjs', 'Next.js', 'Nextjs',['next','featured']),
12+
template('next-rsc', 'Next.js RSC', 'Nextjs',['next','rsc']),
13+
template('next-static', 'Next.js Static', 'Nextjs',['next','static']),
14+
template('react-static', 'React Static', 'React',['react','static']),
15+
template('react-spa', 'React SPA', 'React',['react','featured']),
1116
template('blazor', 'Blazor', 'Blazor', ['tailwind']),
1217
template('blazor-vue', 'Blazor Vue', 'Blazor',['tailwind']),
1318
template('mvc', 'MVC', 'Windows',['tailwind']),
1419
template('razor', 'Razor Pages', 'Razor',['tailwind']),
1520
template('mvc-bootstrap', 'MVC', 'Windows',['bootstrap']),
1621
template('razor-bootstrap', 'Razor Pages', 'Razor',['bootstrap']),
1722
template('vue-mjs', 'Razor Pages', 'Razor',['tailwind','autoquery']),
18-
template('nextjs', 'Next.js', 'Nextjs',['tailwind','autoquery']),
1923
template('vue-vite', 'Vue Vite', 'Vue',['tailwind','autoquery']),
2024
template('vue-ssg', 'Vue SSG', 'Vue',['tailwind','autoquery']),
2125
template('razor-pages', 'Razor Pages', 'Razor',['bootstrap']),
2226
template('mvcauth', 'MVC', 'Windows',['bootstrap']),
2327
template('script', 'MVC', 'Windows',['bootstrap']),
2428
template('vue-spa', 'Vue SPA', 'Vue',['tailwind']),
25-
template('react-static', 'React Static', 'React',['tailwind','autoquery']),
26-
template('react-spa', 'React SPA', 'React',['tailwind','autoquery']),
2729
template('angular-spa', 'Angular SPA', 'Angular',['tailwind']),
2830
template('kmp-desktop', 'Compose Desktop', 'Compose',['kotlin','desktop']),
2931
].reduce((acc, template) => { acc[template.repo] = template; return acc}, {})

MyApp/wwwroot/pages/templates/react.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
import VibeTemplate from "../components/VibeTemplate.mjs"
12
import ReactTemplate from "../components/ReactTemplate.mjs"
23
import ScreenshotsGallery from "../components/ScreenshotsGallery.mjs"
34

45
export default {
56
install(app) {
67
},
78
components: {
9+
VibeTemplate,
810
ReactTemplate,
911
ScreenshotsGallery,
1012
},

0 commit comments

Comments
 (0)