Serves public website, admin SPA, and API from a single host
Shared hosting (e.g. mijnhostingpartner.nl) typically allows only one site/app-pool, so SlpModularCms.Api now serves everything itself: '/' for the customer's public website (deployed separately, not part of this repo), '/admin' for the CMS admin SPA, and '/api/v1' for the API as before. - Program.cs: static files from wwwroot + SPA fallbacks per path so client-side routing works for both frontends. - frontend/: builds with base '/admin/' in production (dev unchanged), router basepath follows suit. - SlpModularCms.Api.csproj: publish now builds the admin frontend and copies its output into wwwroot/admin automatically. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wi5qHAuq8UbzN4NLUFeKkJ
This commit is contained in:
+2
-2
@@ -28,8 +28,8 @@ bld/
|
|||||||
|
|
||||||
# Visual Studio 2015/2017/2019/2022 cache/options directory
|
# Visual Studio 2015/2017/2019/2022 cache/options directory
|
||||||
.vs/
|
.vs/
|
||||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
# Generated on publish: admin SPA build (+ separately-deployed public website), see SlpModularCms.Api.csproj
|
||||||
#wwwroot/
|
wwwroot/
|
||||||
|
|
||||||
# Visual Studio Code design time settings
|
# Visual Studio Code design time settings
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|||||||
@@ -281,11 +281,25 @@ Zie `aidlc-docs/features/local-dev-master-slave-setup/inception/requirements/req
|
|||||||
|
|
||||||
## Productie Setup
|
## Productie Setup
|
||||||
|
|
||||||
|
### 0. Routing op de webhost
|
||||||
|
Op een shared-hosting omgeving (zoals mijnhostingpartner.nl) is er meestal maar ruimte voor 1 website/app-pool. Daarom serveert `SlpModularCms.Api` alles zelf, vanuit één proces:
|
||||||
|
|
||||||
|
| Pad | Inhoud |
|
||||||
|
|---|---|
|
||||||
|
| `/` | De publieke website van de klant — **geen onderdeel van deze repo**, wordt los aangeleverd/gedeployed in `wwwroot/` |
|
||||||
|
| `/admin` | De CMS admin-UI (`frontend/`), gebouwd met `base: '/admin/'` en automatisch gekopieerd naar `wwwroot/admin/` bij `dotnet publish` |
|
||||||
|
| `/api/v1/...` | Deze API |
|
||||||
|
|
||||||
|
Beide SPA's krijgen een fallback naar hun eigen `index.html` zodat client-side routes (bijv. `/admin/dashboard`) werken; ontbrekende bestanden (met een extensie, bijv. `/admin/assets/x.js`) blijven gewoon 404'en. Zie `Program.cs` (`MapFallbackToFile`) en `SlpModularCms.Api.csproj` (`BuildAndCopyAdminFrontend`-target).
|
||||||
|
|
||||||
|
Voor lokale ontwikkeling verandert er niets: `pnpm dev` blijft op `http://localhost:5173` draaien zonder `/admin`-prefix.
|
||||||
|
|
||||||
### 1. Build & Publish
|
### 1. Build & Publish
|
||||||
Compileer de applicatie voor productie:
|
Compileer de applicatie voor productie — dit bouwt en kopieert automatisch ook de admin-frontend naar `wwwroot/admin/`:
|
||||||
```powershell
|
```powershell
|
||||||
dotnet publish src/SlpModularCms.Api -c Release -o ./publish
|
dotnet publish src/SlpModularCms.Api -c Release -o ./publish
|
||||||
```
|
```
|
||||||
|
Kopieer daarna de publieke website van de klant naar `./publish/wwwroot/` (alles behalve de `admin/`-submap, die blijft ongemoeid).
|
||||||
|
|
||||||
### 2. Runtime Configuratie
|
### 2. Runtime Configuratie
|
||||||
In productie moeten gevoelige instellingen worden doorgegeven via Environment Variables:
|
In productie moeten gevoelige instellingen worden doorgegeven via Environment Variables:
|
||||||
|
|||||||
@@ -231,6 +231,8 @@ export const routeTree = rootRoute.addChildren([
|
|||||||
export const router = createRouter({
|
export const router = createRouter({
|
||||||
routeTree,
|
routeTree,
|
||||||
defaultPreload: 'intent',
|
defaultPreload: 'intent',
|
||||||
|
// Matches vite.config.ts's `base`: '/admin/' in production builds, '/' in dev.
|
||||||
|
basepath: import.meta.env.BASE_URL,
|
||||||
context: { auth: undefined as unknown as AuthContextValue },
|
context: { auth: undefined as unknown as AuthContextValue },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ import react from '@vitejs/plugin-react';
|
|||||||
import tailwindcss from '@tailwindcss/vite';
|
import tailwindcss from '@tailwindcss/vite';
|
||||||
|
|
||||||
// https://vite.dev/config/
|
// https://vite.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig(({ command }) => ({
|
||||||
|
// Production builds are deployed under /admin (see Program.cs); the dev server keeps serving from '/'.
|
||||||
|
base: command === 'build' ? '/admin/' : '/',
|
||||||
plugins: [react(), tailwindcss()],
|
plugins: [react(), tailwindcss()],
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
@@ -34,4 +36,4 @@ export default defineConfig({
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
}));
|
||||||
|
|||||||
@@ -46,6 +46,12 @@ if (app.Environment.IsDevelopment())
|
|||||||
|
|
||||||
app.UseHttpsRedirection();
|
app.UseHttpsRedirection();
|
||||||
|
|
||||||
|
// Serve the public website ('/') and the CMS admin SPA ('/admin') from wwwroot.
|
||||||
|
// wwwroot/index.html + assets -> public website (built and deployed separately, not part of this repo)
|
||||||
|
// wwwroot/admin/index.html + assets -> CMS admin build (see frontend/, copied in on publish)
|
||||||
|
app.UseDefaultFiles();
|
||||||
|
app.UseStaticFiles();
|
||||||
|
|
||||||
app.UseCors();
|
app.UseCors();
|
||||||
|
|
||||||
// 7. Use Module Middleware
|
// 7. Use Module Middleware
|
||||||
@@ -56,4 +62,9 @@ app.UseAuthorization();
|
|||||||
|
|
||||||
app.MapControllers();
|
app.MapControllers();
|
||||||
|
|
||||||
|
// SPA fallbacks so client-side routes (e.g. /admin/dashboard) resolve to the right index.html
|
||||||
|
// instead of 404ing. The "nonfile" constraint keeps genuinely missing assets (e.g. /admin/assets/x.js) as 404s.
|
||||||
|
app.MapFallbackToFile("/admin/{*path:nonfile}", "admin/index.html");
|
||||||
|
app.MapFallbackToFile("{*path:nonfile}", "index.html");
|
||||||
|
|
||||||
app.Run();
|
app.Run();
|
||||||
|
|||||||
@@ -24,4 +24,23 @@
|
|||||||
<ProjectReference Include="..\SlpModularCms.Modules.Master\SlpModularCms.Modules.Master.csproj" />
|
<ProjectReference Include="..\SlpModularCms.Modules.Master\SlpModularCms.Modules.Master.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Builds the CMS admin SPA (frontend/) and copies its output into wwwroot/admin so it's served
|
||||||
|
at the /admin path (see Program.cs). Only runs on `dotnet publish`, not on every dev build.
|
||||||
|
The public website ('/') lives outside this repo and is deployed into wwwroot separately.
|
||||||
|
-->
|
||||||
|
<PropertyGroup>
|
||||||
|
<AdminFrontendDir>$(MSBuildProjectDirectory)/../../frontend</AdminFrontendDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<Target Name="BuildAndCopyAdminFrontend" BeforeTargets="Publish">
|
||||||
|
<Message Importance="high" Text="Building CMS admin frontend ($(AdminFrontendDir))..." />
|
||||||
|
<Exec Command="pnpm install --frozen-lockfile" WorkingDirectory="$(AdminFrontendDir)" />
|
||||||
|
<Exec Command="pnpm build" WorkingDirectory="$(AdminFrontendDir)" />
|
||||||
|
<ItemGroup>
|
||||||
|
<AdminFrontendFiles Include="$(AdminFrontendDir)/dist/**/*" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Copy SourceFiles="@(AdminFrontendFiles)" DestinationFolder="$(MSBuildProjectDirectory)/wwwroot/admin/%(RecursiveDir)" SkipUnchangedFiles="true" />
|
||||||
|
</Target>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
Reference in New Issue
Block a user