♡ serve-placeholder
Smart placeholder for missing assets
Why?
Serving each 404 page for assets adds extra load to the server and increases crashing chances. This is crucial for setups with server-side-rendering and removes additional SSR loads when assets like robots.txt
or favicon.ico
don't exist.
We can always send a better 404 response than an HTML page by knowing file extensions. For example, we send a fallback transparent 1x1 image for image extensions.
Instead of indexing invalid URLs with HTML pages, we properly send 404 and the right content type.
Usage
Install package:
# npm
npm install serve-placeholder
# yarn
yarn install serve-placeholder
# pnpm
pnpm install serve-placeholder
Import:
// ESM
import { servePlaceholder } from 'serve-placeholder'
// CommonJS
const { servePlaceholder } = require('serve-placeholder')
Create and add server middleware between serve-static and router middleware:
app.use('/assets', serveStatic(..))
++ app.use('/assets', servePlaceholder())
app.use('/', router)
Additionally, we can have a default placeholder for arbitrary routes which handles known extensions assuming other routes have no extension:
app.use('/assets', serveStatic(..))
app.use('/assets', servePlaceholder())
++ app.use('/', placeholder({ skipUnknown: true }))
app.use('/', router)
Options
handlers
A mapping from file extensions to the handler. Extensions should start with dot like .js
.
You can disable any of the handlers by setting the value to null
If the value of a handler is set to false
, the middleware will be ignored for that extension.
statusCode
- Default:
404
Sets statusCode
for all handled responses. Set to false
to disable overriding statusCode.
skipUnknown
- Default:
false
Skip middleware when no handler is defined for the current request.
Please note that if this option is set to true
, then default
handler will be disabled!
placeholders
- Type:
Object
A mapping from handler to placeholder. Values can be String
or Buffer
. You can disable any of the placeholders by setting the value to false
.
mimes
- Type:
Object
A mapping from handler to the mime type. Mime type will be set as Content-Type
header. You can disable sending any of the mimes by setting the value to false
.
cacheHeaders
- Default:
true
Set headers to prevent accidentally caching 404 resources.
When enabled, these headers will be sent:
{
'cache-control': 'no-cache, no-store, must-revalidate',
'expires': '0',
'pragma': 'no-cache'
}
placeholderHeader
- Default:
true
Sets an X-Placeholder
header with value of handler name.
Defaults
These are default handlers. You can override every of them using provided options.
Handler | Extensions | Mime type | Placeholder |
---|---|---|---|
default |
any unknown extension | - | - |
css |
.css |
text/css |
/* style not found */ |
html |
.html , .htm |
text/html |
<!-- page not found --> |
js |
.js |
application/javascript |
/* script not found */ |
json |
.json |
application/json |
{} |
map |
.map |
application/json |
[empty sourcemap v3 json] |
plain |
.txt , .text , .md |
text/plain |
[empty] |
image |
.png , .jpg , .jpeg , .gif , .svg , .webp , .bmp , .ico |
image/gif |
[transparent 1x1 image] |
💻 Development
- Clone this repository
- Enable Corepack using
corepack enable
(usenpm i -g corepack
for Node.js < 16.10) - Install dependencies using
pnpm install
- Run interactive tests using
pnpm dev
License
Made with
Published under MIT License.