@@ -18,39 +18,31 @@ npm install react react-dom fastify
1818
1919Aurora has two entry points: ` server ` and ` client ` .
2020
21- ### Server ( ` src/server/server.ts ` )
21+ ### Server
2222
2323``` ts
2424import path from " path"
2525import { createServer } from " @cobaltcore-dev/aurora/server"
2626
27- createServer ({
28- viteRoot: path .resolve (__dirname , " ../.." ), // root of your app (where dist/client lives)
29- identityEndpoint: process .env .IDENTITY_ENDPOINT , // OpenStack Keystone URL
30- bffEndpoint: process .env .BFF_ENDPOINT , // tRPC prefix, default "/polaris-bff"
31- defaultEndpointInterface: process .env .DEFAULT_ENDPOINT_INTERFACE , // "public" | "internal"
32- proxyUrl: process .env .GLOBAL_AGENT_HTTP_PROXY , // optional HTTP proxy (dev only)
33- cephRegion: process .env .CEPH_REGION , // Ceph/S3 region for object storage
34- imageMetadataExcludedProperties: process .env .IMAGE_METADATA_EXCLUDED_PROPERTIES , // comma-separated
35- insecureCookies: process .env .INSECURE_COOKIES === " true" , // disable Secure flag locally
36- }).then ((server ) => server .listen ({ host: " 0.0.0.0" , port: 4000 }))
27+ const server = await createServer ({
28+ identityEndpoint: " https://keystone.example.com/v3/" ,
29+ policyDir: path .resolve (__dirname , " ../policies" ),
30+ })
31+
32+ server .listen ({ host: " 0.0.0.0" , port: 4000 })
3733```
3834
39- ### Client ( ` src/client/App.tsx ` )
35+ ### Client
4036
4137``` tsx
4238import { AuroraApp } from " @cobaltcore-dev/aurora/client"
43- import " @cobaltcore-dev/aurora/client/style.css" // include once at your app root
4439
4540export function App() {
4641 return (
4742 <AuroraApp
48- bffEndpoint = " /polaris-bff" // must match the server's bffEndpoint
49- theme = " theme-light" // "theme-light" | "theme-dark"
50- onThemeChange = { (theme ) => {
51- // called when user toggles — persist however you like
52- localStorage .setItem (" theme" , theme )
53- }}
43+ bffEndpoint = " /polaris-bff"
44+ theme = " theme-light"
45+ onThemeChange = { (theme ) => localStorage .setItem (" theme" , theme )}
5446 />
5547 )
5648}
@@ -60,80 +52,84 @@ export function App() {
6052
6153### ` createServer(config) `
6254
63- | Option | Type | Default | Description |
64- | --------------------------------- | --------- | -------------------------- | ---------------------------------------------------------------- |
65- | ` identityEndpoint ` | ` string ` | — | OpenStack Keystone v3 URL (required) |
66- | ` bffEndpoint ` | ` string ` | ` "/polaris-bff" ` | URL prefix for all tRPC routes |
67- | ` viteRoot ` | ` string ` | ` __dirname/../../ ` | Directory that contains ` dist/client/ ` in production |
68- | ` defaultEndpointInterface ` | ` string ` | ` "public" ` | OpenStack service catalog interface |
69- | ` proxyUrl ` | ` string ` | — | HTTP proxy for OpenStack calls (dev only, ignored in production) |
70- | ` cephRegion ` | ` string ` | — | Ceph RGW region for S3 operations |
71- | ` imageMetadataExcludedProperties ` | ` string ` | — | Comma-separated image metadata keys to hide in the UI |
72- | ` cookieName ` | ` string ` | ` "dashboard-session-auth" ` | Override the session cookie name |
73- | ` crossDomainCookie ` | ` boolean ` | ` true ` | Share cookie across subdomains |
74- | ` insecureCookies ` | ` boolean ` | ` false ` | Disable ` Secure ` flag — only for HTTP-only local dev |
55+ | Option | Type | Required | Default | Description |
56+ | --------------------------------- | --------- | -------- | -------------------------- | ---------------------------------------------------------------- |
57+ | ` identityEndpoint ` | ` string ` | yes | — | OpenStack Keystone v3 URL |
58+ | ` policyDir ` | ` string ` | yes | — | Absolute path to a directory of OpenStack policy YAML files |
59+ | ` bffEndpoint ` | ` string ` | no | ` "/polaris-bff" ` | URL prefix for all tRPC routes |
60+ | ` viteRoot ` | ` string ` | no | — | Directory that contains ` dist/client/ ` in production |
61+ | ` defaultEndpointInterface ` | ` string ` | no | ` "public" ` | OpenStack service catalog interface |
62+ | ` proxyUrl ` | ` string ` | no | — | HTTP proxy for OpenStack calls (dev only, ignored in production) |
63+ | ` cephRegion ` | ` string ` | no | — | Ceph RGW region for S3 operations |
64+ | ` imageMetadataExcludedProperties ` | ` string ` | no | — | Comma-separated image metadata keys to hide in the UI |
65+ | ` cookieName ` | ` string ` | no | ` "dashboard-session-auth" ` | Override the session cookie name |
66+ | ` crossDomainCookie ` | ` boolean ` | no | ` true ` | Share cookie across subdomains |
67+ | ` insecureCookies ` | ` boolean ` | no | ` false ` | Disable ` Secure ` flag — only for HTTP-only local dev |
7568
7669### ` <AuroraApp /> `
7770
78- | Prop | Type | Default | Description |
79- | --------------- | ------------------------------- | ---------------- | -------------------------------------- |
80- | ` bffEndpoint ` | ` string ` | ` "/polaris-bff" ` | Must match the server's ` bffEndpoint ` |
81- | ` theme ` | ` "theme-light" \| "theme-dark" ` | ` "theme-light" ` | Initial theme |
82- | ` onThemeChange ` | ` (theme) => void ` | — | Called when the user toggles the theme |
71+ | Prop | Type | Default | Description |
72+ | --------------- | ------------------------------- | ---------------- | -------------------------------------------------- |
73+ | ` bffEndpoint ` | ` string ` | ` "/polaris-bff" ` | Must match the server's ` bffEndpoint ` |
74+ | ` theme ` | ` "theme-light" \| "theme-dark" ` | ` "theme-light" ` | Initial theme |
75+ | ` onThemeChange ` | ` (theme) => void ` | — | Called when the user toggles the theme |
76+ | ` appName ` | ` string ` | ` "Aurora" ` | App name shown in the header breadcrumb and logo |
77+ | ` slots ` | ` Slots ` | — | Optional UI extension points — see [ Slots] ( #slots ) |
8378
84- ## Environment variables
79+ ## Slots
8580
86- Your app reads these from ` .env ` and passes them to ` createServer() ` . Aurora itself never reads environment variables .
81+ Slots let you inject your own React components into specific locations inside ` AuroraApp ` without forking the package. Each slot receives an ` auroraContext ` object with a ` client ` (tRPC client) for making API calls .
8782
88- ``` env
89- IDENTITY_ENDPOINT="https://keystone.example.com/v3/"
90- DEFAULT_ENDPOINT_INTERFACE="public"
91- BFF_ENDPOINT="/polaris-bff"
92- PORT="4000"
83+ ``` tsx
84+ import type { SlotProps } from " @cobaltcore-dev/aurora/client"
9385
94- # Object storage (optional)
95- CEPH_REGION="ceph-objectstore-st1-region-1"
86+ function MyLogo(_props : SlotProps ) {
87+ return <img src = " /my-logo.svg" alt = " My App" style = { { height: " 1.5rem" }} />
88+ }
9689
97- # Local dev only
98- INSECURE_COOKIES=true
99- # GLOBAL_AGENT_HTTP_PROXY=http://localhost:8888
100- ```
90+ function MyBanner({ auroraContext } : SlotProps ) {
91+ // auroraContext.client gives you access to the tRPC API
92+ return < div >Custom sidebar content</ div >
93+ }
10194
102- The ` VITE_BFF_ENDPOINT ` variable (prefixed with ` VITE_ ` ) is read by Vite and passed to the client:
95+ function MyFooter(_props : SlotProps ) {
96+ return (
97+ <footer >
98+ <a href = " /imprint" >Imprint</a > · <a href = " /privacy" >Privacy</a >
99+ </footer >
100+ )
101+ }
103102
104- ``` env
105- VITE_BFF_ENDPOINT="/polaris-bff"
103+ ;< AuroraApp
104+ slots = {{
105+ logo : MyLogo ,
106+ sideNavBanner : MyBanner ,
107+ pageFooter : MyFooter ,
108+ }}
109+ / >
106110```
107111
108- ``` tsx
109- <AuroraApp bffEndpoint = { import .meta .env .VITE_BFF_ENDPOINT } />
110- ```
112+ ### Available slots
111113
112- ## Vite config
114+ | Slot | Location | Renders in shadow DOM |
115+ | --------------- | ----------------------------------------------- | --------------------- |
116+ | ` logo ` | Page header, replacing the default Aurora logo | No |
117+ | ` sideNavBanner ` | Bottom of the project side navigation | Yes |
118+ | ` pageFooter ` | Page footer, replacing the default empty footer | No |
113119
114- In development, point Vite at your own server plugin. In production no extra plugins are needed — aurora ships pre-built CSS and assets.
120+ ** Shadow DOM isolation: ** Slots rendered in a shadow DOM cannot inherit styles from the host page. If your slot component uses a CSS framework, inject the styles inline:
115121
116- ``` js
117- // vite.config.mjs
118- import { defineConfig } from " vite"
119- import react from " @vitejs/plugin-react-swc"
120- import viteFastify from " @fastify/vite/plugin"
121-
122- export default defineConfig (({ mode }) => ({
123- root: " ./src/client" ,
124- build: { outDir: " ../../dist/client" },
125- plugins: [mode !== " production" && viteFastify (), react ()],
126- }))
127- ```
128-
129- ## Running the app
130-
131- ``` bash
132- # Development (hot-reload)
133- tsx watch --env-file=.env src/server/server.ts
122+ ``` tsx
123+ import styles from " my-lib/styles.css?inline"
134124
135- # Production
136- NODE_ENV=production tsx --env-file=.env src/server/server.ts
125+ function MyBanner(_props : SlotProps ) {
126+ return (
127+ <>
128+ <style >{ styles } </style >
129+ <div >...</div >
130+ </>
131+ )
132+ }
137133```
138134
139135## License
0 commit comments