h3 icon indicating copy to clipboard operation
h3 copied to clipboard

support for serving static files

Open mirabledictu opened this issue 2 years ago • 1 comments

Hi, is there an equivalent of

app.use(express.static(`${root}/dist/client`, { index: false }))

in h3? Thanks

mirabledictu avatar Sep 03 '21 06:09 mirabledictu

@mirabledictu You can use the serve-static package.

import serveStatic from 'serve-static'

// Available from /
app.use(serveStatic(`${root}/dist/client`))

// Available from /prefix
app.use('/prefix', serveStatic(`${root}/dist/client`))

mvrlin avatar Nov 06 '21 09:11 mvrlin

@mvrlin Unfortunately, its 2022 & still not working

navicstein avatar Nov 15 '22 13:11 navicstein

Please try using https://github.com/unjs/nitro for supporting static asset serving and many more benefits on top of h3.

h3 aims to be a platform-independent framework and it is not easy to provide a solution that works out of the box without depending on node fs.

Thinking about integration with unstorage for static asset support (pending for https://github.com/unjs/unstorage/issues/21).

pi0 avatar Nov 15 '22 13:11 pi0

For people stumbling upon this issue, here is the current way to leverage serve-static:

import { createApp, fromNodeMiddleware } from 'h3'
import serveStatic from 'serve-static'

const app = createApp()

// Available from /
app.use(fromNodeMiddleware(serveStatic(`${root}/dist/client`)))

// Available from /prefix
app.use('/prefix', fromNodeMiddleware(serveStatic(`${root}/dist/client`)))

magne4000 avatar Sep 28 '23 14:09 magne4000

app.use(fromNodeMiddleware(serveStatic(`${root}/dist/client`)))

@magne4000 something not work, i try with nitroApp.h3App.use()

imcm7 avatar Dec 04 '23 18:12 imcm7

I was able to use the built-in serveStatic like this-

let staticHandler = h3.eventHandler(async (event) => {
    let dir = import.meta.resolve('./static')
    await h3.serveStatic(event, {
        fallthrough: true,
        indexNames: undefined,
        getContents: (id) => readFile(new URL(dir + id)),
        getMeta: async (id) => {
            const stats = await stat(new URL(dir + id)).catch(console.warn);
            if (!stats || !stats.isFile()) {
                return;
            }
            return {
                size: stats.size,
                mtime: stats.mtimeMs,
            };
        },
    });
})

app.use("/", staticHandler)

gulshan avatar Jan 02 '24 02:01 gulshan

app.use doesn't work indeed, but luckily there is a workaround:

import serveStatic from "serve-static"

export default defineNitroPlugin((nitroApp) => {
  nitroApp.h3App.stack.unshift({
    route: "/uploads",
    handler: fromNodeMiddleware(serveStatic("./uploads", { immutable: true })),
  })
})

IlyaSemenov avatar Mar 12 '24 10:03 IlyaSemenov