Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 39 additions & 6 deletions apps/web/content/docs/dev/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,18 @@ import { Callout } from 'fumadocs-ui/components/callout'
A VitNode app has two configuration files, and the line between them is one
question: **may a browser hold this?**

| File | Holds | Reached by |
| :----------------------------- | :---------------------------------------------------- | :----------------------------------------------- |
| `src/vitnode.config.ts` | locales, metadata, theme, `debug`, enabled plugin ids | the browser, the server, **and your Vite build** |
| `src/vitnode.server.config.ts` | message loaders | the server only |
| File | Holds | Reached by |
| :----------------------------- | :---------------------------------------------------------- | :----------------------------------------------- |
| `src/vitnode.config.ts` | locales, metadata, logo, theme, `debug`, enabled plugin ids | the browser, the server, **and your Vite build** |
| `src/vitnode.server.config.ts` | message loaders | the server only |

---

## `vitnode.config.ts` - the shared config

```ts title="apps/web/src/vitnode.config.ts"
import { blogPlugin } from '@vitnode/blog/config'
import { LogoVitNodeBrand } from '@vitnode/core/components/logo-vitnode'
import { buildConfig } from '@vitnode/core/vitnode.config'

export const vitNodeConfig = buildConfig({
Expand All @@ -32,6 +33,7 @@ export const vitNodeConfig = buildConfig({
],
timeZone: 'UTC',
},
logo: LogoVitNodeBrand,
metadata: {
shortTitle: 'VitNode',
title: 'VitNode',
Expand All @@ -45,7 +47,7 @@ export const vitNodeConfig = buildConfig({

Three very different readers depend on this file:

1. **The document shell** renders `metadata`, `theme` and `debug` - in the
1. **The document shell** renders `metadata`, `logo`, `theme` and `debug` - in the
browser as well as on the server.
2. **The locale runtime** derives routing from `i18n`.
3. **Your Vite build** loads it with `jiti` while Vite is still resolving its
Expand All @@ -56,7 +58,7 @@ Three very different readers depend on this file:
Because of reader 3, this file is executed at build time; because of reader 1
it is bundled for a browser. So it holds plain data and plugin *identity* -
never a `() => import(...)` message loader, and never a module that reaches a
database.
database. The one exception is `logo`: a small, self-contained component.
</Callout>

`buildConfig` keeps `locales` a tuple of literal types, so a `Locale` derived
Expand All @@ -67,6 +69,37 @@ against the list right beside it:
export type Locale = (typeof vitNodeConfig.i18n.locales)[number]['code']
```

### Logo

`logo` is the component the site header shows in its home link. Leave it out
and you get the VitNode logo - which is lovely, but it is probably not your
brand.

```tsx title="src/components/logo.tsx"
export const Logo = () => (
<img
alt="Acme"
className="h-8 w-auto"
height={32}
src="/logo.svg"
width={96}
/>
)
```

```ts title="src/vitnode.config.ts"
import { Logo } from '@/components/logo'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use a resolvable import in the logo example

Following this example makes VitNode's build-time config discovery fail with an unresolved module: readAppConfig loads vitnode.config.ts directly through Jiti with no @/ alias configuration, so Vite's later resolve.tsconfigPaths handling is never involved. Use a relative import such as ./components/logo here so users can add the documented logo without breaking route and registry generation.

Useful? React with 👍 / 👎.


export const vitNodeConfig = buildConfig({
// ...
logo: Logo,
})
```

Pass the component itself, not `<Logo />`. Keep it lean: your Vite build
executes this file too, so a logo that imports half your UI makes every
regeneration pass slower.

### Enabled plugins

Register a plugin with its own factory:
Expand Down
21 changes: 0 additions & 21 deletions apps/web/src/components/admin-shell.tsx

This file was deleted.

6 changes: 0 additions & 6 deletions apps/web/src/components/main-header.tsx

This file was deleted.

4 changes: 2 additions & 2 deletions apps/web/src/routes/__root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { vitNodeConfig } from '@/vitnode.config'

import appCss from '../styles.css?url'

const { debug, editor, i18n, metadata, theme } = vitNodeConfig
const { debug, editor, i18n, logo, metadata, theme } = vitNodeConfig

export interface RootRouterContext {
queryClient: QueryClient
Expand Down Expand Up @@ -67,7 +67,7 @@ export const Route = createRootRouteWithContext<RootRouterContext>()({
function RootComponent() {
return (
<VitNodeRootProviders
config={{ debug, editor, locales: i18n.locales, theme }}
config={{ debug, editor, locales: i18n.locales, logo, theme }}
>
<Outlet />
</VitNodeRootProviders>
Expand Down
51 changes: 5 additions & 46 deletions apps/web/src/routes/_admin.tsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,6 @@
import { createFileRoute, Outlet, redirect } from '@tanstack/react-router'
import {
ADMIN_ENTRY_PATH,
adminReturnToFor,
canEnterAdmin,
ensureAdminAccess,
loadAdminMessages,
preloadAdminAccess,
} from '@vitnode/core/tanstack/admin'
import { pageHead } from '@vitnode/core/tanstack/metadata'
import { createFileRoute } from '@tanstack/react-router'
import { adminLayoutRoute } from '@vitnode/core/tanstack/admin'

import { AdminShell } from '@/components/admin-shell'

export const Route = createFileRoute('/_admin')({
beforeLoad: async ({ context, location, preload }) => {
const access = preload
? await preloadAdminAccess(context.queryClient)
: await ensureAdminAccess(context.queryClient)

if (!canEnterAdmin(access)) {
// eslint-disable-next-line @typescript-eslint/only-throw-error
throw redirect({
search: { returnTo: adminReturnToFor(location) },
to: ADMIN_ENTRY_PATH,
} as unknown as Parameters<typeof redirect>[0])
}

return { adminAccess: access }
},

loader: async ({ context }) => {
const { adminNav } = await import('@/admin-nav.gen')

await loadAdminMessages({ ...context, namespaces: adminNav.namespaces })
},

head: () => pageHead({ robots: 'noindex, nofollow' }),
component: AdminLayout,
})

function AdminLayout() {
return (
<AdminShell>
<Outlet />
</AdminShell>
)
}
export const Route = createFileRoute('/_admin')(
adminLayoutRoute(async () => await import('@/admin-nav.gen')),
)
2 changes: 1 addition & 1 deletion apps/web/src/routes/_main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { createFileRoute, Outlet } from '@tanstack/react-router'
import { MainBreadcrumb } from '@vitnode/core/tanstack/breadcrumb'
import {
loadMainShell,
MainHeader,
ThemeLayoutContent,
} from '@vitnode/core/tanstack/layout'

import { MainHeader } from '@/components/main-header'
import { SiteFooter } from '@/site/marketing/footer'

const MainLayout = () => (
Expand Down
2 changes: 0 additions & 2 deletions apps/web/src/site/home/home-content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { HeroSection } from '@/site/home/sections/hero'
import { IntegrationsSection } from '@/site/home/sections/integrations'
import { OutcomesSection } from '@/site/home/sections/outcomes'
import { PluginsSection } from '@/site/home/sections/plugins'
import { PoweringBySection } from '@/site/home/sections/powering-by'
import { PricingSection } from '@/site/home/sections/pricing'
import { SecuritySection } from '@/site/home/sections/security'
import { ShowcaseSection } from '@/site/home/sections/showcase'
Expand All @@ -22,7 +21,6 @@ export const HomeRouteContent = () => (
<RouteMessages namespaces={HOME_NAMESPACES}>
<MarketingPage>
<HeroSection />
<PoweringBySection />
<div className="container mx-auto px-4 pt-12 sm:px-6">
<CanaryNotice />
</div>
Expand Down
Loading
Loading