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 Railway:
30 * the SSR server plus client assets (prerendered pages included) on one
31 * `Railway.Service`.
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 * During `alchemy dev` the site is SolidStart's own Vite dev server and no
43 * cloud resources are created. `Alchemy.remote()` opts back into the live
44 * Service path.
45 *
46 * ### Creating SolidStart Sites
47 * **Example:** Basic SolidStart App
48 * ```typescript
49 * const site = yield* Railway.Website.SolidStart("Web", {
50 * rootDir: "./app",
51 * });
52 * ```
53 *
54 * **Example:** Custom Domain
55 * ```typescript
56 * const site = yield* Railway.Website.SolidStart("Web", {
57 * rootDir: "./app",
58 * domain: "app.example.com",
59 * });
60 * ```
61 *
62 * ### Server Configuration
63 * **Example:** Process Environment
64 * ```typescript
65 * const site = yield* Railway.Website.SolidStart("Web", {
66 * rootDir: "./app",
67 * env: {
68 * GREETING: "Hello from SolidStart on Railway!",
69 * },
70 * });
71 * ```
72 *
73 * ### Prerendering
74 * The integration owns the nitro plugin instance (a `nitroV2Plugin()` in
75 * your `vite.config.*` is rejected), so nitro options — prerendering
76 * included — go on the `nitro` prop. Prerendered pages are baked into the
77 * Service image and served as static files.
78 *
79 * **Example:** Prerender Routes
80 * ```typescript
81 * const site = yield* Railway.Website.SolidStart("Web", {
82 * rootDir: "./app",
83 * nitro: { prerender: { routes: ["/", "/about"] } },
84 * });
85 * ```
86 *
87 * @resource
88 * @product Website
89 */
90export const SolidStart = (id: string, props: SolidStartProps = {}) =>
91 makeFrameworkSite(id, props, {
92 name: "SolidStart",
93 framework: SOLIDSTART_FRAMEWORK_SPECIFIER,
94 target: SOLIDSTART_NODE_TARGET_SPECIFIER,
95 options: { nitro: props.nitro },
96 }).pipe(Namespace.push(id));