1import type { InputProps } from "../../Input.ts";
2import * as Namespace from "../../Namespace.ts";
3import { makeFrameworkSite, type FrameworkSiteProps } from "./FrameworkSite.ts";
4
5/** The framework-integration package that drives the Nuxt build. */
6export const NUXT_FRAMEWORK_SPECIFIER = "@alchemy.run/frontend-frameworks/nuxt";
7
8/** The AWS Lambda deploy target for the Nuxt build. */
9export const NUXT_AWS_TARGET_SPECIFIER =
10 "@alchemy.run/frontend-frameworks/nuxt/aws";
11
12export interface NuxtProps extends FrameworkSiteProps {
13 /**
14 * Nuxt config overrides merged over the project's own `nuxt.config.ts`
15 * (the highest-priority c12 layer — a value here wins over the file).
16 * Use it for deploy-time values the config file can't express, e.g.
17 * per-stage `runtimeConfig`; `nuxt.config.ts` remains the primary home
18 * for everything else.
19 *
20 * Must be JSON-serializable — no functions, plugins, or modules (the
21 * value persists in state and participates in the rebuild hash).
22 * `nitro.preset` is always owned by the deploy target and cannot be
23 * overridden here.
24 */
25 nuxt?: Record<string, unknown>;
26}
27
28/**
29 * Deploy a Nuxt application to AWS: the nitro server on a streaming Lambda
30 * Function URL, static assets (prerendered pages included) in S3, and a
31 * CloudFront distribution whose edge router serves uploaded files from S3
32 * and forwards everything else to the server.
33 *
34 * The build runs through `@alchemy.run/frontend-frameworks/nuxt` with the
35 * `@alchemy.run/frontend-frameworks/nuxt/aws` deploy target (nitro's `aws-lambda` preset,
36 * streaming enabled) — both must be installed in your project.
37 *
38 * ### Creating Nuxt Sites
39 * **Example:** Basic Nuxt App
40 * ```typescript
41 * const site = yield* AWS.Website.Nuxt("Web", {
42 * rootDir: "./app",
43 * });
44 * ```
45 *
46 * **Example:** Custom Domain
47 * ```typescript
48 * const site = yield* AWS.Website.Nuxt("Web", {
49 * rootDir: "./app",
50 * domain: {
51 * name: "app.example.com",
52 * hostedZoneId: zone.hostedZoneId,
53 * },
54 * });
55 * ```
56 *
57 * ### Server Configuration
58 * **Example:** Tune The Server Function
59 * ```typescript
60 * const site = yield* AWS.Website.Nuxt("Web", {
61 * rootDir: "./app",
62 * memorySize: 2048,
63 * env: {
64 * NUXT_PUBLIC_API_BASE: api.url,
65 * },
66 * });
67 * ```
68 *
69 * ### Config Overrides
70 * `nuxt.config.ts` is the primary home for Nuxt configuration — it loads
71 * natively. The `nuxt` prop layers deploy-time overrides on top (the
72 * highest-priority c12 layer) for values the file can't express, like
73 * per-stage settings. The bag must be JSON-serializable — no functions,
74 * plugins, or modules — and `nitro.preset` stays owned by the deploy
75 * target.
76 *
77 * **Example:** Deploy-time config overrides
78 * ```typescript
79 * const site = yield* AWS.Website.Nuxt("Web", {
80 * rootDir: "./app",
81 * nuxt: {
82 * app: { baseURL: "/docs/" },
83 * runtimeConfig: {
84 * public: { apiBase: "https://api.example.com" },
85 * },
86 * },
87 * });
88 * ```
89 *
90 * @resource
91 */
92export const Nuxt = (id: string, props: InputProps<NuxtProps> = {}) => {
93 const p = props as NuxtProps;
94 return makeFrameworkSite(id, props, {
95 name: "Nuxt",
96 framework: NUXT_FRAMEWORK_SPECIFIER,
97 target: NUXT_AWS_TARGET_SPECIFIER,
98 options: p.nuxt !== undefined ? { nuxt: p.nuxt } : undefined,
99 }).pipe(Namespace.push(id));
100};