diff --git a/docs/config/preview-options.md b/docs/config/preview-options.md index 32589a5091d12b..3604afb9576d42 100644 --- a/docs/config/preview-options.md +++ b/docs/config/preview-options.md @@ -75,3 +75,9 @@ Uses [`http-proxy`](https://github.com/http-party/node-http-proxy). Full options - **Default:** [`server.cors`](./server-options#server-cors) Configure CORS for the preview server. This is enabled by default and allows any origin. Pass an [options object](https://github.com/expressjs/cors) to fine tune the behavior or `false` to disable. + +## preview.headers + +- **Type:** `OutgoingHttpHeaders` + +Specify server response headers. diff --git a/packages/vite/src/node/preview.ts b/packages/vite/src/node/preview.ts index bebd212217d384..82640c3ff5c43c 100644 --- a/packages/vite/src/node/preview.ts +++ b/packages/vite/src/node/preview.ts @@ -111,12 +111,20 @@ export async function preview( // static assets const distDir = path.resolve(config.root, config.build.outDir) + const headers = config.preview.headers app.use( previewBase, sirv(distDir, { etag: true, dev: true, - single: config.appType === 'spa' + single: config.appType === 'spa', + setHeaders(res) { + if (headers) { + for (const name in headers) { + res.setHeader(name, headers[name]!) + } + } + } }) ) diff --git a/playground/fs-serve/__tests__/fs-serve.spec.ts b/playground/fs-serve/__tests__/fs-serve.spec.ts index 8fcb3f61125158..90d35d21b04773 100644 --- a/playground/fs-serve/__tests__/fs-serve.spec.ts +++ b/playground/fs-serve/__tests__/fs-serve.spec.ts @@ -1,3 +1,4 @@ +import fetch from 'node-fetch' import { beforeAll, describe, expect, test } from 'vitest' import testJSON from '../safe.json' import { isServe, page, viteTestUrl } from '~utils' @@ -97,3 +98,11 @@ describe.runIf(isServe)('main', () => { expect(await page.textContent('.unsafe-dotenv')).toBe('404') }) }) + +describe('fetch', () => { + // Note: this should pass in build too, but the test setup doesn't use Vite preview + test.runIf(isServe)('serve with configured headers', async () => { + const res = await fetch(viteTestUrl + '/src/') + expect(res.headers.get('x-served-by')).toBe('vite') + }) +}) diff --git a/playground/fs-serve/package.json b/playground/fs-serve/package.json index c50be06a8cb286..6a5d18e2303c53 100644 --- a/playground/fs-serve/package.json +++ b/playground/fs-serve/package.json @@ -6,6 +6,6 @@ "dev": "vite root", "build": "vite build root", "debug": "node --inspect-brk ../../packages/vite/bin/vite", - "preview": "vite preview" + "preview": "vite preview root" } } diff --git a/playground/fs-serve/root/vite.config.js b/playground/fs-serve/root/vite.config.js index 5712ad5acb3438..12d07754cbf10d 100644 --- a/playground/fs-serve/root/vite.config.js +++ b/playground/fs-serve/root/vite.config.js @@ -18,6 +18,14 @@ module.exports = { }, hmr: { overlay: false + }, + headers: { + 'x-served-by': 'vite' + } + }, + preview: { + headers: { + 'x-served-by': 'vite' } }, define: {