| 1 | import type { InputProps } from "../../Input.ts"; |
| 2 | import * as Namespace from "../../Namespace.ts"; |
| 3 | import { makeFrameworkSite, type FrameworkSiteProps } from "./FrameworkSite.ts"; |
| 4 | |
| 5 | /** The framework-integration package that drives the Nuxt build. */ |
| 6 | export const NUXT_FRAMEWORK_SPECIFIER = "@alchemy.run/frontend-frameworks/nuxt"; |
| 7 | |
| 8 | /** The AWS Lambda deploy target for the Nuxt build. */ |
| 9 | export const NUXT_AWS_TARGET_SPECIFIER = |
| 10 | "@alchemy.run/frontend-frameworks/nuxt/aws"; |
| 11 | |
| 12 | export 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 | */ |
| 92 | export 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 | }; |