Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions packages/dev/src/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1062,4 +1062,94 @@ describe('Handling requests', () => {
await fixture.destroy()
})
})

describe('Static file serving', () => {
test('Serves static files from given `staticFiles.directories` only', async () => {
const fixture = new Fixture()
.withFile(
'netlify.toml',
`[build]
publish = "dist"
`,
)
.withFile('dist/index.html', `from dist`)
.withFile('custom-static/app.css', `from custom-static`)
.withFile('another-static/script.js', `from another-static`)
const directory = await fixture.create()

const dev = new NetlifyDev({
projectRoot: directory,
edgeFunctions: {},
geolocation: {
enabled: false,
},
staticFiles: {
directories: [`${directory}/custom-static`, `${directory}/another-static`],
},
})
await dev.start()

const customStaticRes = await dev.handle(new Request('https://site.netlify/app.css'))
expect(await customStaticRes?.text()).toBe('from custom-static')
const anotherStaticRes = await dev.handle(new Request('https://site.netlify/script.js'))
expect(await anotherStaticRes?.text()).toBe('from another-static')
const publishDirRes = await dev.handle(new Request('https://site.netlify/index.html'))
expect(publishDirRes).toBeUndefined()

await dev.stop()
await fixture.destroy()
})

test('Falls back to publish directory when no custom directories provided', async () => {
const fixture = new Fixture()
.withFile(
'netlify.toml',
`[build]
publish = "public"
`,
)
.withFile('public/index.html', `from public`)
.withFile('public/style.css', `from public css`)
const directory = await fixture.create()

const dev = new NetlifyDev({
projectRoot: directory,
edgeFunctions: {},
geolocation: {
enabled: false,
},
})
await dev.start()

const publishDirRes1 = await dev.handle(new Request('https://site.netlify/index.html'))
expect(await publishDirRes1?.text()).toBe('from public')
const publishDirRes2 = await dev.handle(new Request('https://site.netlify/style.css'))
expect(await publishDirRes2?.text()).toBe('from public css')

await dev.stop()
await fixture.destroy()
})

test('Uses project root when no publish directory configured and no custom directories provided', async () => {
const fixture = new Fixture().withFile('index.html', `from root`).withFile('app.js', `from root js`)
const directory = await fixture.create()

const dev = new NetlifyDev({
projectRoot: directory,
edgeFunctions: {},
geolocation: {
enabled: false,
},
})
await dev.start()

const projectRootRes1 = await dev.handle(new Request('https://site.netlify/index.html'))
expect(await projectRootRes1?.text()).toBe('from root')
const projectRootRes2 = await dev.handle(new Request('https://site.netlify/app.js'))
expect(await projectRootRes2?.text()).toBe('from root js')

await dev.stop()
await fixture.destroy()
})
})
})
17 changes: 9 additions & 8 deletions packages/dev/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ export interface Features {
enabled?: boolean

/**
* Additional list of directories where static files can be found. The
* `publish` directory configured on your site will be used automatically.
* List of directories where static files can be found. If not provided,
* the `publish` directory configured on your Netlify project will be used automatically.
*/
directories?: string[]
}
Expand Down Expand Up @@ -196,7 +196,7 @@ export class NetlifyDev {
#serverAddress?: string | null
#siteID?: string
#staticHandler?: StaticHandler
#staticHandlerAdditionalDirectories: string[]
#staticHandlerDirectories?: string[]

constructor(options: NetlifyDevOptions) {
if (options.apiURL) {
Expand Down Expand Up @@ -227,7 +227,7 @@ export class NetlifyDev {
this.#logger = options.logger ?? globalThis.console
this.#serverAddress = options.serverAddress
this.#projectRoot = projectRoot
this.#staticHandlerAdditionalDirectories = options.staticFiles?.directories ?? []
this.#staticHandlerDirectories = options.staticFiles?.directories ?? undefined
}

private getServerAddress(requestServerAddress?: string) {
Expand Down Expand Up @@ -582,11 +582,12 @@ export class NetlifyDev {
}

if (this.#features.static) {
// If custom static directories are provided (e.g., by `@netlify/vite-plugin` or `@netlify/nuxt`),
// use those directories. Otherwise, use the build.publish directory from config.
const directories = this.#staticHandlerDirectories ?? [this.#config?.config.build.publish ?? this.#projectRoot]

this.#staticHandler = new StaticHandler({
directory: [
this.#config?.config.build.publish ?? this.#projectRoot,
...this.#staticHandlerAdditionalDirectories,
],
directory: directories,
})
}

Expand Down
Loading