Skip to content

Document JavaScript framework publish methods (PublishAsStaticWebsite, PublishAsNodeServer, PublishAsNpmScript, AddNextJsApp) #673

@davidfowl

Description

@davidfowl

Summary

PR microsoft/aspire#15736 added new JavaScript publish methods and AddNextJsApp to Aspire.Hosting.JavaScript. We need a comprehensive article covering how to use JavaScript frameworks with Aspire — from local development through deployment.

Proposed article: "Using JavaScript frameworks with Aspire"

Topics to cover

1. Framework categories and which publish method to use

Category Publish Method Frameworks Why
Static SPAs PublishAsStaticWebsite Vite, React, Vue, Angular, Astro (static) Build outputs static dist/ files, served by YARP
Self-contained Node servers PublishAsNodeServer SvelteKit, TanStack Start Build bundles everything, runs with node server.js
Node servers needing node_modules PublishAsNpmScript Nuxt, Remix, Astro SSR Runtime imports from node_modules
Next.js AddNextJsApp Next.js Standalone output with 3-COPY Dockerfile pattern

2. Local development (run mode)

  • AddViteApp vs AddJavaScriptApp vs AddNodeApp vs AddNextJsApp — when to use each
  • Port binding: how Aspire passes --port (Vite) vs -p (Next.js) to dev servers
  • Package managers: WithNpm(), WithYarn(), WithPnpm(), WithBun() — composable with all methods
  • WithOtlpExporter() — getting telemetry from JS apps into the Aspire dashboard

3. Publishing / Deployment

  • PublishAsStaticWebsite — YARP-based static file serving
    • Default behavior (SPA fallback, dist/ output)
    • outputPath for Angular (dist/browser) and other frameworks
    • API reverse-proxy with apiPath/apiTarget (solves CORS for SPAs)
    • StripPrefix option
    • TargetEndpointName for specific endpoint selection
  • PublishAsNodeServer — self-contained Node.js server
    • entryPoint and outputPath parameters
    • Framework-specific examples (SvelteKit build/index.js, TanStack .output/server/index.mjs)
  • PublishAsNpmScript — runtime with node_modules
    • When to use (Nuxt's useAsyncData, Remix's react-router-serve, Astro SSR's @astrojs/*)
    • startScriptName and runScriptArguments
  • AddNextJsApp — Next.js standalone
    • output: "standalone" in next.config.ts (required)
    • public/ directory requirement
    • Deploy-time validation and DisableBuildValidation()

4. Framework-specific gotchas

Based on aspire-js-chaos POC validation:

  • Nuxt: Pages must be under app/pages/, env vars need NUXT_ prefix for runtimeConfig
  • Astro SSR: Must set export const prerender = false, use process.env not import.meta.env
  • SvelteKit: Requires @sveltejs/adapter-node (default adapter-auto doesn't produce a deployable artifact)
  • Next.js: Must set output: "standalone", needs public/ directory
  • Angular: Uses dist/browser output path, not dist

5. Advanced scenarios

  • Custom base images via WithDockerfileBaseImage
  • PublishWithContainerFiles for embedding static files into a .NET server (existing pattern)
  • How to choose between PublishAsStaticWebsite + API proxy vs PublishWithContainerFiles

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions