1import * as Namespace from "../../Namespace.ts";
2import { makeFrameworkSite, type FrameworkSiteProps } from "./FrameworkSite.ts";
3
4/** The framework-integration package that drives the SolidStart build. */
5export const SOLIDSTART_FRAMEWORK_SPECIFIER =
6 "@alchemy.run/frontend-frameworks/solidstart";
7
8/** The Node container deploy target for the SolidStart build. */
9export const SOLIDSTART_NODE_TARGET_SPECIFIER =
10 "@alchemy.run/frontend-frameworks/solidstart/node";
11
12export interface SolidStartProps extends FrameworkSiteProps {
13 /**
14 * Nitro options forwarded into the nitro plugin the integration appends
15 * (prerendering, route rules, storage, ...). `preset` is owned by the
16 * Node deploy target and may not be set here. JSON-serializable values
17 * only — no functions or plugin instances.
18 *
19 * This is a prop (rather than project config) because the integration
20 * owns the nitro plugin instance: a `nitroV2Plugin()` in your project's
21 * `vite.config.*` is rejected, so this prop is the one home for nitro
22 * options — and it accepts values derived from other resources' Outputs,
23 * which a config file cannot.
24 */
25 nitro?: Record<string, unknown>;
26}
27
28/**
29 * Deploy a [SolidStart](https://start.solidjs.com) application to a
30 * Hetzner Cloud Server: the SSR server as a systemd unit on port 3000,
31 * static assets (prerendered pages included) baked into the unit.
32 *
33 * The build runs through `@alchemy.run/frontend-frameworks/solidstart` with
34 * the `@alchemy.run/frontend-frameworks/solidstart/node` deploy target —
35 * both must be installed in your project, alongside `@solidjs/start` and
36 * `@solidjs/vite-plugin-nitro-2`.
37 *
38 * Your `vite.config.ts` needs no adapter wiring: the integration drives the
39 * project's own `vite build` and appends its own nitro plugin instance
40 * carrying nitro's `node` preset.
41 *
42 *
43 * ### Creating SolidStart Sites
44 * **Example:** Basic SolidStart App
45 * ```typescript
46 * const site = yield* Hetzner.Website.SolidStart("Web", {
47 * rootDir: "./app",
48 * });
49 * ```
50 *
51 * **Example:** Custom Domain
52 * ```typescript
53 * const site = yield* Hetzner.Website.SolidStart("Web", {
54 * rootDir: "./app",
55 * domain: "app.example.com",
56 * zone,
57 * });
58 * ```
59 *
60 * ### Server Configuration
61 * **Example:** Process Environment
62 * ```typescript
63 * const site = yield* Hetzner.Website.SolidStart("Web", {
64 * rootDir: "./app",
65 * env: {
66 * API_BASE: "https://api.example.com",
67 * },
68 * });
69 * ```
70 *
71 * ### Prerendering
72 * The integration owns the nitro plugin instance (a `nitroV2Plugin()` in
73 * your `vite.config.*` is rejected), so nitro options — prerendering
74 * included — go on the `nitro` prop. Prerendered pages are baked into the
75 * unit and served as static assets.
76 *
77 * **Example:** Prerender Routes
78 * ```typescript
79 * const site = yield* Hetzner.Website.SolidStart("Web", {
80 * rootDir: "./app",
81 * nitro: { prerender: { routes: ["/", "/about"] } },
82 * });
83 * ```
84 *
85 * @resource
86 * @product Website
87 */
88export const SolidStart = (id: string, props: SolidStartProps = {}) =>
89 makeFrameworkSite(id, props, {
90 name: "SolidStart",
91 framework: SOLIDSTART_FRAMEWORK_SPECIFIER,
92 target: SOLIDSTART_NODE_TARGET_SPECIFIER,
93 options: { nitro: props.nitro },
94 }).pipe(Namespace.push(id));