# Build a marketing site with Astro (/docs/guides/compute/astro-marketing-site) > For the complete Prisma documentation index, see [llms.txt](https://www.prisma.io/docs/llms.txt). A markdown version of any docs page is available by appending `.md` to its URL. Build a static marketing site with Astro, serve it from a Node server, and deploy it to Prisma Compute with Prisma Composer. Location: Guides > Build on Compute > Build a marketing site with Astro ## Introduction [#introduction] This guide builds a small marketing site with [Astro](https://astro.build) (a home page, a pricing page, and an about page) and deploys it to [Prisma Compute](https://www.prisma.io/docs/compute). Every page is rendered to static HTML at build time, so the site needs no database and no Prisma ORM. Compute runs a server process, not a folder of files. The one Astro-specific step is adding the Node adapter, which keeps your pages static and adds a small server that serves them. Every command below was run end to end, including the deploy. ## Prerequisites [#prerequisites] * [Node.js](https://nodejs.org) 24 or later * A [Prisma Data Platform account](https://pris.ly/pdp), free to create. You only need it for the deploy step. ## 1. Scaffold the site [#1-scaffold-the-site] Create an Astro project from the minimal template: #### bun ```bash bun create astro@latest marketing-site --template minimal --install --no-git --yes cd marketing-site ``` #### pnpm ```bash pnpm create astro@latest marketing-site --template minimal --install --no-git --yes cd marketing-site ``` #### yarn ```bash yarn create astro@latest marketing-site --template minimal --install --no-git --yes cd marketing-site ``` #### npm ```bash npm create astro@latest -- marketing-site --template minimal --install --no-git --yes cd marketing-site ``` ```text no-copy ✔ Project initialized! ■ Template copied ■ Dependencies installed next Liftoff confirmed. Explore your project! ``` The template gives you one page, `src/pages/index.astro`, and an empty `astro.config.mjs`. ## 2. Build the pages [#2-build-the-pages] Add a shared layout with the header and navigation every page uses: ```astro title="src/layouts/Base.astro" --- interface Props { title: string; description: string; } const { title, description } = Astro.props; ---
Everything your team needs to go from idea to production.
See pricing ``` ```astro title="src/pages/pricing.astro" --- import Base from "../layouts/Base.astro"; const plans = [ { name: "Starter", price: "$0", blurb: "For side projects." }, { name: "Team", price: "$29", blurb: "For growing teams." }, ]; ---We build tools for teams that ship.
``` Run `npm run dev` and open [http://localhost:4321](http://localhost:4321) to check the pages, then stop the dev server. ## 3. Add the Node adapter [#3-add-the-node-adapter] Compute needs a server entrypoint to run. A plain Astro build only produces HTML files, so add the Node adapter in standalone mode: #### bun ```bash bunx astro add node --yes ``` #### pnpm ```bash pnpm dlx astro add node --yes ``` #### yarn ```bash yarn dlx astro add node --yes ``` #### npm ```bash npx astro add node --yes ``` ```js title="astro.config.mjs" // @ts-check import { defineConfig } from 'astro/config'; import node from '@astrojs/node'; // https://astro.build/config export default defineConfig({ adapter: node({ mode: 'standalone' }) }); ``` Leave `output` unset. It defaults to `"static"`, so every page is still rendered at build time. The adapter adds a server that serves those files. Build to confirm: #### bun ```bash bun run build ``` #### pnpm ```bash pnpm run build ``` #### yarn ```bash yarn build ``` #### npm ```bash npm run build ``` ```text no-copy [build] output: "static" [build] mode: "server" [build] adapter: @astrojs/node [build] Building server entrypoints... prerendering static routes ├─ /about/index.html (+7ms) ├─ /pricing/index.html (+3ms) ├─ /index.html (+4ms) ✓ Completed in 50ms. [build] Server built in 815ms [build] Complete! ``` The pages land in `dist/client/` and the server lands in `dist/server/entry.mjs`. Compute runs that server. ## 4. Declare the app with Prisma Composer [#4-declare-the-app-with-prisma-composer] [Prisma Composer](https://www.prisma.io/docs/composer) describes what to deploy. Install it, plus the Prisma CLI as a dev dependency: #### bun ```bash bun add @prisma/composer @prisma/composer-prisma-cloud bun add --dev prisma ``` #### pnpm ```bash pnpm add @prisma/composer @prisma/composer-prisma-cloud pnpm add -D prisma ``` #### yarn ```bash yarn add @prisma/composer @prisma/composer-prisma-cloud yarn add --dev prisma ``` #### npm ```bash npm install @prisma/composer @prisma/composer-prisma-cloud npm install -D prisma ``` Declare the service and point it at the Astro server entry. `dir` is the build output directory, and `entry` is the server file inside it: ```ts title="service.ts" import node from "@prisma/composer/node"; import { compute } from "@prisma/composer-prisma-cloud"; export default compute({ name: "web", deps: {}, build: node({ module: import.meta.url, dir: "./dist", entry: "server/entry.mjs" }), }); ``` The root module is the app. Its name becomes the project name on Compute: ```ts title="module.ts" import { module } from "@prisma/composer"; import web from "./service.ts"; export default module("marketing-site", ({ provision }) => { provision(web); }); ``` The deploy config tells the CLI where to deploy. The `region` applies when the first deploy creates the project: ```ts title="prisma.config.ts" import { defineConfig as composer } from "@prisma/composer/config"; import { nodeBuild } from "@prisma/composer/node/control"; import { prismaCloud, prismaState } from "@prisma/composer-prisma-cloud/control"; import { definePrismaConfig } from "prisma/config"; export default definePrismaConfig({ composer: composer({ extensions: [prismaCloud({ region: "us-east-1" }), nodeBuild()], state: prismaState(), }), }); ``` Composer writes local state to `.alchemy/` and `.prisma-composer/`. Add both to `.gitignore`: ```bash title=".gitignore" /.alchemy /.prisma-composer ``` ## 5. Run it locally [#5-run-it-locally] Run the built site the way Compute will. No account is needed: #### bun ```bash bun run build bunx prisma dev module.ts ``` #### pnpm ```bash pnpm run build pnpm prisma dev module.ts ``` #### yarn ```bash yarn build yarn prisma dev module.ts ``` #### npm ```bash npm run build npx prisma dev module.ts ``` ```text no-copy dev: ready web: http://localhost:3000 ``` `dev` keeps running. From a second terminal in the same directory, check each route. `prisma dev url web` prints the URL of the `web` service, whichever port it got: ```bash curl -s -o /dev/null -w "%{http_code}\n" "$(npx prisma dev url web)/pricing" ``` ```text no-copy 200 ``` Composer hands the server its port, so you do not set `PORT` or `HOST` yourself. Stop `dev` with `Ctrl+C`. ## 6. Deploy to Prisma Compute [#6-deploy-to-prisma-compute] Sign in once. It opens your browser: #### bun ```bash bunx prisma auth login ``` #### pnpm ```bash pnpm prisma auth login ``` #### yarn ```bash yarn prisma auth login ``` #### npm ```bash npx prisma auth login ``` Then build and deploy: #### bun ```bash bun run build bunx prisma deploy module.ts ``` #### pnpm ```bash pnpm run build pnpm prisma deploy module.ts ``` #### yarn ```bash yarn build yarn prisma deploy module.ts ``` #### npm ```bash npm run build npx prisma deploy module.ts ``` ```text no-copy Plan: 4 to create, 1 tasks ... marketing-site └─ web compute-service cps_abc123 https://abc123.ewr.prisma.build ... Done: 5 succeeded (16.8s) ``` The deploy creates a project named `marketing-site` in your workspace and prints the live URL. If a project with that name already exists and its deploy state cannot be verified, the deploy stops with `HostedStateBootstrapError`; rename the module in `module.ts` or pass `--name