; rel="last"
+```
diff --git a/astro/src/content/api/4x/api/response/res-locals.md b/astro/src/content/api/4x/api/response/res-locals.md
new file mode 100644
index 0000000000..b15e2558c9
--- /dev/null
+++ b/astro/src/content/api/4x/api/response/res-locals.md
@@ -0,0 +1,33 @@
+---
+title: res.locals
+description: Use this property to set variables accessible in templates rendered with [res.render](#res.render).
+---
+
+res.locals
+
+Use this property to set variables accessible in templates rendered with [res.render](#res.render).
+The variables set on `res.locals` are available within a single request-response cycle, and will not
+be shared between requests.
+
+
+The `locals` object is used by view engines to render a response. The object
+keys may be particularly sensitive and should not contain user-controlled
+input, as it may affect the operation of the view engine or provide a path to
+cross-site scripting. Consult the documentation for the used view engine for
+additional considerations.
+
+
+In order to keep local variables for use in template rendering between requests, use
+[app.locals](#app.locals) instead.
+
+This property is useful for exposing request-level information such as the request path name,
+authenticated user, user settings, and so on to templates rendered within the application.
+
+```js
+app.use(function (req, res, next) {
+ // Make `user` and `authenticated` available in templates
+ res.locals.user = req.user;
+ res.locals.authenticated = !req.user.anonymous;
+ next();
+});
+```
diff --git a/astro/src/content/api/4x/api/response/res-location.md b/astro/src/content/api/4x/api/response/res-location.md
new file mode 100644
index 0000000000..537a0532d8
--- /dev/null
+++ b/astro/src/content/api/4x/api/response/res-location.md
@@ -0,0 +1,30 @@
+---
+title: res.location
+description: Sets the response Location HTTP header to the specified path parameter.
+---
+
+res.location(path)
+
+Sets the response `Location` HTTP header to the specified `path` parameter.
+
+```js
+res.location('/foo/bar');
+res.location('http://example.com');
+res.location('back');
+```
+
+{% include admonitions/note.html content="`'back'` was deprecated in 4.21.0, use `req.get('Referrer') || '/'` as an argument instead." %}
+
+A `path` value of "back" has a special meaning, it refers to the URL specified in the `Referer` header of the request. If the `Referer` header was not specified, it refers to "/".
+
+See also [Security best practices: Prevent open redirect
+vulnerabilities](http://expressjs.com/en/advanced/best-practice-security#prevent-open-redirects).
+
+
+After encoding the URL, if not encoded already, Express passes the specified URL to the browser in the `Location` header,
+without any validation.
+
+Browsers take the responsibility of deriving the intended URL from the current URL
+or the referring URL, and the URL specified in the `Location` header; and redirect the user accordingly.
+
+
diff --git a/astro/src/content/api/4x/api/response/res-redirect.md b/astro/src/content/api/4x/api/response/res-redirect.md
new file mode 100644
index 0000000000..0acffcea95
--- /dev/null
+++ b/astro/src/content/api/4x/api/response/res-redirect.md
@@ -0,0 +1,65 @@
+---
+title: res.redirect
+description: Redirects to the URL derived from the specified path, with specified status, a positive integer
+---
+
+res.redirect([status,] path)
+
+Redirects to the URL derived from the specified `path`, with specified `status`, a positive integer
+that corresponds to an [HTTP status code](https://www.rfc-editor.org/rfc/rfc9110#name-status-codes) .
+If not specified, `status` defaults to "302 "Found".
+
+```js
+res.redirect('/foo/bar');
+res.redirect('http://example.com');
+res.redirect(301, 'http://example.com');
+res.redirect('../login');
+```
+
+Redirects can be a fully-qualified URL for redirecting to a different site:
+
+```js
+res.redirect('http://google.com');
+```
+
+Redirects can be relative to the root of the host name. For example, if the
+application is on `http://example.com/admin/post/new`, the following
+would redirect to the URL `http://example.com/admin`:
+
+```js
+res.redirect('/admin');
+```
+
+Redirects can be relative to the current URL. For example,
+from `http://example.com/blog/admin/` (notice the trailing slash), the following
+would redirect to the URL `http://example.com/blog/admin/post/new`.
+
+```js
+res.redirect('post/new');
+```
+
+Redirecting to `post/new` from `http://example.com/blog/admin` (no trailing slash),
+will redirect to `http://example.com/blog/post/new`.
+
+If you found the above behavior confusing, think of path segments as directories
+(with trailing slashes) and files, it will start to make sense.
+
+Path-relative redirects are also possible. If you were on
+`http://example.com/admin/post/new`, the following would redirect to
+`http://example.com/admin/post`:
+
+```js
+res.redirect('..');
+```
+
+A `back` redirection redirects the request back to the [referer](http://en.wikipedia.org/wiki/HTTP_referer),
+defaulting to `/` when the referer is missing.
+
+```js
+res.redirect('back');
+```
+
+{% include admonitions/note.html content="`back` redirect was deprecated in 4.21.0, use `req.get('Referrer') || '/'` as an argument instead." %}
+
+See also [Security best practices: Prevent open redirect
+vulnerabilities](http://expressjs.com/en/advanced/best-practice-security#prevent-open-redirects).
diff --git a/astro/src/content/api/4x/api/response/res-render.md b/astro/src/content/api/4x/api/response/res-render.md
new file mode 100644
index 0000000000..9a829d8348
--- /dev/null
+++ b/astro/src/content/api/4x/api/response/res-render.md
@@ -0,0 +1,50 @@
+---
+title: res.render
+description: Renders a view and sends the rendered HTML string to the client.
+---
+
+res.render(view [, locals] [, callback])
+
+Renders a `view` and sends the rendered HTML string to the client.
+Optional parameters:
+
+- `locals`, an object whose properties define local variables for the view.
+- `callback`, a callback function. If provided, the method returns both the possible error and rendered string, but does not perform an automated response. When an error occurs, the method invokes `next(err)` internally.
+
+The `view` argument is a string that is the file path of the view file to render. This can be an absolute path, or a path relative to the `views` setting. If the path does not contain a file extension, then the `view engine` setting determines the file extension. If the path does contain a file extension, then Express will load the module for the specified template engine (via `require()`) and render it using the loaded module's `__express` function.
+
+For more information, see [Using template engines with Express](/en/guide/using-template-engines).
+
+
+The `view` argument performs file system operations like reading a file from
+disk and evaluating Node.js modules, and as so for security reasons should not
+contain input from the end-user.
+
+
+
+The `locals` object is used by view engines to render a response. The object
+keys may be particularly sensitive and should not contain user-controlled
+input, as it may affect the operation of the view engine or provide a path to
+cross-site scripting. Consult the documentation for the used view engine for
+additional considerations.
+
+
+
+The local variable `cache` enables view caching. Set it to `true`,
+to cache the view during development; view caching is enabled in production by default.
+
+
+```js
+// send the rendered view to the client
+res.render('index');
+
+// if a callback is specified, the rendered HTML string has to be sent explicitly
+res.render('index', function (err, html) {
+ res.send(html);
+});
+
+// pass a local variable to the view
+res.render('user', { name: 'Tobi' }, function (err, html) {
+ // ...
+});
+```
diff --git a/astro/src/content/api/4x/api/response/res-req.md b/astro/src/content/api/4x/api/response/res-req.md
new file mode 100644
index 0000000000..f20548a045
--- /dev/null
+++ b/astro/src/content/api/4x/api/response/res-req.md
@@ -0,0 +1,9 @@
+---
+title: res.req
+description: This property holds a reference to the
+---
+
+res.req
+
+This property holds a reference to the request object
+that relates to this response object.
diff --git a/astro/src/content/api/4x/api/response/res-send.md b/astro/src/content/api/4x/api/response/res-send.md
new file mode 100644
index 0000000000..c7fc23dff6
--- /dev/null
+++ b/astro/src/content/api/4x/api/response/res-send.md
@@ -0,0 +1,44 @@
+---
+title: res.send
+description: Sends the HTTP response.
+---
+
+res.send([body])
+
+Sends the HTTP response.
+
+The `body` parameter can be a `Buffer` object, a `String`, an object, `Boolean`, or an `Array`.
+For example:
+
+```js
+res.send(Buffer.from('whoop'));
+res.send({ some: 'json' });
+res.send('some html
');
+res.status(404).send('Sorry, we cannot find that!');
+res.status(500).send({ error: 'something blew up' });
+```
+
+This method performs many useful tasks for simple non-streaming responses:
+For example, it automatically assigns the `Content-Length` HTTP response header field
+(unless previously defined) and provides automatic HEAD and HTTP cache freshness support.
+
+When the parameter is a `Buffer` object, the method sets the `Content-Type`
+response header field to "application/octet-stream", unless previously defined as shown below:
+
+```js
+res.set('Content-Type', 'text/html');
+res.send(Buffer.from('some html
'));
+```
+
+When the parameter is a `String`, the method sets the `Content-Type` to "text/html":
+
+```js
+res.send('some html
');
+```
+
+When the parameter is an `Array` or `Object`, Express responds with the JSON representation:
+
+```js
+res.send({ user: 'tobi' });
+res.send([1, 2, 3]);
+```
diff --git a/astro/src/content/api/4x/api/response/res-sendFile.md b/astro/src/content/api/4x/api/response/res-sendFile.md
new file mode 100644
index 0000000000..65c5ca3627
--- /dev/null
+++ b/astro/src/content/api/4x/api/response/res-sendFile.md
@@ -0,0 +1,91 @@
+---
+title: res.sendFile
+description: Transfers the file at the given path. Sets the Content-Type response HTTP header field based on the filename extension
+---
+
+res.sendFile(path [, options] [, fn])
+
+
+`res.sendFile()` is supported by Express v4.8.0 onwards.
+
+
+Transfers the file at the given `path`. Sets the `Content-Type` response HTTP header field
+based on the filename's extension. Unless the `root` option is set in
+the options object, `path` must be an absolute path to the file.
+
+
+This API provides access to data on the running file system. Ensure that either (a) the way in
+which the `path` argument was constructed into an absolute path is secure if it contains user
+input or (b) set the `root` option to the absolute path of a directory to contain access within.
+
+When the `root` option is provided, the `path` argument is allowed to be a relative path,
+including containing `..`. Express will validate that the relative path provided as `path` will
+resolve within the given `root` option.
+
+
+
+The following table provides details on the `options` parameter.
+
+
+
+| Property | Description | Default | Availability |
+| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------ |
+| `maxAge` | Sets the max-age property of the `Cache-Control` header in milliseconds or a string in [ms format](https://www.npmjs.org/package/ms) | 0 | |
+| `root` | Root directory for relative filenames. | | |
+| `lastModified` | Sets the `Last-Modified` header to the last modified date of the file on the OS. Set `false` to disable it. | Enabled | 4.9.0+ |
+| `headers` | Object containing HTTP headers to serve with the file. | | |
+| `dotfiles` | Option for serving dotfiles. Possible values are "allow", "deny", "ignore". | "ignore" | |
+| `acceptRanges` | Enable or disable accepting ranged requests. | `true` | 4.14+ |
+| `cacheControl` | Enable or disable setting `Cache-Control` response header. | `true` | 4.14+ |
+| `immutable` | Enable or disable the `immutable` directive in the `Cache-Control` response header. If enabled, the `maxAge` option should also be specified to enable caching. The `immutable` directive will prevent supported clients from making conditional requests during the life of the `maxAge` option to check if the file has changed. | `false` | 4.16+ |
+
+
+
+The method invokes the callback function `fn(err)` when the transfer is complete
+or when an error occurs. If the callback function is specified and an error occurs,
+the callback function must explicitly handle the response process either by
+ending the request-response cycle, or by passing control to the next route.
+
+Here is an example of using `res.sendFile` with all its arguments.
+
+```js
+app.get('/file/:name', function (req, res, next) {
+ var options = {
+ root: path.join(__dirname, 'public'),
+ dotfiles: 'deny',
+ headers: {
+ 'x-timestamp': Date.now(),
+ 'x-sent': true,
+ },
+ };
+
+ var fileName = req.params.name;
+ res.sendFile(fileName, options, function (err) {
+ if (err) {
+ next(err);
+ } else {
+ console.log('Sent:', fileName);
+ }
+ });
+});
+```
+
+The following example illustrates using
+`res.sendFile` to provide fine-grained support for serving files:
+
+```js
+app.get('/user/:uid/photos/:file', function (req, res) {
+ var uid = req.params.uid;
+ var file = req.params.file;
+
+ req.user.mayViewFilesFrom(uid, function (yes) {
+ if (yes) {
+ res.sendFile('/uploads/' + uid + '/' + file);
+ } else {
+ res.status(403).send("Sorry! You can't see that.");
+ }
+ });
+});
+```
+
+For more information, or if you have issues or concerns, see [send](https://github.com/pillarjs/send).
diff --git a/astro/src/content/api/4x/api/response/res-sendStatus.md b/astro/src/content/api/4x/api/response/res-sendStatus.md
new file mode 100644
index 0000000000..eef217cd82
--- /dev/null
+++ b/astro/src/content/api/4x/api/response/res-sendStatus.md
@@ -0,0 +1,20 @@
+---
+title: res.sendStatus
+description: Sets the response HTTP status code to statusCode and sends the registered status message as the text response body. If an unknown status code is specified, the response body will be just the code number.
+---
+
+res.sendStatus(statusCode)
+
+Sets the response HTTP status code to `statusCode` and sends the registered status message as the text response body. If an unknown status code is specified, the response body will just be the code number.
+
+```js
+res.sendStatus(404);
+```
+
+
+Some versions of Node.js will throw when `res.statusCode` is set to an
+invalid HTTP status code (outside of the range `100` to `599`). Consult
+the HTTP server documentation for the Node.js version being used.
+
+
+[More about HTTP Status Codes](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
diff --git a/astro/src/content/api/4x/api/response/res-set.md b/astro/src/content/api/4x/api/response/res-set.md
new file mode 100644
index 0000000000..6d2b01e63e
--- /dev/null
+++ b/astro/src/content/api/4x/api/response/res-set.md
@@ -0,0 +1,21 @@
+---
+title: res.set
+description: Sets the response HTTP header field to value.
+---
+
+res.set(field [, value])
+
+Sets the response's HTTP header `field` to `value`.
+To set multiple fields at once, pass an object as the parameter.
+
+```js
+res.set('Content-Type', 'text/plain');
+
+res.set({
+ 'Content-Type': 'text/plain',
+ 'Content-Length': '123',
+ ETag: '12345',
+});
+```
+
+Aliased as `res.header(field [, value])`.
diff --git a/astro/src/content/api/4x/api/response/res-status.md b/astro/src/content/api/4x/api/response/res-status.md
new file mode 100644
index 0000000000..445fed30fb
--- /dev/null
+++ b/astro/src/content/api/4x/api/response/res-status.md
@@ -0,0 +1,15 @@
+---
+title: res.status
+description: Sets the HTTP status for the response.
+---
+
+res.status(code)
+
+Sets the HTTP status for the response.
+It is a chainable alias of Node's [response.statusCode](https://nodejs.org/api/http.html#http_response_statuscode).
+
+```js
+res.status(403).end();
+res.status(400).send('Bad Request');
+res.status(404).sendFile('/absolute/path/to/404.png');
+```
diff --git a/astro/src/content/api/4x/api/response/res-type.md b/astro/src/content/api/4x/api/response/res-type.md
new file mode 100644
index 0000000000..615ffb3c6a
--- /dev/null
+++ b/astro/src/content/api/4x/api/response/res-type.md
@@ -0,0 +1,23 @@
+---
+title: res.type
+description: Sets the Content-Type HTTP header to the MIME type as determined by the specified type. If type contains the slash character, then it sets the Content-Type to the exact value.
+---
+
+res.type(type)
+
+Sets the `Content-Type` HTTP header to the MIME type as determined by the specified `type`. If `type` contains the "/" character, then it sets the `Content-Type` to the exact value of `type`, otherwise it is assumed to be a file extension and the MIME type is looked up in a mapping using the `express.static.mime.lookup()` method.
+
+```js
+res.type('.html');
+// => 'text/html'
+res.type('html');
+// => 'text/html'
+res.type('json');
+// => 'application/json'
+res.type('application/json');
+// => 'application/json'
+res.type('png');
+// => 'image/png'
+```
+
+Aliased as `res.contentType(type)`.
diff --git a/astro/src/content/api/4x/api/response/res-vary.md b/astro/src/content/api/4x/api/response/res-vary.md
new file mode 100644
index 0000000000..164bed9285
--- /dev/null
+++ b/astro/src/content/api/4x/api/response/res-vary.md
@@ -0,0 +1,12 @@
+---
+title: res.vary
+description: Adds the field to the Vary response header, if it is not there already.
+---
+
+res.vary(field)
+
+Adds the field to the `Vary` response header, if it is not there already.
+
+```js
+res.vary('User-Agent').render('docs');
+```
diff --git a/astro/src/content/api/4x/api/router/overview.md b/astro/src/content/api/4x/api/router/overview.md
new file mode 100644
index 0000000000..9d1ec07241
--- /dev/null
+++ b/astro/src/content/api/4x/api/router/overview.md
@@ -0,0 +1,66 @@
+---
+title: Methods
+description: section markdown="1">
+---
+
+Router
+
+
+A `router` object is an instance of middleware and routes. You can think of it
+as a "mini-application," capable only of performing middleware and routing
+functions. Every Express application has a built-in app router.
+
+A router behaves like middleware itself, so you can use it as an argument to
+[app.use()](#app.use) or as the argument to another router's [use()](#router.use) method.
+
+The top-level `express` object has a [Router()](#express.router) method that creates a new `router` object.
+
+Once you've created a router object, you can add middleware and HTTP method routes (such as `get`, `put`, `post`,
+and so on) to it just like an application. For example:
+
+```js
+// invoked for any requests passed to this router
+router.use(function (req, res, next) {
+ // .. some logic here .. like any other middleware
+ next();
+});
+
+// will handle any request that ends in /events
+// depends on where the router is "use()'d"
+router.get('/events', function (req, res, next) {
+ // ..
+});
+```
+
+You can then use a router for a particular root URL in this way separating your routes into files or even mini-apps.
+
+```js
+// only requests to /calendar/* will be sent to our "router"
+app.use('/calendar', router);
+```
+
+Keep in mind that any middleware applied to a router will run for all requests on that router's path, even those that aren't part of the router.
+
+
+
+Methods
+
+
+ {% include api/en/4x/router-all.md %}
+
+
+
+ {% include api/en/4x/router-METHOD.md %}
+
+
+
+ {% include api/en/4x/router-param.md %}
+
+
+
+ {% include api/en/4x/router-route.md %}
+
+
+
+ {% include api/en/4x/router-use.md %}
+
diff --git a/astro/src/content/api/4x/api/router/router-METHOD.md b/astro/src/content/api/4x/api/router/router-METHOD.md
new file mode 100644
index 0000000000..2c6ea555f4
--- /dev/null
+++ b/astro/src/content/api/4x/api/router/router-METHOD.md
@@ -0,0 +1,47 @@
+---
+title: router.METHOD
+description: The router.METHOD methods provide the routing functionality in Express,
+---
+
+router.METHOD(path, [callback, ...] callback)
+
+The `router.METHOD()` methods provide the routing functionality in Express,
+where METHOD is one of the HTTP methods, such as GET, PUT, POST, and so on,
+in lowercase. Thus, the actual methods are `router.get()`, `router.post()`,
+`router.put()`, and so on.
+
+
+ The `router.get()` function is automatically called for the HTTP `HEAD` method in
+ addition to the `GET` method if `router.head()` was not called for the
+ path before `router.get()`.
+
+
+You can provide multiple callbacks, and all are treated equally, and behave just
+like middleware, except that these callbacks may invoke `next('route')`
+to bypass the remaining route callback(s). You can use this mechanism to perform
+pre-conditions on a route then pass control to subsequent routes when there is no
+reason to proceed with the route matched.
+
+The following snippet illustrates the most simple route definition possible.
+Express translates the path strings to regular expressions, used internally
+to match incoming requests. Query strings are _not_ considered when performing
+these matches, for example "GET /" would match the following route, as would
+"GET /?name=tobi".
+
+```js
+router.get('/', function (req, res) {
+ res.send('hello world');
+});
+```
+
+You can also use regular expressions—useful if you have very specific
+constraints, for example the following would match "GET /commits/71dbb9c" as well
+as "GET /commits/71dbb9c..4c084f9".
+
+```js
+router.get(/^\/commits\/(\w+)(?:\.\.(\w+))?$/, function (req, res) {
+ var from = req.params[0];
+ var to = req.params[1] || 'HEAD';
+ res.send('commit range ' + from + '..' + to);
+});
+```
diff --git a/astro/src/content/api/4x/api/router/router-Router.md b/astro/src/content/api/4x/api/router/router-Router.md
new file mode 100644
index 0000000000..de2867f15c
--- /dev/null
+++ b/astro/src/content/api/4x/api/router/router-Router.md
@@ -0,0 +1,5 @@
+---
+title: Router
+---
+
+Router([options])
diff --git a/astro/src/content/api/4x/api/router/router-all.md b/astro/src/content/api/4x/api/router/router-all.md
new file mode 100644
index 0000000000..cda8e9c21b
--- /dev/null
+++ b/astro/src/content/api/4x/api/router/router-all.md
@@ -0,0 +1,36 @@
+---
+title: router.all
+description: This method is just like the router.METHOD methods, except that it matches all HTTP methods (verbs).
+---
+
+router.all(path, [callback, ...] callback)
+
+This method is just like the `router.METHOD()` methods, except that it matches all HTTP methods (verbs).
+
+This method is extremely useful for
+mapping "global" logic for specific path prefixes or arbitrary matches.
+For example, if you placed the following route at the top of all other
+route definitions, it would require that all routes from that point on
+would require authentication, and automatically load a user. Keep in mind
+that these callbacks do not have to act as end points; `loadUser`
+can perform a task, then call `next()` to continue matching subsequent
+routes.
+
+```js
+router.all('*', requireAuthentication, loadUser);
+```
+
+Or the equivalent:
+
+```js
+router.all('*', requireAuthentication);
+router.all('*', loadUser);
+```
+
+Another example of this is white-listed "global" functionality. Here
+the example is much like before, but it only restricts paths prefixed with
+"/api":
+
+```js
+router.all('/api/*', requireAuthentication);
+```
diff --git a/astro/src/content/api/4x/api/router/router-param.md b/astro/src/content/api/4x/api/router/router-param.md
new file mode 100644
index 0000000000..cb82308fb4
--- /dev/null
+++ b/astro/src/content/api/4x/api/router/router-param.md
@@ -0,0 +1,128 @@
+---
+title: router.param
+description: Adds callback triggers to route parameters, where name is the name of the parameter and callback is the callback function. Although name is technically optional, it is required.
+---
+
+router.param(name, callback)
+
+Adds callback triggers to route parameters, where `name` is the name of the parameter and `callback` is the callback function. Although `name` is technically optional, using this method without it is deprecated starting with Express v4.11.0 (see below).
+
+The parameters of the callback function are:
+
+- `req`, the request object.
+- `res`, the response object.
+- `next`, indicating the next middleware function.
+- The value of the `name` parameter.
+- The name of the parameter.
+
+
+Unlike `app.param()`, `router.param()` does not accept an array of route parameters.
+
+
+For example, when `:user` is present in a route path, you may map user loading logic to automatically provide `req.user` to the route, or perform validations on the parameter input.
+
+```js
+router.param('user', function (req, res, next, id) {
+ // try to get the user details from the User model and attach it to the request object
+ User.find(id, function (err, user) {
+ if (err) {
+ next(err);
+ } else if (user) {
+ req.user = user;
+ next();
+ } else {
+ next(new Error('failed to load user'));
+ }
+ });
+});
+```
+
+Param callback functions are local to the router on which they are defined. They are not inherited by mounted apps or routers, nor are they triggered for route parameters inherited from parent routers. Hence, param callbacks defined on `router` will be triggered only by route parameters defined on `router` routes.
+
+A param callback will be called only once in a request-response cycle, even if the parameter is matched in multiple routes, as shown in the following examples.
+
+```js
+router.param('id', function (req, res, next, id) {
+ console.log('CALLED ONLY ONCE');
+ next();
+});
+
+router.get('/user/:id', function (req, res, next) {
+ console.log('although this matches');
+ next();
+});
+
+router.get('/user/:id', function (req, res) {
+ console.log('and this matches too');
+ res.end();
+});
+```
+
+On `GET /user/42`, the following is printed:
+
+```
+CALLED ONLY ONCE
+although this matches
+and this matches too
+```
+
+
+The following section describes `router.param(callback)`, which is deprecated as of v4.11.0.
+
+
+The behavior of the `router.param(name, callback)` method can be altered entirely by passing only a function to `router.param()`. This function is a custom implementation of how `router.param(name, callback)` should behave - it accepts two parameters and must return a middleware.
+
+The first parameter of this function is the name of the URL parameter that should be captured, the second parameter can be any JavaScript object which might be used for returning the middleware implementation.
+
+The middleware returned by the function decides the behavior of what happens when a URL parameter is captured.
+
+In this example, the `router.param(name, callback)` signature is modified to `router.param(name, accessId)`. Instead of accepting a name and a callback, `router.param()` will now accept a name and a number.
+
+```js
+var express = require('express');
+var app = express();
+var router = express.Router();
+
+// customizing the behavior of router.param()
+router.param(function (param, option) {
+ return function (req, res, next, val) {
+ if (val === option) {
+ next();
+ } else {
+ res.sendStatus(403);
+ }
+ };
+});
+
+// using the customized router.param()
+router.param('id', '1337');
+
+// route to trigger the capture
+router.get('/user/:id', function (req, res) {
+ res.send('OK');
+});
+
+app.use(router);
+
+app.listen(3000, function () {
+ console.log('Ready');
+});
+```
+
+In this example, the `router.param(name, callback)` signature remains the same, but instead of a middleware callback, a custom data type checking function has been defined to validate the data type of the user id.
+
+```js
+router.param(function (param, validator) {
+ return function (req, res, next, val) {
+ if (validator(val)) {
+ next();
+ } else {
+ res.sendStatus(403);
+ }
+ };
+});
+
+router.param('id', function (candidate) {
+ return !isNaN(parseFloat(candidate)) && isFinite(candidate);
+});
+```
diff --git a/astro/src/content/api/4x/api/router/router-route.md b/astro/src/content/api/4x/api/router/router-route.md
new file mode 100644
index 0000000000..89dd15bbcb
--- /dev/null
+++ b/astro/src/content/api/4x/api/router/router-route.md
@@ -0,0 +1,54 @@
+---
+title: router.route
+description: Returns an instance of a single route which you can then use to handle HTTP verbs
+---
+
+router.route(path)
+
+Returns an instance of a single route which you can then use to handle HTTP verbs
+with optional middleware. Use `router.route()` to avoid duplicate route naming and
+thus typing errors.
+
+Building on the `router.param()` example above, the following code shows how to use
+`router.route()` to specify various HTTP method handlers.
+
+```js
+var router = express.Router();
+
+router.param('user_id', function (req, res, next, id) {
+ // sample user, would actually fetch from DB, etc...
+ req.user = {
+ id: id,
+ name: 'TJ',
+ };
+ next();
+});
+
+router
+ .route('/users/:user_id')
+ .all(function (req, res, next) {
+ // runs for all HTTP verbs first
+ // think of it as route specific middleware!
+ next();
+ })
+ .get(function (req, res, next) {
+ res.json(req.user);
+ })
+ .put(function (req, res, next) {
+ // just an example of maybe updating the user
+ req.user.name = req.params.name;
+ // save user ... etc
+ res.json(req.user);
+ })
+ .post(function (req, res, next) {
+ next(new Error('not implemented'));
+ })
+ .delete(function (req, res, next) {
+ next(new Error('not implemented'));
+ });
+```
+
+This approach re-uses the single `/users/:user_id` path and adds handlers for
+various HTTP methods.
+
+{% include admonitions/note.html content="When you use `router.route()`, middleware ordering is based on when the _route_ is created, not when method handlers are added to the route. For this purpose, you can consider method handlers to belong to the route to which they were added." %}
diff --git a/astro/src/content/api/4x/api/router/router-use.md b/astro/src/content/api/4x/api/router/router-use.md
new file mode 100644
index 0000000000..b6f3929a32
--- /dev/null
+++ b/astro/src/content/api/4x/api/router/router-use.md
@@ -0,0 +1,112 @@
+---
+title: router.use
+description: Uses the specified middleware function or functions, with optional mount path that defaults to slash.
+---
+
+router.use([path], [function, ...] function)
+
+Uses the specified middleware function or functions, with optional mount path `path`, that defaults to "/".
+
+This method is similar to [app.use()](#app.use). A simple example and use case is described below.
+See [app.use()](#app.use) for more information.
+
+Middleware is like a plumbing pipe: requests start at the first middleware function defined
+and work their way "down" the middleware stack processing for each path they match.
+
+```js
+var express = require('express');
+var app = express();
+var router = express.Router();
+
+// simple logger for this router's requests
+// all requests to this router will first hit this middleware
+router.use(function (req, res, next) {
+ console.log('%s %s %s', req.method, req.url, req.path);
+ next();
+});
+
+// this will only be invoked if the path starts with /bar from the mount point
+router.use('/bar', function (req, res, next) {
+ // ... maybe some additional /bar logging ...
+ next();
+});
+
+// always invoked
+router.use(function (req, res, next) {
+ res.send('Hello World');
+});
+
+app.use('/foo', router);
+
+app.listen(3000);
+```
+
+The "mount" path is stripped and is _not_ visible to the middleware function.
+The main effect of this feature is that a mounted middleware function may operate without
+code changes regardless of its "prefix" pathname.
+
+The order in which you define middleware with `router.use()` is very important.
+They are invoked sequentially, thus the order defines middleware precedence. For example,
+usually a logger is the very first middleware you would use, so that every request gets logged.
+
+```js
+var logger = require('morgan');
+var path = require('path');
+
+router.use(logger());
+router.use(express.static(path.join(__dirname, 'public')));
+router.use(function (req, res) {
+ res.send('Hello');
+});
+```
+
+Now suppose you wanted to ignore logging requests for static files, but to continue
+logging routes and middleware defined after `logger()`. You would simply move the call to `express.static()` to the top,
+before adding the logger middleware:
+
+```js
+router.use(express.static(path.join(__dirname, 'public')));
+router.use(logger());
+router.use(function (req, res) {
+ res.send('Hello');
+});
+```
+
+Another example is serving files from multiple directories,
+giving precedence to "./public" over the others:
+
+```js
+router.use(express.static(path.join(__dirname, 'public')));
+router.use(express.static(path.join(__dirname, 'files')));
+router.use(express.static(path.join(__dirname, 'uploads')));
+```
+
+The `router.use()` method also supports named parameters so that your mount points
+for other routers can benefit from preloading using named parameters.
+
+**NOTE**: Although these middleware functions are added via a particular router, _when_
+they run is defined by the path they are attached to (not the router). Therefore,
+middleware added via one router may run for other routers if its routes
+match. For example, this code shows two different routers mounted on the same path:
+
+```js
+var authRouter = express.Router();
+var openRouter = express.Router();
+
+authRouter.use(require('./authenticate').basic(usersdb));
+
+authRouter.get('/:user_id/edit', function (req, res, next) {
+ // ... Edit user UI ...
+});
+openRouter.get('/', function (req, res, next) {
+ // ... List users ...
+});
+openRouter.get('/:user_id', function (req, res, next) {
+ // ... View user ...
+});
+
+app.use('/users', authRouter);
+app.use('/users', openRouter);
+```
+
+Even though the authentication middleware was added via the `authRouter` it will run on the routes defined by the `openRouter` as well since both routers were mounted on `/users`. To avoid this behavior, use different paths for each router.
diff --git a/astro/src/content/api/4x/api/router/routing-args.html b/astro/src/content/api/4x/api/router/routing-args.html
new file mode 100644
index 0000000000..cbf0dd027a
--- /dev/null
+++ b/astro/src/content/api/4x/api/router/routing-args.html
@@ -0,0 +1,58 @@
+Arguments
+
+
diff --git a/astro/src/content/api/5x/api.md b/astro/src/content/api/5x/api.md
new file mode 100644
index 0000000000..0cc0143122
--- /dev/null
+++ b/astro/src/content/api/5x/api.md
@@ -0,0 +1,8 @@
+---
+title: 4x API Reference
+description: API Reference for version 4.x
+---
+
+# 4.x API
+
+Some content here...
diff --git a/astro/src/content/api/5x/api/application/app-METHOD.md b/astro/src/content/api/5x/api/application/app-METHOD.md
new file mode 100644
index 0000000000..57c01e7b8b
--- /dev/null
+++ b/astro/src/content/api/5x/api/application/app-METHOD.md
@@ -0,0 +1,65 @@
+---
+title: app.METHOD
+description: Routes an HTTP request, where METHOD is the HTTP method of the request, such as GET,
+---
+
+app.METHOD(path, callback [, callback ...])
+
+Routes an HTTP request, where METHOD is the HTTP method of the request, such as GET,
+PUT, POST, and so on, in lowercase. Thus, the actual methods are `app.get()`,
+`app.post()`, `app.put()`, and so on. See [Routing methods](#routing-methods) below for the complete list.
+
+{% include api/en/5x/routing-args.html %}
+
+#### Routing methods
+
+Express supports the following routing methods corresponding to the HTTP methods of the same names:
+
+
+
+ checkout
+ copy
+ delete
+ get
+ head
+ lock
+ merge
+ mkactivity
+
+
+ mkcol
+ move
+ m-search
+ notify
+ options
+ patch
+ post
+
+
+ purge
+ put
+ report
+ search
+ subscribe
+ trace
+ unlock
+ unsubscribe
+
+
+
+The API documentation has explicit entries only for the most popular HTTP methods `app.get()`,
+`app.post()`, `app.put()`, and `app.delete()`.
+However, the other methods listed above work in exactly the same way.
+
+To route methods that translate to invalid JavaScript variable names, use the bracket notation. For example, `app['m-search']('/', function ...`.
+
+
+ The `app.get()` function is automatically called for the HTTP `HEAD` method in addition to the `GET`
+ method if `app.head()` was not called for the path before `app.get()`.
+
+
+The method, `app.all()`, is not derived from any HTTP method and loads middleware at
+the specified path for _all_ HTTP request methods.
+For more information, see [app.all](#app.all).
+
+For more information on routing, see the [routing guide](/en/guide/routing).
diff --git a/astro/src/content/api/5x/api/application/app-all.md b/astro/src/content/api/5x/api/application/app-all.md
new file mode 100644
index 0000000000..62daf475b3
--- /dev/null
+++ b/astro/src/content/api/5x/api/application/app-all.md
@@ -0,0 +1,49 @@
+---
+title: app.all
+description: This method is like the standard [app.METHOD()](#app.METHOD) methods,
+---
+
+app.all(path, callback [, callback ...])
+
+This method is like the standard [app.METHOD()](#app.METHOD) methods,
+except it matches all HTTP verbs.
+
+{% include api/en/5x/routing-args.html %}
+
+#### Examples
+
+The following callback is executed for requests to `/secret` whether using
+GET, POST, PUT, DELETE, or any other HTTP request method:
+
+```js
+app.all('/secret', (req, res, next) => {
+ console.log('Accessing the secret section ...');
+ next(); // pass control to the next handler
+});
+```
+
+The `app.all()` method is useful for mapping "global" logic for specific path prefixes or arbitrary matches. For example, if you put the following at the top of all other
+route definitions, it requires that all routes from that point on
+require authentication, and automatically load a user. Keep in mind
+that these callbacks do not have to act as end-points: `loadUser`
+can perform a task, then call `next()` to continue matching subsequent
+routes.
+
+```js
+app.all('{*splat}', requireAuthentication, loadUser);
+```
+
+Or the equivalent:
+
+```js
+app.all('{*splat}', requireAuthentication);
+app.all('{*splat}', loadUser);
+```
+
+Another example is white-listed "global" functionality.
+The example is similar to the ones above, but it only restricts paths that start with
+"/api":
+
+```js
+app.all('/api/{*splat}', requireAuthentication);
+```
diff --git a/astro/src/content/api/5x/api/application/app-delete-method.md b/astro/src/content/api/5x/api/application/app-delete-method.md
new file mode 100644
index 0000000000..48ece5abd1
--- /dev/null
+++ b/astro/src/content/api/5x/api/application/app-delete-method.md
@@ -0,0 +1,19 @@
+---
+title: app.delete
+description: Routes HTTP DELETE requests to the specified path with the specified callback functions.
+---
+
+app.delete(path, callback [, callback ...])
+
+Routes HTTP DELETE requests to the specified path with the specified callback functions.
+For more information, see the [routing guide](/en/guide/routing).
+
+{% include api/en/5x/routing-args.html %}
+
+#### Example
+
+```js
+app.delete('/', (req, res) => {
+ res.send('DELETE request to homepage');
+});
+```
diff --git a/astro/src/content/api/5x/api/application/app-disable.md b/astro/src/content/api/5x/api/application/app-disable.md
new file mode 100644
index 0000000000..10b95613be
--- /dev/null
+++ b/astro/src/content/api/5x/api/application/app-disable.md
@@ -0,0 +1,17 @@
+---
+title: app.disable
+description: Sets the Boolean setting name to false, where name is one of the properties from the app settings table.
+---
+
+app.disable(name)
+
+Sets the Boolean setting `name` to `false`, where `name` is one of the properties from the [app settings table](/en/api/application/app-set#app.settings.table).
+Calling `app.set('foo', false)` for a Boolean property is the same as calling `app.disable('foo')`.
+
+For example:
+
+```js
+app.disable('trust proxy');
+app.get('trust proxy');
+// => false
+```
diff --git a/astro/src/content/api/5x/api/application/app-disabled.md b/astro/src/content/api/5x/api/application/app-disabled.md
new file mode 100644
index 0000000000..f48b061d1d
--- /dev/null
+++ b/astro/src/content/api/5x/api/application/app-disabled.md
@@ -0,0 +1,18 @@
+---
+title: app.disabled
+description: Returns true if the Boolean setting name is disabled (false), where name is one of the properties from
+---
+
+app.disabled(name)
+
+Returns `true` if the Boolean setting `name` is disabled (`false`), where `name` is one of the properties from
+the [app settings table](/en/api/application/app-set#app.settings.table).
+
+```js
+app.disabled('trust proxy');
+// => true
+
+app.enable('trust proxy');
+app.disabled('trust proxy');
+// => false
+```
diff --git a/astro/src/content/api/5x/api/application/app-enable.md b/astro/src/content/api/5x/api/application/app-enable.md
new file mode 100644
index 0000000000..00c390d286
--- /dev/null
+++ b/astro/src/content/api/5x/api/application/app-enable.md
@@ -0,0 +1,15 @@
+---
+title: app.enable
+description: Sets the Boolean setting name to true, where name is one of the properties from the app settings table.
+---
+
+app.enable(name)
+
+Sets the Boolean setting `name` to `true`, where `name` is one of the properties from the [app settings table](/en/api/application/app-set#app.settings.table).
+Calling `app.set('foo', true)` for a Boolean property is the same as calling `app.enable('foo')`.
+
+```js
+app.enable('trust proxy');
+app.get('trust proxy');
+// => true
+```
diff --git a/astro/src/content/api/5x/api/application/app-enabled.md b/astro/src/content/api/5x/api/application/app-enabled.md
new file mode 100644
index 0000000000..72aacfe240
--- /dev/null
+++ b/astro/src/content/api/5x/api/application/app-enabled.md
@@ -0,0 +1,18 @@
+---
+title: app.enabled
+description: Returns true if the setting name is enabled (true), where name is one of the properties from the app settings table
+---
+
+app.enabled(name)
+
+Returns `true` if the setting `name` is enabled (`true`), where `name` is one of the
+properties from the [app settings table](/en/api/application/app-set#app.settings.table).
+
+```js
+app.enabled('trust proxy');
+// => false
+
+app.enable('trust proxy');
+app.enabled('trust proxy');
+// => true
+```
diff --git a/astro/src/content/api/5x/api/application/app-engine.md b/astro/src/content/api/5x/api/application/app-engine.md
new file mode 100644
index 0000000000..7096d556f2
--- /dev/null
+++ b/astro/src/content/api/5x/api/application/app-engine.md
@@ -0,0 +1,41 @@
+---
+title: app.engine
+description: Registers the given template engine callback as ext.
+---
+
+app.engine(ext, callback)
+
+Registers the given template engine `callback` as `ext`.
+
+By default, Express will `require()` the engine based on the file extension.
+For example, if you try to render a "foo.pug" file, Express invokes the
+following internally, and caches the `require()` on subsequent calls to increase
+performance.
+
+```js
+app.engine('pug', require('pug').__express);
+```
+
+Use this method for engines that do not provide `.__express` out of the box,
+or if you wish to "map" a different extension to the template engine.
+
+For example, to map the EJS template engine to ".html" files:
+
+```js
+app.engine('html', require('ejs').renderFile);
+```
+
+In this case, EJS provides a `.renderFile()` method with
+the same signature that Express expects: `(path, options, callback)`,
+though note that it aliases this method as `ejs.__express` internally
+so if you're using ".ejs" extensions you don't need to do anything.
+
+Some template engines do not follow this convention. The
+[consolidate.js](https://github.com/tj/consolidate.js) library maps Node template engines to follow this convention,
+so they work seamlessly with Express.
+
+```js
+const engines = require('consolidate');
+app.engine('haml', engines.haml);
+app.engine('html', engines.hogan);
+```
diff --git a/astro/src/content/api/5x/api/application/app-get-method.md b/astro/src/content/api/5x/api/application/app-get-method.md
new file mode 100644
index 0000000000..0d61c5ba42
--- /dev/null
+++ b/astro/src/content/api/5x/api/application/app-get-method.md
@@ -0,0 +1,20 @@
+---
+title: app.get
+description: Routes HTTP GET requests to the specified path with the specified callback functions.
+---
+
+app.get(path, callback [, callback ...])
+
+Routes HTTP GET requests to the specified path with the specified callback functions.
+
+{% include api/en/5x/routing-args.html %}
+
+For more information, see the [routing guide](/en/guide/routing).
+
+#### Example
+
+```js
+app.get('/', (req, res) => {
+ res.send('GET request to homepage');
+});
+```
diff --git a/astro/src/content/api/5x/api/application/app-get.md b/astro/src/content/api/5x/api/application/app-get.md
new file mode 100644
index 0000000000..8b56e45bfd
--- /dev/null
+++ b/astro/src/content/api/5x/api/application/app-get.md
@@ -0,0 +1,18 @@
+---
+title: app.get
+description: Returns the value of name app setting, where name is one of the strings in the app settings table
+---
+
+app.get(name)
+
+Returns the value of `name` app setting, where `name` is one of the strings in the
+[app settings table](/en/api/application/app-set#app.settings.table). For example:
+
+```js
+app.get('title');
+// => undefined
+
+app.set('title', 'My Site');
+app.get('title');
+// => "My Site"
+```
diff --git a/astro/src/content/api/5x/api/application/app-listen.md b/astro/src/content/api/5x/api/application/app-listen.md
new file mode 100644
index 0000000000..b7845a8c3c
--- /dev/null
+++ b/astro/src/content/api/5x/api/application/app-listen.md
@@ -0,0 +1,56 @@
+---
+title: app.listen
+description: Starts a UNIX socket and listens for connections on the given path.
+---
+
+app.listen(path, [callback])
+
+Starts a UNIX socket and listens for connections on the given path.
+This method is identical to Node's [http.Server.listen()](https://nodejs.org/api/http.html#http_server_listen).
+
+```js
+const express = require('express');
+const app = express();
+app.listen('/tmp/sock');
+```
+
+app.listen([port[, host[, backlog]]][, callback])
+
+Binds and listens for connections on the specified host and port.
+This method is identical to Node's [http.Server.listen()](https://nodejs.org/api/http.html#http_server_listen).
+
+If port is omitted or is 0, the operating system will assign an arbitrary unused
+port, which is useful for cases like automated tasks (tests, etc.).
+
+```js
+const express = require('express');
+const app = express();
+app.listen(3000);
+```
+
+The `app` returned by `express()` is in fact a JavaScript
+`Function`, designed to be passed to Node's HTTP servers as a callback
+to handle requests. This makes it easy to provide both HTTP and HTTPS versions of
+your app with the same code base, as the app does not inherit from these
+(it is simply a callback):
+
+```js
+const express = require('express');
+const https = require('https');
+const http = require('http');
+const app = express();
+
+http.createServer(app).listen(80);
+https.createServer(options, app).listen(443);
+```
+
+The `app.listen()` method returns an [http.Server](https://nodejs.org/api/http.html#http_class_http_server) object and (for HTTP) is a convenience method for the following:
+
+```js
+app.listen = function () {
+ const server = http.createServer(this);
+ return server.listen.apply(server, arguments);
+};
+```
+
+{% include admonitions/note.html content="All the forms of Node's [http.Server.listen()](https://nodejs.org/api/http.html#http_server_listen) method are in fact actually supported." %}
diff --git a/astro/src/content/api/5x/api/application/app-locals.md b/astro/src/content/api/5x/api/application/app-locals.md
new file mode 100644
index 0000000000..f3718bc1a6
--- /dev/null
+++ b/astro/src/content/api/5x/api/application/app-locals.md
@@ -0,0 +1,39 @@
+---
+title: app.locals
+description: The app.locals object has properties that are local variables within the application,
+---
+
+app.locals
+
+The `app.locals` object has properties that are local variables within the application,
+and will be available in templates rendered with [res.render](#res.render).
+
+
+The `locals` object is used by view engines to render a response. The object
+keys may be particularly sensitive and should not contain user-controlled
+input, as it may affect the operation of the view engine or provide a path to
+cross-site scripting. Consult the documentation for the used view engine for
+additional considerations.
+
+
+```js
+console.dir(app.locals.title);
+// => 'My App'
+
+console.dir(app.locals.email);
+// => 'me@myapp.com'
+```
+
+Once set, the value of `app.locals` properties persist throughout the life of the application,
+in contrast with [res.locals](#res.locals) properties that
+are valid only for the lifetime of the request.
+
+You can access local variables in templates rendered within the application.
+This is useful for providing helper functions to templates, as well as application-level data.
+Local variables are available in middleware via `req.app.locals` (see [req.app](#req.app))
+
+```js
+app.locals.title = 'My App';
+app.locals.strftime = require('strftime');
+app.locals.email = 'me@myapp.com';
+```
diff --git a/astro/src/content/api/5x/api/application/app-mountpath.md b/astro/src/content/api/5x/api/application/app-mountpath.md
new file mode 100644
index 0000000000..1b0b530f69
--- /dev/null
+++ b/astro/src/content/api/5x/api/application/app-mountpath.md
@@ -0,0 +1,50 @@
+---
+title: app.mountpath
+description: The app.mountpath property contains one or more path patterns on which a sub-app was mounted.
+---
+
+app.mountpath
+
+The `app.mountpath` property contains one or more path patterns on which a sub-app was mounted.
+
+
+ A sub-app is an instance of `express` that may be used for handling the request to a route.
+
+
+```js
+const express = require('express');
+
+const app = express(); // the main app
+const admin = express(); // the sub app
+
+admin.get('/', (req, res) => {
+ console.log(admin.mountpath); // /admin
+ res.send('Admin Homepage');
+});
+
+app.use('/admin', admin); // mount the sub app
+```
+
+It is similar to the [baseUrl](#req.baseUrl) property of the `req` object, except `req.baseUrl`
+returns the matched URL path, instead of the matched patterns.
+
+If a sub-app is mounted on multiple path patterns, `app.mountpath` returns the list of
+patterns it is mounted on, as shown in the following example.
+
+```js
+const admin = express();
+
+admin.get('/', (req, res) => {
+ console.log(admin.mountpath); // [ '/adm{*splat}n', '/manager' ]
+ res.send('Admin Homepage');
+});
+
+const secret = express();
+secret.get('/', (req, res) => {
+ console.log(secret.mountpath); // /secr{*splat}t
+ res.send('Admin Secret');
+});
+
+admin.use('/secr{*splat}t', secret); // load the 'secret' router on '/secr{*splat}t', on the 'admin' sub app
+app.use(['/adm{*splat}n', '/manager'], admin); // load the 'admin' router on '/adm{*splat}n' and '/manager', on the parent app
+```
diff --git a/astro/src/content/api/5x/api/application/app-onmount.md b/astro/src/content/api/5x/api/application/app-onmount.md
new file mode 100644
index 0000000000..ad746547a8
--- /dev/null
+++ b/astro/src/content/api/5x/api/application/app-onmount.md
@@ -0,0 +1,35 @@
+---
+title: app.on
+description: The mount event is fired on a sub-app, when it is mounted on a parent app. The parent app is passed to the callback function.
+---
+
+app.on('mount', callback(parent))
+
+The `mount` event is fired on a sub-app, when it is mounted on a parent app. The parent app is passed to the callback function.
+
+
+**NOTE**
+
+Sub-apps will:
+
+- Not inherit the value of settings that have a default value. You must set the value in the sub-app.
+- Inherit the value of settings with no default value.
+
+For details, see [Application settings](/en/api/application/app-set#app.settings.table).
+
+
+
+```js
+const admin = express();
+
+admin.on('mount', (parent) => {
+ console.log('Admin Mounted');
+ console.log(parent); // refers to the parent app
+});
+
+admin.get('/', (req, res) => {
+ res.send('Admin Homepage');
+});
+
+app.use('/admin', admin);
+```
diff --git a/astro/src/content/api/5x/api/application/app-param.md b/astro/src/content/api/5x/api/application/app-param.md
new file mode 100644
index 0000000000..1a9792f582
--- /dev/null
+++ b/astro/src/content/api/5x/api/application/app-param.md
@@ -0,0 +1,83 @@
+---
+title: app.param
+description: Add callback triggers to route parameters, where name is the name of the parameter or an array of parameter names, and callback is the callback function.
+---
+
+app.param(name, callback)
+
+Add callback triggers to [route parameters](/en/guide/routing#route-parameters), where `name` is the name of the parameter or an array of them, and `callback` is the callback function. The parameters of the callback function are the request object, the response object, the next middleware, the value of the parameter and the name of the parameter, in that order.
+
+If `name` is an array, the `callback` trigger is registered for each parameter declared in it, in the order in which they are declared. Furthermore, for each declared parameter except the last one, a call to `next` inside the callback will call the callback for the next declared parameter. For the last parameter, a call to `next` will call the next middleware in place for the route currently being processed, just like it would if `name` were just a string.
+
+For example, when `:user` is present in a route path, you may map user loading logic to automatically provide `req.user` to the route, or perform validations on the parameter input.
+
+```js
+app.param('user', (req, res, next, id) => {
+ // try to get the user details from the User model and attach it to the request object
+ User.find(id, (err, user) => {
+ if (err) {
+ next(err);
+ } else if (user) {
+ req.user = user;
+ next();
+ } else {
+ next(new Error('failed to load user'));
+ }
+ });
+});
+```
+
+Param callback functions are local to the router on which they are defined. They are not inherited by mounted apps or routers, nor are they triggered for route parameters inherited from parent routers. Hence, param callbacks defined on `app` will be triggered only by route parameters defined on `app` routes.
+
+All param callbacks will be called before any handler of any route in which the param occurs, and they will each be called only once in a request-response cycle, even if the parameter is matched in multiple routes, as shown in the following examples.
+
+```js
+app.param('id', (req, res, next, id) => {
+ console.log('CALLED ONLY ONCE');
+ next();
+});
+
+app.get('/user/:id', (req, res, next) => {
+ console.log('although this matches');
+ next();
+});
+
+app.get('/user/:id', (req, res) => {
+ console.log('and this matches too');
+ res.end();
+});
+```
+
+On `GET /user/42`, the following is printed:
+
+```
+CALLED ONLY ONCE
+although this matches
+and this matches too
+```
+
+```js
+app.param(['id', 'page'], (req, res, next, value) => {
+ console.log('CALLED ONLY ONCE with', value);
+ next();
+});
+
+app.get('/user/:id/:page', (req, res, next) => {
+ console.log('although this matches');
+ next();
+});
+
+app.get('/user/:id/:page', (req, res) => {
+ console.log('and this matches too');
+ res.end();
+});
+```
+
+On `GET /user/42/3`, the following is printed:
+
+```
+CALLED ONLY ONCE with 42
+CALLED ONLY ONCE with 3
+although this matches
+and this matches too
+```
diff --git a/astro/src/content/api/5x/api/application/app-path.md b/astro/src/content/api/5x/api/application/app-path.md
new file mode 100644
index 0000000000..78c6885667
--- /dev/null
+++ b/astro/src/content/api/5x/api/application/app-path.md
@@ -0,0 +1,24 @@
+---
+title: app.path
+description: Returns the canonical path of the app, a string.
+---
+
+app.path()
+
+Returns the canonical path of the app, a string.
+
+```js
+const app = express();
+const blog = express();
+const blogAdmin = express();
+
+app.use('/blog', blog);
+blog.use('/admin', blogAdmin);
+
+console.log(app.path()); // ''
+console.log(blog.path()); // '/blog'
+console.log(blogAdmin.path()); // '/blog/admin'
+```
+
+The behavior of this method can become very complicated in complex cases of mounted apps:
+it is usually better to use [req.baseUrl](#req.baseUrl) to get the canonical path of the app.
diff --git a/astro/src/content/api/5x/api/application/app-post-method.md b/astro/src/content/api/5x/api/application/app-post-method.md
new file mode 100644
index 0000000000..416a401151
--- /dev/null
+++ b/astro/src/content/api/5x/api/application/app-post-method.md
@@ -0,0 +1,19 @@
+---
+title: app.post
+description: Routes HTTP POST requests to the specified path with the specified callback functions.
+---
+
+app.post(path, callback [, callback ...])
+
+Routes HTTP POST requests to the specified path with the specified callback functions.
+For more information, see the [routing guide](/en/guide/routing).
+
+{% include api/en/5x/routing-args.html %}
+
+#### Example
+
+```js
+app.post('/', (req, res) => {
+ res.send('POST request to homepage');
+});
+```
diff --git a/astro/src/content/api/5x/api/application/app-put-method.md b/astro/src/content/api/5x/api/application/app-put-method.md
new file mode 100644
index 0000000000..2eb53a77eb
--- /dev/null
+++ b/astro/src/content/api/5x/api/application/app-put-method.md
@@ -0,0 +1,18 @@
+---
+title: app.put
+description: Routes HTTP PUT requests to the specified path with the specified callback functions.
+---
+
+app.put(path, callback [, callback ...])
+
+Routes HTTP PUT requests to the specified path with the specified callback functions.
+
+{% include api/en/5x/routing-args.html %}
+
+#### Example
+
+```js
+app.put('/', (req, res) => {
+ res.send('PUT request to homepage');
+});
+```
diff --git a/astro/src/content/api/5x/api/application/app-render.md b/astro/src/content/api/5x/api/application/app-render.md
new file mode 100644
index 0000000000..d5f65bf258
--- /dev/null
+++ b/astro/src/content/api/5x/api/application/app-render.md
@@ -0,0 +1,44 @@
+---
+title: app.render
+description: Returns the rendered HTML of a view via the callback function. It accepts an optional parameter that is an object containing local variables for the vie
+---
+
+app.render(view, [locals], callback)
+
+Returns the rendered HTML of a view via the `callback` function. It accepts an optional parameter
+that is an object containing local variables for the view. It is like [res.render()](#res.render),
+except it cannot send the rendered view to the client on its own.
+
+
+Think of `app.render()` as a utility function for generating rendered view strings.
+Internally `res.render()` uses `app.render()` to render views.
+
+
+
+The `view` argument performs file system operations like reading a file from
+disk and evaluating Node.js modules, and as so for security reasons should not
+contain input from the end-user.
+
+
+
+The `locals` object is used by view engines to render a response. The object
+keys may be particularly sensitive and should not contain user-controlled
+input, as it may affect the operation of the view engine or provide a path to
+cross-site scripting. Consult the documentation for the used view engine for
+additional considerations.
+
+
+
+The local variable `cache` is reserved for enabling view cache. Set it to `true`, if you want to
+cache view during development; view caching is enabled in production by default.
+
+
+```js
+app.render('email', (err, html) => {
+ // ...
+});
+
+app.render('email', { name: 'Tobi' }, (err, html) => {
+ // ...
+});
+```
diff --git a/astro/src/content/api/5x/api/application/app-route.md b/astro/src/content/api/5x/api/application/app-route.md
new file mode 100644
index 0000000000..a0f9816d5d
--- /dev/null
+++ b/astro/src/content/api/5x/api/application/app-route.md
@@ -0,0 +1,26 @@
+---
+title: app.route
+description: Returns an instance of a single route, which you can then use to handle HTTP verbs with optional middleware.
+---
+
+app.route(path)
+
+Returns an instance of a single route, which you can then use to handle HTTP verbs with optional middleware.
+Use `app.route()` to avoid duplicate route names (and thus typo errors).
+
+```js
+const app = express();
+
+app
+ .route('/events')
+ .all((req, res, next) => {
+ // runs for all HTTP verbs first
+ // think of it as route specific middleware!
+ })
+ .get((req, res, next) => {
+ res.json({});
+ })
+ .post((req, res, next) => {
+ // maybe add a new event...
+ });
+```
diff --git a/astro/src/content/api/5x/api/application/app-router.md b/astro/src/content/api/5x/api/application/app-router.md
new file mode 100644
index 0000000000..6bd664d291
--- /dev/null
+++ b/astro/src/content/api/5x/api/application/app-router.md
@@ -0,0 +1,24 @@
+---
+title: app.router
+description: The application's in-built instance of router. This is created lazily, on first access.
+---
+
+app.router
+
+The application's in-built instance of router. This is created lazily, on first access.
+
+```js
+const express = require('express');
+const app = express();
+const router = app.router;
+
+router.get('/', (req, res) => {
+ res.send('hello world');
+});
+
+app.listen(3000);
+```
+
+You can add middleware and HTTP method routes to the `router` just like an application.
+
+For more information, see [Router](#router).
diff --git a/astro/src/content/api/5x/api/application/app-set.md b/astro/src/content/api/5x/api/application/app-set.md
new file mode 100644
index 0000000000..a0f6e0e3eb
--- /dev/null
+++ b/astro/src/content/api/5x/api/application/app-set.md
@@ -0,0 +1,354 @@
+---
+title: app.set
+description: Assigns setting name to value
+---
+
+app.set(name, value)
+
+Assigns setting `name` to `value`. You may store any value that you want,
+but certain names can be used to configure the behavior of the server. These
+special names are listed in the [app settings table](/en/api/application/app-set#app.settings.table).
+
+Calling `app.set('foo', true)` for a Boolean property is the same as calling
+`app.enable('foo')`. Similarly, calling `app.set('foo', false)` for a Boolean
+property is the same as calling `app.disable('foo')`.
+
+Retrieve the value of a setting with [`app.get()`](#app.get).
+
+```js
+app.set('title', 'My Site');
+app.get('title'); // "My Site"
+```
+
+Application Settings
+
+The following table lists application settings.
+
+Note that sub-apps will:
+
+- Not inherit the value of settings that have a default value. You must set the value in the sub-app.
+- Inherit the value of settings with no default value; these are explicitly noted in the table below.
+
+Exceptions: Sub-apps will inherit the value of `trust proxy` even though it has a default value (for backward-compatibility);
+Sub-apps will not inherit the value of `view cache` in production (when `NODE_ENV` is "production").
+
+
+
+ Options for `trust proxy` setting
+
+
+ Read [Express behind proxies](/en/guide/behind-proxies) for more
+ information.
+
+
+
+
+ Options for `etag` setting
+
+
+**NOTE**: These settings apply only to dynamic files, not static files.
+The [express.static](#express.static) middleware ignores these settings.
+
+
+
+ The ETag functionality is implemented using the
+ [etag](https://www.npmjs.org/package/etag) package.
+ For more information, see its documentation.
+
+
+
diff --git a/astro/src/content/api/5x/api/application/app-use.md b/astro/src/content/api/5x/api/application/app-use.md
new file mode 100644
index 0000000000..56b14bc76c
--- /dev/null
+++ b/astro/src/content/api/5x/api/application/app-use.md
@@ -0,0 +1,310 @@
+---
+title: app.use
+description: Mounts the specified [middleware](/en/guide/using-middleware) function or functions
+---
+
+app.use([path,] callback [, callback...])
+
+Mounts the specified [middleware](/en/guide/using-middleware) function or functions
+at the specified path:
+the middleware function is executed when the base of the requested path matches `path`.
+
+{% include api/en/5x/routing-args.html %}
+
+#### Description
+
+A route will match any path that follows its path immediately with a "`/`".
+For example: `app.use('/apple', ...)` will match "/apple", "/apple/images",
+"/apple/images/news", and so on.
+
+Since `path` defaults to "/", middleware mounted without a path will be executed for every request to the app.
+For example, this middleware function will be executed for _every_ request to the app:
+
+```js
+app.use((req, res, next) => {
+ console.log('Time: %d', Date.now());
+ next();
+});
+```
+
+
+**NOTE**
+
+Sub-apps will:
+
+- Not inherit the value of settings that have a default value. You must set the value in the sub-app.
+- Inherit the value of settings with no default value.
+
+For details, see [Application settings](/en/5x/api/application/app-settings/).
+
+
+
+Middleware functions are executed sequentially, therefore the order of middleware inclusion is important.
+
+```js
+// this middleware will not allow the request to go beyond it
+app.use((req, res, next) => {
+ res.send('Hello World');
+});
+
+// requests will never reach this route
+app.get('/', (req, res) => {
+ res.send('Welcome');
+});
+```
+
+**Error-handling middleware**
+
+Error-handling middleware always takes _four_ arguments. You must provide four arguments to identify it as an error-handling middleware function. Even if you don't need to use the `next` object, you must specify it to maintain the signature. Otherwise, the `next` object will be interpreted as regular middleware and will fail to handle errors. For details about error-handling middleware, see: [Error handling](/en/guide/error-handling).
+
+Define error-handling middleware functions in the same way as other middleware functions, except with four arguments instead of three, specifically with the signature `(err, req, res, next)`):
+
+```js
+app.use((err, req, res, next) => {
+ console.error(err.stack);
+ res.status(500).send('Something broke!');
+});
+```
+
+#### Path examples
+
+The following table provides some simple examples of valid `path` values for
+mounting middleware.
+
+
+
+#### Middleware callback function examples
+
+The following table provides some simple examples of middleware functions that
+can be used as the `callback` argument to `app.use()`, `app.METHOD()`, and `app.all()`.
+
+
+
+Following are some examples of using the [express.static](/en/guide/using-middleware#middleware.built-in)
+middleware in an Express app.
+
+Serve static content for the app from the "public" directory in the application directory:
+
+```js
+// GET /style.css etc
+app.use(express.static(path.join(__dirname, 'public')));
+```
+
+Mount the middleware at "/static" to serve static content only when their request path is prefixed with "/static":
+
+```js
+// GET /static/style.css etc.
+app.use('/static', express.static(path.join(__dirname, 'public')));
+```
+
+Disable logging for static content requests by loading the logger middleware after the static middleware:
+
+```js
+app.use(express.static(path.join(__dirname, 'public')));
+app.use(logger());
+```
+
+Serve static files from multiple directories, but give precedence to "./public" over the others:
+
+```js
+app.use(express.static(path.join(__dirname, 'public')));
+app.use(express.static(path.join(__dirname, 'files')));
+app.use(express.static(path.join(__dirname, 'uploads')));
+```
diff --git a/astro/src/content/api/5x/api/application/overview.mdx b/astro/src/content/api/5x/api/application/overview.mdx
new file mode 100644
index 0000000000..0efaf2dcef
--- /dev/null
+++ b/astro/src/content/api/5x/api/application/overview.mdx
@@ -0,0 +1,122 @@
+---
+title: Application Object
+description: Learn about the properties of the Express application object.
+---
+
+import Card from '@components/primitives/Card/Card.astro';
+import { CardList } from '@components/patterns';
+
+## Application
+
+The `app` object conventionally denotes the Express application.
+Create it by calling the top-level `express()` function exported by the Express module:
+
+```js
+var express = require('express');
+var app = express();
+
+app.get('/', function (req, res) {
+ res.send('hello world');
+});
+
+app.listen(3000);
+```
+
+The `app` object has methods for
+
+- Routing HTTP requests; see for example, [app.METHOD](./app-METHOD) and [app.param](./app-param).
+- Configuring middleware; see [app.route](./app-route).
+- Rendering HTML views; see [app.render](./app-render).
+- Registering a template engine; see [app.engine](./app-engine).
+
+It also has settings (properties) that affect how the application behaves;
+for more information, see [Application settings](./app-settings/).
+
+
+ The Express application object can be referred from the [request object](#req) and the [response
+ object](#res) as `req.app`, and `res.app`, respectively.
+
+
+Properties
+
+
+
+
+
+
+
+
+
+
+Events
+
+
+
+
+
+
+
+Methods
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/astro/src/content/api/5x/api/express/express.json.md b/astro/src/content/api/5x/api/express/express.json.md
new file mode 100644
index 0000000000..ca0935b6da
--- /dev/null
+++ b/astro/src/content/api/5x/api/express/express.json.md
@@ -0,0 +1,43 @@
+---
+title: express.json
+description: This is a built-in middleware function in Express. It parses incoming requests
+---
+
+express.json([options])
+
+This is a built-in middleware function in Express. It parses incoming requests
+with JSON payloads and is based on
+[body-parser](/en/resources/middleware/body-parser).
+
+Returns middleware that only parses JSON and only looks at requests where
+the `Content-Type` header matches the `type` option. This parser accepts any
+Unicode encoding of the body and supports automatic inflation of `gzip` and
+`deflate` encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`), or `undefined` if
+there was no body to parse, the `Content-Type` was not matched, or an error
+occurred.
+
+
+As `req.body`'s shape is based on user-controlled input, all properties and
+values in this object are untrusted and should be validated before trusting.
+For example, `req.body.foo.toString()` may fail in multiple ways, for example
+`foo` may not be there or may not be a string, and `toString` may not be a
+function and instead a string or other user-input.
+
+
+The following table describes the properties of the optional `options` object.
+
+
+
+| Property | Description | Type | Default |
+| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- | -------------------- |
+| `inflate` | Enables or disables handling deflated (compressed) bodies; when disabled, deflated bodies are rejected. | Boolean | `true` |
+| `limit` | Controls the maximum request body size. If this is a number, then the value specifies the number of bytes; if it is a string, the value is passed to the [bytes](https://www.npmjs.com/package/bytes) library for parsing. | Mixed | `"100kb"` |
+| `reviver` | The `reviver` option is passed directly to `JSON.parse` as the second argument. You can find more information on this argument [in the MDN documentation about JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Example.3A_Using_the_reviver_parameter). | Function | `null` |
+| `strict` | Enables or disables only accepting arrays and objects; when disabled will accept anything `JSON.parse` accepts. | Boolean | `true` |
+| `type` | This is used to determine what media type the middleware will parse. This option can be a string, array of strings, or a function. If not a function, `type` option is passed directly to the [type-is](https://www.npmjs.org/package/type-is#readme) library and this can be an extension name (like `json`), a mime type (like `application/json`), or a mime type with a wildcard (like `*/*` or `*/json`). If a function, the `type` option is called as `fn(req)` and the request is parsed if it returns a truthy value. | Mixed | `"application/json"` |
+| `verify` | This option, if supplied, is called as `verify(req, res, buf, encoding)`, where `buf` is a `Buffer` of the raw request body and `encoding` is the encoding of the request. The parsing can be aborted by throwing an error. | Function | `undefined` |
+
+
diff --git a/astro/src/content/api/5x/api/express/express.raw.md b/astro/src/content/api/5x/api/express/express.raw.md
new file mode 100644
index 0000000000..ab545cc1de
--- /dev/null
+++ b/astro/src/content/api/5x/api/express/express.raw.md
@@ -0,0 +1,41 @@
+---
+title: express.raw
+description: This is a built-in middleware function in Express. It parses incoming request
+---
+
+express.raw([options])
+
+This is a built-in middleware function in Express. It parses incoming request
+payloads into a `Buffer` and is based on
+[body-parser](/en/resources/middleware/body-parser).
+
+Returns middleware that parses all bodies as a `Buffer` and only looks at requests
+where the `Content-Type` header matches the `type` option. This parser accepts
+any Unicode encoding of the body and supports automatic inflation of `gzip` and
+`deflate` encodings.
+
+A new `body` `Buffer` containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`), or `undefined` if
+there was no body to parse, the `Content-Type` was not matched, or an error
+occurred.
+
+
+As `req.body`'s shape is based on user-controlled input, all properties and
+values in this object are untrusted and should be validated before trusting.
+For example, `req.body.toString()` may fail in multiple ways, for example
+stacking multiple parsers `req.body` may be from a different parser. Testing
+that `req.body` is a `Buffer` before calling buffer methods is recommended.
+
+
+The following table describes the properties of the optional `options` object.
+
+
+
+| Property | Description | Type | Default |
+| --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ---------------------------- |
+| `inflate` | Enables or disables handling deflated (compressed) bodies; when disabled, deflated bodies are rejected. | Boolean | `true` |
+| `limit` | Controls the maximum request body size. If this is a number, then the value specifies the number of bytes; if it is a string, the value is passed to the [bytes](https://www.npmjs.com/package/bytes) library for parsing. | Mixed | `"100kb"` |
+| `type` | This is used to determine what media type the middleware will parse. This option can be a string, array of strings, or a function. If not a function, `type` option is passed directly to the [type-is](https://www.npmjs.org/package/type-is#readme) library and this can be an extension name (like `bin`), a mime type (like `application/octet-stream`), or a mime type with a wildcard (like `*/*` or `application/*`). If a function, the `type` option is called as `fn(req)` and the request is parsed if it returns a truthy value. | Mixed | `"application/octet-stream"` |
+| `verify` | This option, if supplied, is called as `verify(req, res, buf, encoding)`, where `buf` is a `Buffer` of the raw request body and `encoding` is the encoding of the request. The parsing can be aborted by throwing an error. | Function | `undefined` |
+
+
diff --git a/astro/src/content/api/5x/api/express/express.router.md b/astro/src/content/api/5x/api/express/express.router.md
new file mode 100644
index 0000000000..2474bc3fa0
--- /dev/null
+++ b/astro/src/content/api/5x/api/express/express.router.md
@@ -0,0 +1,29 @@
+---
+title: express.Router
+description: Creates a new [router](#router) object.
+---
+
+express.Router([options])
+
+Creates a new [router](#router) object.
+
+```js
+const router = express.Router([options]);
+```
+
+The optional `options` parameter specifies the behavior of the router.
+
+
+
+| Property | Description | Default | Availability |
+| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | ------------ |
+| `caseSensitive` | Enable case sensitivity. | Disabled by default, treating "/Foo" and "/foo" as the same. | |
+| `mergeParams` | Preserve the `req.params` values from the parent router. If the parent and the child have conflicting param names, the child's value take precedence. | `false` | 4.5.0+ |
+| `strict` | Enable strict routing. | Disabled by default, "/foo" and "/foo/" are treated the same by the router. | |
+
+
+
+You can add middleware and HTTP method routes (such as `get`, `put`, `post`, and
+so on) to `router` just like an application.
+
+For more information, see [Router](#router).
diff --git a/astro/src/content/api/5x/api/express/express.static.md b/astro/src/content/api/5x/api/express/express.static.md
new file mode 100644
index 0000000000..70609dba0c
--- /dev/null
+++ b/astro/src/content/api/5x/api/express/express.static.md
@@ -0,0 +1,99 @@
+---
+title: express.static
+description: This is a built-in middleware function in Express.
+---
+
+express.static(root, [options])
+
+This is a built-in middleware function in Express.
+It serves static files and is based on [serve-static](/en/resources/middleware/serve-static).
+
+NOTE: For best results, [use a reverse proxy](/en/advanced/best-practice-performance#use-a-reverse-proxy) cache to improve performance of serving static assets.
+
+
+The `root` argument specifies the root directory from which to serve static assets.
+The function determines the file to serve by combining `req.url` with the provided `root` directory.
+When a file is not found, instead of sending a 404 response, it instead calls `next()`
+to move on to the next middleware, allowing for stacking and fall-backs.
+
+The following table describes the properties of the `options` object.
+See also the [example below](#example.of.express.static).
+
+
+
+| Property | Description | Type | Default |
+| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------ |
+| `dotfiles` | Determines how dotfiles (files or directories that begin with a dot ".") are treated. See [dotfiles](#dotfiles) below. | String | "ignore" |
+| `etag` | Enable or disable etag generation NOTE: `express.static` always sends weak ETags. | Boolean | `true` |
+| `extensions` | Sets file extension fallbacks: If a file is not found, search for files with the specified extensions and serve the first one found. Example: `['html', 'htm']`. | Mixed | `false` |
+| `fallthrough` | Let client errors fall-through as unhandled requests, otherwise forward a client error. See [fallthrough](#fallthrough) below. | Boolean | `true` |
+| `immutable` | Enable or disable the `immutable` directive in the `Cache-Control` response header. If enabled, the `maxAge` option should also be specified to enable caching. The `immutable` directive will prevent supported clients from making conditional requests during the life of the `maxAge` option to check if the file has changed. | Boolean | `false` |
+| `index` | Sends the specified directory index file. Set to `false` to disable directory indexing. | Mixed | "index.html" |
+| `lastModified` | Set the `Last-Modified` header to the last modified date of the file on the OS. | Boolean | `true` |
+| `maxAge` | Set the max-age property of the Cache-Control header in milliseconds or a string in [ms format](https://www.npmjs.org/package/ms). | Number | 0 |
+| `redirect` | Redirect to trailing "/" when the pathname is a directory. | Boolean | `true` |
+| `setHeaders` | Function for setting HTTP headers to serve with the file. See [setHeaders](#setHeaders) below. | Function | |
+| `acceptRanges` | Enable or disable accepting ranged requests. Disabling this will not send the Accept-Ranges header and will ignore the contents of the Range request header. | Boolean | true |
+| `cacheControl` | Enable or disable setting the Cache-Control response header. Disabling this will ignore the immutable and maxAge options. | Boolean | true |
+
+
+
+For more information, see [Serving static files in Express](/en/starter/static-files).
+and [Using middleware - Built-in middleware](/en/guide/using-middleware#middleware.built-in).
+
+ dotfiles
+
+Possible values for this option are:
+
+- "allow" - No special treatment for dotfiles.
+- "deny" - Deny a request for a dotfile, respond with `403`, then call `next()`.
+- "ignore" - Act as if the dotfile does not exist, respond with `404`, then call `next()`.
+
+fallthrough
+
+When this option is `true`, client errors such as a bad request or a request to a non-existent
+file will cause this middleware to simply call `next()` to invoke the next middleware in the stack.
+When false, these errors (even 404s), will invoke `next(err)`.
+
+Set this option to `true` so you can map multiple physical directories
+to the same web address or for routes to fill in non-existent files.
+
+Use `false` if you have mounted this middleware at a path designed
+to be strictly a single file system directory, which allows for short-circuiting 404s
+for less overhead. This middleware will also reply to all methods.
+
+
+
+For this option, specify a function to set custom response headers. Alterations to the headers must occur synchronously.
+
+The signature of the function is:
+
+```js
+fn(res, path, stat);
+```
+
+Arguments:
+
+- `res`, the [response object](#res).
+- `path`, the file path that is being sent.
+- `stat`, the `stat` object of the file that is being sent.
+
+Example of express.static
+
+Here is an example of using the `express.static` middleware function with an elaborate options object:
+
+```js
+const options = {
+ dotfiles: 'ignore',
+ etag: false,
+ extensions: ['htm', 'html'],
+ index: false,
+ maxAge: '1d',
+ redirect: false,
+ setHeaders(res, path, stat) {
+ res.set('x-timestamp', Date.now());
+ },
+};
+
+app.use(express.static('public', options));
+```
diff --git a/astro/src/content/api/5x/api/express/express.text.md b/astro/src/content/api/5x/api/express/express.text.md
new file mode 100644
index 0000000000..2bb815bf33
--- /dev/null
+++ b/astro/src/content/api/5x/api/express/express.text.md
@@ -0,0 +1,42 @@
+---
+title: express.text
+description: This is a built-in middleware function in Express. It parses incoming request
+---
+
+express.text([options])
+
+This is a built-in middleware function in Express. It parses incoming request
+payloads into a string and is based on
+[body-parser](/en/resources/middleware/body-parser).
+
+Returns middleware that parses all bodies as a string and only looks at requests
+where the `Content-Type` header matches the `type` option. This parser accepts
+any Unicode encoding of the body and supports automatic inflation of `gzip` and
+`deflate` encodings.
+
+A new `body` string containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`), or `undefined` if
+there was no body to parse, the `Content-Type` was not matched, or an error
+occurred.
+
+
+As `req.body`'s shape is based on user-controlled input, all properties and
+values in this object are untrusted and should be validated before trusting.
+For example, `req.body.trim()` may fail in multiple ways, for example
+stacking multiple parsers `req.body` may be from a different parser. Testing
+that `req.body` is a string before calling string methods is recommended.
+
+
+The following table describes the properties of the optional `options` object.
+
+
+
+| Property | Description | Type | Default |
+| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -------------- |
+| `defaultCharset` | Specify the default character set for the text content if the charset is not specified in the `Content-Type` header of the request. | String | `"utf-8"` |
+| `inflate` | Enables or disables handling deflated (compressed) bodies; when disabled, deflated bodies are rejected. | Boolean | `true` |
+| `limit` | Controls the maximum request body size. If this is a number, then the value specifies the number of bytes; if it is a string, the value is passed to the [bytes](https://www.npmjs.com/package/bytes) library for parsing. | Mixed | `"100kb"` |
+| `type` | This is used to determine what media type the middleware will parse. This option can be a string, array of strings, or a function. If not a function, `type` option is passed directly to the [type-is](https://www.npmjs.org/package/type-is#readme) library and this can be an extension name (like `txt`), a mime type (like `text/plain`), or a mime type with a wildcard (like `*/*` or `text/*`). If a function, the `type` option is called as `fn(req)` and the request is parsed if it returns a truthy value. | Mixed | `"text/plain"` |
+| `verify` | This option, if supplied, is called as `verify(req, res, buf, encoding)`, where `buf` is a `Buffer` of the raw request body and `encoding` is the encoding of the request. The parsing can be aborted by throwing an error. | Function | `undefined` |
+
+
diff --git a/astro/src/content/api/5x/api/express/express.urlencoded.md b/astro/src/content/api/5x/api/express/express.urlencoded.md
new file mode 100644
index 0000000000..bc51a18d91
--- /dev/null
+++ b/astro/src/content/api/5x/api/express/express.urlencoded.md
@@ -0,0 +1,45 @@
+---
+title: express.urlencoded
+description: This is a built-in middleware function in Express. It parses incoming requests
+---
+
+express.urlencoded([options])
+
+This is a built-in middleware function in Express. It parses incoming requests
+with urlencoded payloads and is based on [body-parser](/en/resources/middleware/body-parser).
+
+Returns middleware that only parses urlencoded bodies and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser accepts only UTF-8 encoding of the body and supports automatic
+inflation of `gzip` and `deflate` encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`), or `undefined` if
+there was no body to parse, the `Content-Type` was not matched, or an error
+occurred. This object will contain key-value pairs, where the value can be
+a string or array (when `extended` is `false`), or any type (when `extended`
+is `true`).
+
+
+As `req.body`'s shape is based on user-controlled input, all properties and
+values in this object are untrusted and should be validated before trusting.
+For example, `req.body.foo.toString()` may fail in multiple ways, for example
+`foo` may not be there or may not be a string, and `toString` may not be a
+function and instead a string or other user-input.
+
+
+The following table describes the properties of the optional `options` object.
+
+
+
+| Property | Description | Type | Default |
+| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------- |
+| `extended` | This option allows to choose between parsing the URL-encoded data with the `querystring` library (when `false`) or the `qs` library (when `true`). The "extended" syntax allows for rich objects and arrays to be encoded into the URL-encoded format, allowing for a JSON-like experience with URL-encoded. For more information, please [see the qs library](https://www.npmjs.org/package/qs#readme). | Boolean | `false` |
+| `inflate` | Enables or disables handling deflated (compressed) bodies; when disabled, deflated bodies are rejected. | Boolean | `true` |
+| `limit` | Controls the maximum request body size. If this is a number, then the value specifies the number of bytes; if it is a string, the value is passed to the [bytes](https://www.npmjs.com/package/bytes) library for parsing. | Mixed | `"100kb"` |
+| `parameterLimit` | This option controls the maximum number of parameters that are allowed in the URL-encoded data. If a request contains more parameters than this value, an error will be raised. | Number | `1000` |
+| `type` | This is used to determine what media type the middleware will parse. This option can be a string, array of strings, or a function. If not a function, `type` option is passed directly to the [type-is](https://www.npmjs.org/package/type-is#readme) library and this can be an extension name (like `urlencoded`), a mime type (like `application/x-www-form-urlencoded`), or a mime type with a wildcard (like `*/x-www-form-urlencoded`). If a function, the `type` option is called as `fn(req)` and the request is parsed if it returns a truthy value. | Mixed | `"application/x-www-form-urlencoded"` |
+| `verify` | This option, if supplied, is called as `verify(req, res, buf, encoding)`, where `buf` is a `Buffer` of the raw request body and `encoding` is the encoding of the request. The parsing can be aborted by throwing an error. | Function | `undefined` |
+| `depth` | Configure the maximum depth of the `qs` library when `extended` is `true`. This allows you to limit the amount of keys that are parsed and can be useful to prevent certain types of abuse. Defaults to `32`. It is recommended to keep this value as low as possible. | Number | `32` |
+
+
diff --git a/astro/src/content/api/5x/api/express/overview.mdx b/astro/src/content/api/5x/api/express/overview.mdx
new file mode 100644
index 0000000000..ea511dc5f7
--- /dev/null
+++ b/astro/src/content/api/5x/api/express/overview.mdx
@@ -0,0 +1,42 @@
+---
+title: Express Object
+description: Learn about the methods available on the top-level Express object.
+---
+
+import Card from '@components/primitives/Card/Card.astro';
+import { CardList } from '@components/patterns';
+
+## express()
+
+Creates an Express application. The `express()` function is a top-level function exported by the `express` module.
+
+```js
+const express = require('express');
+const app = express();
+```
+
+Methods
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/astro/src/content/api/5x/api/request/overview.md b/astro/src/content/api/5x/api/request/overview.md
new file mode 100644
index 0000000000..203654e039
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/overview.md
@@ -0,0 +1,160 @@
+---
+title: Properties
+description: The req object represents the HTTP request and has properties for the request query string, parameters, body, HTTP headers, and so on
+---
+
+Request
+
+The `req` object represents the HTTP request and has properties for the
+request query string, parameters, body, HTTP headers, and so on. In this documentation and by convention,
+the object is always referred to as `req` (and the HTTP response is `res`) but its actual name is determined
+by the parameters to the callback function in which you're working.
+
+For example:
+
+```js
+app.get('/user/:id', (req, res) => {
+ res.send(`user ${req.params.id}`);
+});
+```
+
+But you could just as well have:
+
+```js
+app.get('/user/:id', (request, response) => {
+ response.send(`user ${request.params.id}`);
+});
+```
+
+The `req` object is an enhanced version of Node's own request object
+and supports all [built-in fields and methods](https://nodejs.org/api/http.html#http_class_http_incomingmessage).
+
+Properties
+
+
+In Express 4, `req.files` is no longer available on the `req` object by default. To access uploaded files
+on the `req.files` object, use multipart-handling middleware like [busboy](https://www.npmjs.
+com/package/busboy), [multer](https://www.npmjs.com/package/multer),
+[formidable](https://www.npmjs.com/package/formidable),
+[multiparty](https://www.npmjs.com/package/multiparty),
+[connect-multiparty](https://www.npmjs.com/package/connect-multiparty),
+or [pez](https://www.npmjs.com/package/pez).
+
+
+
+ {% include api/en/5x/req-app.md %}
+
+
+
+ {% include api/en/5x/req-baseUrl.md %}
+
+
+
+ {% include api/en/5x/req-body.md %}
+
+
+
+ {% include api/en/5x/req-cookies.md %}
+
+
+
+ {% include api/en/5x/req-fresh.md %}
+
+
+
+ {% include api/en/5x/req-host.md %}
+
+
+
+ {% include api/en/5x/req-hostname.md %}
+
+
+
+ {% include api/en/5x/req-ip.md %}
+
+
+
+ {% include api/en/5x/req-ips.md %}
+
+
+
+ {% include api/en/5x/req-method.md %}
+
+
+
+ {% include api/en/5x/req-originalUrl.md %}
+
+
+
+ {% include api/en/5x/req-params.md %}
+
+
+
+ {% include api/en/5x/req-path.md %}
+
+
+
+ {% include api/en/5x/req-protocol.md %}
+
+
+
+ {% include api/en/5x/req-query.md %}
+
+
+
+ {% include api/en/5x/req-res.md %}
+
+
+
+ {% include api/en/5x/req-route.md %}
+
+
+
+ {% include api/en/5x/req-secure.md %}
+
+
+
+ {% include api/en/5x/req-signedCookies.md %}
+
+
+
+ {% include api/en/5x/req-stale.md %}
+
+
+
+ {% include api/en/5x/req-subdomains.md %}
+
+
+
+ {% include api/en/5x/req-xhr.md %}
+
+
+Methods
+
+
+ {% include api/en/5x/req-accepts.md %}
+
+
+
+ {% include api/en/5x/req-acceptsCharsets.md %}
+
+
+
+ {% include api/en/5x/req-acceptsEncodings.md %}
+
+
+
+ {% include api/en/5x/req-acceptsLanguages.md %}
+
+
+
+ {% include api/en/5x/req-get.md %}
+
+
+
+ {% include api/en/5x/req-is.md %}
+
+
+
+ {% include api/en/5x/req-range.md %}
+
diff --git a/astro/src/content/api/5x/api/request/req-accepts.md b/astro/src/content/api/5x/api/request/req-accepts.md
new file mode 100644
index 0000000000..763c6c6ab7
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-accepts.md
@@ -0,0 +1,41 @@
+---
+title: req.accepts
+description: Checks if the specified content types are acceptable, based on the request Accept HTTP header field.
+---
+
+req.accepts(types)
+
+Checks if the specified content types are acceptable, based on the request's `Accept` HTTP header field.
+The method returns the best match, or if none of the specified content types is acceptable, returns
+`false` (in which case, the application should respond with `406 "Not Acceptable"`).
+
+The `type` value may be a single MIME type string (such as "application/json"),
+an extension name such as "json", a comma-delimited list, or an array. For a
+list or array, the method returns the _best_ match (if any).
+
+```js
+// Accept: text/html
+req.accepts('html');
+// => "html"
+
+// Accept: text/*, application/json
+req.accepts('html');
+// => "html"
+req.accepts('text/html');
+// => "text/html"
+req.accepts(['json', 'text']);
+// => "json"
+req.accepts('application/json');
+// => "application/json"
+
+// Accept: text/*, application/json
+req.accepts('image/png');
+req.accepts('png');
+// => false
+
+// Accept: text/*;q=.5, application/json
+req.accepts(['html', 'json']);
+// => "json"
+```
+
+For more information, or if you have issues or concerns, see [accepts](https://github.com/expressjs/accepts).
diff --git a/astro/src/content/api/5x/api/request/req-acceptsCharsets.md b/astro/src/content/api/5x/api/request/req-acceptsCharsets.md
new file mode 100644
index 0000000000..69bed2797b
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-acceptsCharsets.md
@@ -0,0 +1,12 @@
+---
+title: req.acceptsCharsets
+description: Returns the first accepted charset of the specified character sets,
+---
+
+req.acceptsCharsets(charset [, ...])
+
+Returns the first accepted charset of the specified character sets,
+based on the request's `Accept-Charset` HTTP header field.
+If none of the specified charsets is accepted, returns `false`.
+
+For more information, or if you have issues or concerns, see [accepts](https://github.com/expressjs/accepts).
diff --git a/astro/src/content/api/5x/api/request/req-acceptsEncodings.md b/astro/src/content/api/5x/api/request/req-acceptsEncodings.md
new file mode 100644
index 0000000000..384e10bb6a
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-acceptsEncodings.md
@@ -0,0 +1,12 @@
+---
+title: req.acceptsEncodings
+description: Returns the first accepted encoding of the specified encodings,
+---
+
+req.acceptsEncodings(encoding [, ...])
+
+Returns the first accepted encoding of the specified encodings,
+based on the request's `Accept-Encoding` HTTP header field.
+If none of the specified encodings is accepted, returns `false`.
+
+For more information, or if you have issues or concerns, see [accepts](https://github.com/expressjs/accepts).
diff --git a/astro/src/content/api/5x/api/request/req-acceptsLanguages.md b/astro/src/content/api/5x/api/request/req-acceptsLanguages.md
new file mode 100644
index 0000000000..998805fa9e
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-acceptsLanguages.md
@@ -0,0 +1,20 @@
+---
+title: req.acceptsLanguages
+description: Returns the first accepted language of the specified languages,
+---
+
+req.acceptsLanguages([lang, ...])
+
+Returns the first accepted language of the specified languages,
+based on the request's `Accept-Language` HTTP header field.
+If none of the specified languages is accepted, returns `false`.
+
+If no `lang` argument is given, then `req.acceptsLanguages()`
+returns all languages from the HTTP `Accept-Language` header
+as an `Array`.
+
+For more information, or if you have issues or concerns, see [accepts](https://github.com/expressjs/accepts).
+
+Express (5.x) source: [request.js line 172](https://github.com/expressjs/express/blob/v5.1.0/lib/request.js#L172)
+
+Accepts (2.0) source: [index.js line 195](https://github.com/jshttp/accepts/blob/2.0.0/index.js#L195)
diff --git a/astro/src/content/api/5x/api/request/req-app.md b/astro/src/content/api/5x/api/request/req-app.md
new file mode 100644
index 0000000000..6594a0142a
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-app.md
@@ -0,0 +1,25 @@
+---
+title: req.app
+description: This property holds a reference to the instance of the Express application that is using the middleware.
+---
+
+req.app
+
+This property holds a reference to the instance of the Express application that is using the middleware.
+
+If you follow the pattern in which you create a module that just exports a middleware function
+and `require()` it in your main file, then the middleware can access the Express instance via `req.app`
+
+For example:
+
+```js
+// index.js
+app.get('/viewdirectory', require('./mymiddleware.js'));
+```
+
+```js
+// mymiddleware.js
+module.exports = (req, res) => {
+ res.send(`The views directory is ${req.app.get('views')}`);
+};
+```
diff --git a/astro/src/content/api/5x/api/request/req-base-url.md b/astro/src/content/api/5x/api/request/req-base-url.md
new file mode 100644
index 0000000000..a49e6912ca
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-base-url.md
@@ -0,0 +1,35 @@
+---
+title: req.baseUrl
+description: The URL path on which a router instance was mounted.
+---
+
+req.baseUrl
+
+The URL path on which a router instance was mounted.
+
+The `req.baseUrl` property is similar to the [mountpath](#app.mountpath) property of the `app` object,
+except `app.mountpath` returns the matched path pattern(s).
+
+For example:
+
+```js
+const greet = express.Router();
+
+greet.get('/jp', (req, res) => {
+ console.log(req.baseUrl); // /greet
+ res.send('Konichiwa!');
+});
+
+app.use('/greet', greet); // load the router on '/greet'
+```
+
+Even if you use a path pattern or a set of path patterns to load the router,
+the `baseUrl` property returns the matched string, not the pattern(s). In the
+following example, the `greet` router is loaded on two path patterns.
+
+```js
+app.use(['/gre:"param"t', '/hel{l}o'], greet); // load the router on '/gre:"param"t' and '/hel{l}o'
+```
+
+When a request is made to `/greet/jp`, `req.baseUrl` is "/greet". When a request is
+made to `/hello/jp`, `req.baseUrl` is "/hello".
diff --git a/astro/src/content/api/5x/api/request/req-body.md b/astro/src/content/api/5x/api/request/req-body.md
new file mode 100644
index 0000000000..a921f3c624
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-body.md
@@ -0,0 +1,30 @@
+---
+title: req.body
+description: Contains key-value pairs of data submitted in the request body.
+---
+
+req.body
+
+Contains key-value pairs of data submitted in the request body.
+By default, it is `undefined`, and is populated when you use body-parsing middleware such
+as [`express.json()`](#express.json) or [`express.urlencoded()`](#express.urlencoded).
+
+
+As `req.body`'s shape is based on user-controlled input, all properties and values in this object are untrusted and should be validated before trusting. For example, `req.body.foo.toString()` may fail in multiple ways, for example `foo` may not be there or may not be a string, and `toString` may not be a function and instead a string or other user-input.
+
+
+The following example shows how to use body-parsing middleware to populate `req.body`.
+
+```js
+const express = require('express');
+
+const app = express();
+
+app.use(express.json()); // for parsing application/json
+app.use(express.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
+
+app.post('/profile', (req, res, next) => {
+ console.log(req.body);
+ res.json(req.body);
+});
+```
diff --git a/astro/src/content/api/5x/api/request/req-cookies.md b/astro/src/content/api/5x/api/request/req-cookies.md
new file mode 100644
index 0000000000..806b6dc5ab
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-cookies.md
@@ -0,0 +1,19 @@
+---
+title: req.cookies
+description: When using cookie-parser middleware, this property is an object that contains cookies sent by the request
+---
+
+req.cookies
+
+When using [cookie-parser](https://www.npmjs.com/package/cookie-parser) middleware, this property is an object that
+contains cookies sent by the request. If the request contains no cookies, it defaults to `{}`.
+
+```js
+// Cookie: name=tj
+console.dir(req.cookies.name);
+// => "tj"
+```
+
+If the cookie has been signed, you have to use [req.signedCookies](#req.signedCookies).
+
+For more information, issues, or concerns, see [cookie-parser](https://github.com/expressjs/cookie-parser).
diff --git a/astro/src/content/api/5x/api/request/req-fresh.md b/astro/src/content/api/5x/api/request/req-fresh.md
new file mode 100644
index 0000000000..293c12e898
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-fresh.md
@@ -0,0 +1,18 @@
+---
+title: req.fresh
+description: When the response is still fresh in the client cache true is returned, otherwise false is returned to indicate that the client cache is now stale.
+---
+
+req.fresh
+
+When the response is still "fresh" in the client's cache `true` is returned, otherwise `false` is returned to indicate that the client cache is now stale and the full response should be sent.
+
+When a client sends the `Cache-Control: no-cache` request header to indicate an end-to-end reload request, this module will return `false` to make handling these requests transparent.
+
+Further details for how cache validation works can be found in the
+[HTTP/1.1 Caching Specification](https://tools.ietf.org/html/rfc7234).
+
+```js
+console.dir(req.fresh);
+// => true
+```
diff --git a/astro/src/content/api/5x/api/request/req-get.md b/astro/src/content/api/5x/api/request/req-get.md
new file mode 100644
index 0000000000..ad116d8421
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-get.md
@@ -0,0 +1,22 @@
+---
+title: req.get
+description: Returns the specified HTTP request header field (case-insensitive match).
+---
+
+req.get(field)
+
+Returns the specified HTTP request header field (case-insensitive match).
+The `Referrer` and `Referer` fields are interchangeable.
+
+```js
+req.get('Content-Type');
+// => "text/plain"
+
+req.get('content-type');
+// => "text/plain"
+
+req.get('Something');
+// => undefined
+```
+
+Aliased as `req.header(field)`.
diff --git a/astro/src/content/api/5x/api/request/req-host.md b/astro/src/content/api/5x/api/request/req-host.md
new file mode 100644
index 0000000000..6a61ec6be0
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-host.md
@@ -0,0 +1,27 @@
+---
+title: req.host
+description: Contains the host derived from the Host HTTP header.
+---
+
+req.host
+
+Contains the host derived from the `Host` HTTP header.
+
+When the [`trust proxy` setting](/en/api/application/app-set#app.settings.table)
+does not evaluate to `false`, this property will instead get the value
+from the `X-Forwarded-Host` header field. This header can be set by
+the client or by the proxy.
+
+If there is more than one `X-Forwarded-Host` header in the request, the
+value of the first header is used. This includes a single header with
+comma-separated values, in which the first value is used.
+
+```js
+// Host: "example.com:3000"
+console.dir(req.host);
+// => 'example.com:3000'
+
+// Host: "[::1]:3000"
+console.dir(req.host);
+// => '[::1]:3000'
+```
diff --git a/astro/src/content/api/5x/api/request/req-hostname.md b/astro/src/content/api/5x/api/request/req-hostname.md
new file mode 100644
index 0000000000..97247f67ef
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-hostname.md
@@ -0,0 +1,28 @@
+---
+title: req.hostname
+description: Contains the hostname derived from the Host HTTP header.
+---
+
+req.hostname
+
+Contains the hostname derived from the `Host` HTTP header.
+
+When the [`trust proxy` setting](/en/5x/api#trust.proxy.options.table)
+does not evaluate to `false`, this property will instead get the value
+from the `X-Forwarded-Host` header field. This header can be set by
+the client or by the proxy.
+
+If there is more than one `X-Forwarded-Host` header in the request, the
+value of the first header is used. This includes a single header with
+comma-separated values, in which the first value is used.
+
+
+Prior to Express v4.17.0, the `X-Forwarded-Host` could not contain multiple
+values or be present more than once.
+
+
+```js
+// Host: "example.com:3000"
+console.dir(req.hostname);
+// => 'example.com'
+```
diff --git a/astro/src/content/api/5x/api/request/req-ip.md b/astro/src/content/api/5x/api/request/req-ip.md
new file mode 100644
index 0000000000..eac6ea89b8
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-ip.md
@@ -0,0 +1,17 @@
+---
+title: req.ip
+description: Contains the remote IP address of the request.
+---
+
+req.ip
+
+Contains the remote IP address of the request.
+
+When the [`trust proxy` setting](/en/5x/api#trust.proxy.options.table) does not evaluate to `false`,
+the value of this property is derived from the left-most entry in the
+`X-Forwarded-For` header. This header can be set by the client or by the proxy.
+
+```js
+console.dir(req.ip);
+// => "127.0.0.1"
+```
diff --git a/astro/src/content/api/5x/api/request/req-ips.md b/astro/src/content/api/5x/api/request/req-ips.md
new file mode 100644
index 0000000000..88d70824e5
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-ips.md
@@ -0,0 +1,14 @@
+---
+title: req.ips
+description: When the trust proxy setting does not evaluate to false, this property contains an array of IP addresses specified in the X-Forwarded-For request header
+---
+
+req.ips
+
+When the [`trust proxy` setting](/en/5x/api#trust.proxy.options.table) does not evaluate to `false`,
+this property contains an array of IP addresses
+specified in the `X-Forwarded-For` request header. Otherwise, it contains an
+empty array. This header can be set by the client or by the proxy.
+
+For example, if `X-Forwarded-For` is `client, proxy1, proxy2`, `req.ips` would be
+`["client", "proxy1", "proxy2"]`, where `proxy2` is the furthest downstream.
diff --git a/astro/src/content/api/5x/api/request/req-is.md b/astro/src/content/api/5x/api/request/req-is.md
new file mode 100644
index 0000000000..3c9b22623d
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-is.md
@@ -0,0 +1,36 @@
+---
+title: req.is
+description: Returns the matching content type if the incoming request's "Content-Type" HTTP header field
+---
+
+req.is(type)
+
+Returns the matching content type if the incoming request's "Content-Type" HTTP header field
+matches the MIME type specified by the `type` parameter. If the request has no body, returns `null`.
+Returns `false` otherwise.
+
+```js
+// With Content-Type: text/html; charset=utf-8
+req.is('html'); // => 'html'
+req.is('text/html'); // => 'text/html'
+req.is('text/*'); // => 'text/*'
+
+// When Content-Type is application/json
+req.is('json'); // => 'json'
+req.is('application/json'); // => 'application/json'
+req.is('application/*'); // => 'application/*'
+
+// Using arrays
+// When Content-Type is application/json
+req.is(['json', 'html']); // => 'json'
+
+// Using multiple arguments
+// When Content-Type is application/json
+req.is('json', 'html'); // => 'json'
+
+req.is('html'); // => false
+req.is(['xml', 'yaml']); // => false
+req.is('xml', 'yaml'); // => false
+```
+
+For more information, or if you have issues or concerns, see [type-is](https://github.com/expressjs/type-is).
diff --git a/astro/src/content/api/5x/api/request/req-method.md b/astro/src/content/api/5x/api/request/req-method.md
new file mode 100644
index 0000000000..92b683bcfd
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-method.md
@@ -0,0 +1,9 @@
+---
+title: req.method
+description: Contains a string corresponding to the HTTP method of the request
+---
+
+req.method
+
+Contains a string corresponding to the HTTP method of the request:
+`GET`, `POST`, `PUT`, and so on.
diff --git a/astro/src/content/api/5x/api/request/req-originalUrl.md b/astro/src/content/api/5x/api/request/req-originalUrl.md
new file mode 100644
index 0000000000..c7d4b142ed
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-originalUrl.md
@@ -0,0 +1,33 @@
+---
+title: req.originalUrl
+description: req.url is not a native Express property, it is inherited from Node http module
+---
+
+req.originalUrl
+
+
+`req.url` is not a native Express property, it is inherited from Node's [http module](https://nodejs.org/api/http.html#http_message_url).
+
+
+This property is much like `req.url`; however, it retains the original request URL,
+allowing you to rewrite `req.url` freely for internal routing purposes. For example,
+the "mounting" feature of [app.use()](#app.use) will rewrite `req.url` to strip the mount point.
+
+```js
+// GET /search?q=something
+console.dir(req.originalUrl);
+// => "/search?q=something"
+```
+
+`req.originalUrl` is available both in middleware and router objects, and is a
+combination of `req.baseUrl` and `req.url`. Consider following example:
+
+```js
+// GET 'http://www.example.com/admin/new?sort=desc'
+app.use('/admin', (req, res, next) => {
+ console.dir(req.originalUrl); // '/admin/new?sort=desc'
+ console.dir(req.baseUrl); // '/admin'
+ console.dir(req.path); // '/new'
+ next();
+});
+```
diff --git a/astro/src/content/api/5x/api/request/req-params.md b/astro/src/content/api/5x/api/request/req-params.md
new file mode 100644
index 0000000000..fd2531cf6f
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-params.md
@@ -0,0 +1,44 @@
+---
+title: req.params
+description: This property is an object containing properties mapped to the [named route "parameters"](/en/guide/routing#route-parameters). Fo...
+---
+
+req.params
+
+This property is an object containing properties mapped to the [named route "parameters"](/en/guide/routing#route-parameters). For example, if you have the route `/user/:name`, then the "name" property is available as `req.params.name`. This object defaults to `Object.create(null)` when using string paths, but remains a standard object with a normal prototype when the path is defined with a regular expression.
+
+```js
+// GET /user/tj
+console.dir(req.params.name);
+// => "tj"
+```
+
+Properties corresponding to wildcard parameters are arrays containing separate path segments split on `/`:
+
+```js
+app.get('/files/*file', (req, res) => {
+ console.dir(req.params.file);
+ // GET /files/note.txt
+ // => [ 'note.txt' ]
+ // GET /files/images/image.png
+ // => [ 'images', 'image.png' ]
+});
+```
+
+When you use a regular expression for the route definition, capture groups are provided as integer keys using `req.params[n]`, where `n` is the nth capture group.
+
+```js
+app.use(/^\/file\/(.*)$/, (req, res) => {
+ // GET /file/javascripts/jquery.js
+ console.dir(req.params[0]);
+ // => "javascripts/jquery.js"
+});
+```
+
+Named capturing groups in regular expressions behave like named route parameters. For example the group from `/^\/file\/(?.*)$/` expression is available as `req.params.path`.
+
+If you need to make changes to a key in `req.params`, use the [app.param](/en/5x/api#app.param) handler. Changes are applicable only to [parameters](/en/guide/routing#route-parameters) already defined in the route path.
+
+Any changes made to the `req.params` object in a middleware or route handler will be reset.
+
+{% include admonitions/note.html content="Express automatically decodes the values in `req.params` (using `decodeURIComponent`)." %}
diff --git a/astro/src/content/api/5x/api/request/req-path.md b/astro/src/content/api/5x/api/request/req-path.md
new file mode 100644
index 0000000000..2214b9cfb6
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-path.md
@@ -0,0 +1,18 @@
+---
+title: req.path
+description: Contains the path part of the request URL.
+---
+
+req.path
+
+Contains the path part of the request URL.
+
+```js
+// example.com/users?sort=desc
+console.dir(req.path);
+// => "/users"
+```
+
+
+When called from a middleware, the mount point is not included in `req.path`. See [app.use()](/en/5x/api#app.use) for more details.
+
diff --git a/astro/src/content/api/5x/api/request/req-protocol.md b/astro/src/content/api/5x/api/request/req-protocol.md
new file mode 100644
index 0000000000..082e784b47
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-protocol.md
@@ -0,0 +1,17 @@
+---
+title: req.protocol
+description: Contains the request protocol string either http or (for TLS requests) https.
+---
+
+req.protocol
+
+Contains the request protocol string: either `http` or (for TLS requests) `https`.
+
+When the [`trust proxy` setting](#trust.proxy.options.table) does not evaluate to `false`,
+this property will use the value of the `X-Forwarded-Proto` header field if present.
+This header can be set by the client or by the proxy.
+
+```js
+console.dir(req.protocol);
+// => "http"
+```
diff --git a/astro/src/content/api/5x/api/request/req-query.md b/astro/src/content/api/5x/api/request/req-query.md
new file mode 100644
index 0000000000..5734720a9c
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-query.md
@@ -0,0 +1,26 @@
+---
+title: req.query
+description: This property is an object containing a property for each query string parameter in the route.
+---
+
+req.query
+
+This property is an object containing a property for each query string parameter in the route.
+When [query parser](/en/api/application/app-set#app.settings.table) is set to disabled, it is an empty object `{}`, otherwise it is the result of the configured query parser.
+
+
+As `req.query`'s shape is based on user-controlled input, all properties and values in this object are untrusted and should be validated before trusting. For example, `req.query.foo.toString()` may fail in multiple ways, for example `foo` may not be there or may not be a string, and `toString` may not be a function and instead a string or other user-input.
+
+
+The value of this property can be configured with the [query parser application setting](/en/api/application/app-set#app.settings.table) to work how your application needs it. A very popular query string parser is the [`qs` module](https://www.npmjs.org/package/qs), and this is used by default. The `qs` module is very configurable with many settings, and it may be desirable to use different settings than the default to populate `req.query`:
+
+```js
+const qs = require('qs');
+app.set('query parser', (str) =>
+ qs.parse(str, {
+ /* custom options */
+ })
+);
+```
+
+Check out the [query parser application setting](/en/api/application/app-set#app.settings.table) documentation for other customization options.
diff --git a/astro/src/content/api/5x/api/request/req-range.md b/astro/src/content/api/5x/api/request/req-range.md
new file mode 100644
index 0000000000..6c103987a2
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-range.md
@@ -0,0 +1,38 @@
+---
+title: req.range
+description: Range header parser
+---
+
+req.range(size[, options])
+
+`Range` header parser.
+
+The `size` parameter is the maximum size of the resource.
+
+The `options` parameter is an object that can have the following properties.
+
+
+
+| Property | Type | Description |
+| --------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `combine` | Boolean | Specify if overlapping & adjacent ranges should be combined, defaults to `false`. When `true`, ranges will be combined and returned as if they were specified that way in the header. |
+
+
+
+An array of ranges will be returned or negative numbers indicating an error parsing.
+
+- `-2` signals a malformed header string
+- `-1` signals an unsatisfiable range
+
+```js
+// parse header from request
+const range = req.range(1000);
+
+// the type of the range
+if (range.type === 'bytes') {
+ // the ranges
+ range.forEach((r) => {
+ // do something with r.start and r.end
+ });
+}
+```
diff --git a/astro/src/content/api/5x/api/request/req-res.md b/astro/src/content/api/5x/api/request/req-res.md
new file mode 100644
index 0000000000..94e5554756
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-res.md
@@ -0,0 +1,9 @@
+---
+title: req.res
+description: This property holds a reference to the
+---
+
+req.res
+
+This property holds a reference to the response object
+that relates to this request object.
diff --git a/astro/src/content/api/5x/api/request/req-route.md b/astro/src/content/api/5x/api/request/req-route.md
new file mode 100644
index 0000000000..d2a3159b3b
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-route.md
@@ -0,0 +1,36 @@
+---
+title: req.route
+description: Contains the currently-matched route, a string
+---
+
+req.route
+
+Contains the currently-matched route, a string. For example:
+
+```js
+app.get('/user/{:id}', (req, res) => {
+ console.dir(req.route, { depth: null });
+ res.send('GET');
+});
+```
+
+Example output from the previous snippet:
+
+```
+Route {
+ path: '/user/{:id}',
+ stack: [
+ Layer {
+ handle: [Function (anonymous)],
+ keys: [],
+ name: '',
+ params: undefined,
+ path: undefined,
+ slash: false,
+ matchers: [ [Function: match] ],
+ method: 'get'
+ }
+ ],
+ methods: [Object: null prototype] { get: true }
+}
+```
diff --git a/astro/src/content/api/5x/api/request/req-secure.md b/astro/src/content/api/5x/api/request/req-secure.md
new file mode 100644
index 0000000000..d3f86bdcd2
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-secure.md
@@ -0,0 +1,14 @@
+---
+title: req.secure
+description: A Boolean property that is true if a TLS connection is established. Equivalent to the following code.
+---
+
+req.secure
+
+A Boolean property that is true if a TLS connection is established. Equivalent to the following:
+
+
+
+```js
+req.protocol === 'https';
+```
diff --git a/astro/src/content/api/5x/api/request/req-signedCookies.md b/astro/src/content/api/5x/api/request/req-signedCookies.md
new file mode 100644
index 0000000000..b573fc082e
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-signedCookies.md
@@ -0,0 +1,22 @@
+---
+title: req.signedCookies
+description: When using cookie-parser middleware, this property contains signed cookies sent by the request
+---
+
+req.signedCookies
+
+When using [cookie-parser](https://www.npmjs.com/package/cookie-parser) middleware, this property
+contains signed cookies sent by the request, unsigned and ready for use. Signed cookies reside
+in a different object to show developer intent; otherwise, a malicious attack could be placed on
+`req.cookie` values (which are easy to spoof). Note that signing a cookie does not make it "hidden"
+or encrypted; but simply prevents tampering (because the secret used to sign is private).
+
+If no signed cookies are sent, the property defaults to `{}`.
+
+```js
+// Cookie: user=tobi.CP7AWaXDfAKIRfH49dQzKJx7sKzzSoPq7/AcBBRVwlI3
+console.dir(req.signedCookies.user);
+// => "tobi"
+```
+
+For more information, issues, or concerns, see [cookie-parser](https://github.com/expressjs/cookie-parser).
diff --git a/astro/src/content/api/5x/api/request/req-stale.md b/astro/src/content/api/5x/api/request/req-stale.md
new file mode 100644
index 0000000000..b39f5cb5ef
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-stale.md
@@ -0,0 +1,14 @@
+---
+title: req.stale
+description: Indicates whether the request is stale, and is the opposite of req.fresh.
+---
+
+req.stale
+
+Indicates whether the request is "stale," and is the opposite of `req.fresh`.
+For more information, see [req.fresh](#req.fresh).
+
+```js
+console.dir(req.stale);
+// => true
+```
diff --git a/astro/src/content/api/5x/api/request/req-subdomains.md b/astro/src/content/api/5x/api/request/req-subdomains.md
new file mode 100644
index 0000000000..3f05bccac0
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-subdomains.md
@@ -0,0 +1,18 @@
+---
+title: req.subdomains
+description: An array of subdomains in the domain name of the request.
+---
+
+req.subdomains
+
+An array of subdomains in the domain name of the request.
+
+```js
+// Host: "tobi.ferrets.example.com"
+console.dir(req.subdomains);
+// => ["ferrets", "tobi"]
+```
+
+The application property `subdomain offset`, which defaults to 2, is used for determining the
+beginning of the subdomain segments. To change this behavior, change its value
+using [app.set](/en/5x/api#app.set).
diff --git a/astro/src/content/api/5x/api/request/req-xhr.md b/astro/src/content/api/5x/api/request/req-xhr.md
new file mode 100644
index 0000000000..f247d20b05
--- /dev/null
+++ b/astro/src/content/api/5x/api/request/req-xhr.md
@@ -0,0 +1,14 @@
+---
+title: req.xhr
+description: A Boolean property that is true if the request X-Requested-With header field is "XMLHttpRequest"
+---
+
+req.xhr
+
+A Boolean property that is `true` if the request's `X-Requested-With` header field is
+"XMLHttpRequest", indicating that the request was issued by a client library such as jQuery.
+
+```js
+console.dir(req.xhr);
+// => true
+```
diff --git a/astro/src/content/api/5x/api/response/overview.md b/astro/src/content/api/5x/api/response/overview.md
new file mode 100644
index 0000000000..ac989a33d8
--- /dev/null
+++ b/astro/src/content/api/5x/api/response/overview.md
@@ -0,0 +1,135 @@
+---
+title: Properties
+description: section markdown="1">
+---
+
+Response
+
+The `res` object represents the HTTP response that an Express app sends when it gets an HTTP request.
+
+In this documentation and by convention,
+the object is always referred to as `res` (and the HTTP request is `req`) but its actual name is determined
+by the parameters to the callback function in which you're working.
+
+For example:
+
+```js
+app.get('/user/:id', (req, res) => {
+ res.send(`user ${req.params.id}`);
+});
+```
+
+But you could just as well have:
+
+```js
+app.get('/user/:id', (request, response) => {
+ response.send(`user ${request.params.id}`);
+});
+```
+
+The `res` object is an enhanced version of Node's own response object
+and supports all [built-in fields and methods](https://nodejs.org/api/http.html#http_class_http_serverresponse).
+
+Properties
+
+
+ {% include api/en/5x/res-app.md %}
+
+
+
+ {% include api/en/5x/res-headersSent.md %}
+
+
+
+ {% include api/en/5x/res-locals.md %}
+
+
+
+ {% include api/en/5x/res-req.md %}
+
+
+Methods
+
+
+ {% include api/en/5x/res-append.md %}
+
+
+
+ {% include api/en/5x/res-attachment.md %}
+
+
+
+ {% include api/en/5x/res-cookie.md %}
+
+
+
+ {% include api/en/5x/res-clearCookie.md %}
+
+
+
+ {% include api/en/5x/res-download.md %}
+
+
+
+ {% include api/en/5x/res-end.md %}
+
+
+
+ {% include api/en/5x/res-format.md %}
+
+
+
+ {% include api/en/5x/res-get.md %}
+
+
+
+ {% include api/en/5x/res-json.md %}
+
+
+
+ {% include api/en/5x/res-jsonp.md %}
+
+
+
+ {% include api/en/5x/res-links.md %}
+
+
+
+ {% include api/en/5x/res-location.md %}
+
+
+
+ {% include api/en/5x/res-redirect.md %}
+
+
+
+ {% include api/en/5x/res-render.md %}
+
+
+
+ {% include api/en/5x/res-send.md %}
+
+
+
+ {% include api/en/5x/res-sendFile.md %}
+
+
+
+ {% include api/en/5x/res-sendStatus.md %}
+
+
+
+ {% include api/en/5x/res-set.md %}
+
+
+
+ {% include api/en/5x/res-status.md %}
+
+
+
+ {% include api/en/5x/res-type.md %}
+
+
+
+ {% include api/en/5x/res-vary.md %}
+
diff --git a/astro/src/content/api/5x/api/response/res-app.md b/astro/src/content/api/5x/api/response/res-app.md
new file mode 100644
index 0000000000..b853d54dd3
--- /dev/null
+++ b/astro/src/content/api/5x/api/response/res-app.md
@@ -0,0 +1,10 @@
+---
+title: res.app
+description: This property holds a reference to the instance of the Express application that is using the middleware.
+---
+
+res.app
+
+This property holds a reference to the instance of the Express application that is using the middleware.
+
+`res.app` is identical to the [req.app](#req.app) property in the request object.
diff --git a/astro/src/content/api/5x/api/response/res-append.md b/astro/src/content/api/5x/api/response/res-append.md
new file mode 100644
index 0000000000..abda903e81
--- /dev/null
+++ b/astro/src/content/api/5x/api/response/res-append.md
@@ -0,0 +1,21 @@
+---
+title: res.append
+description: res.append appends the specified value to the HTTP response header field
+---
+
+res.append(field [, value])
+
+
+`res.append()` is supported by Express v4.11.0+
+
+
+Appends the specified `value` to the HTTP response header `field`. If the header is not already set,
+it creates the header with the specified value. The `value` parameter can be a string or an array.
+
+{% include admonitions/note.html content="calling `res.set()` after `res.append()` will reset the previously-set header value." %}
+
+```js
+res.append('Link', [' ', ' ']);
+res.append('Set-Cookie', 'foo=bar; Path=/; HttpOnly');
+res.append('Warning', '199 Miscellaneous warning');
+```
diff --git a/astro/src/content/api/5x/api/response/res-attachment.md b/astro/src/content/api/5x/api/response/res-attachment.md
new file mode 100644
index 0000000000..7d667eedd4
--- /dev/null
+++ b/astro/src/content/api/5x/api/response/res-attachment.md
@@ -0,0 +1,19 @@
+---
+title: res.attachment
+description: Sets the HTTP response Content-Disposition header field to attachment
+---
+
+res.attachment([filename])
+
+Sets the HTTP response `Content-Disposition` header field to "attachment". If a `filename` is given,
+then it sets the `Content-Type` based on the extension name via `res.type()`,
+and sets the `Content-Disposition` "filename=" parameter.
+
+```js
+res.attachment();
+// Content-Disposition: attachment
+
+res.attachment('path/to/logo.png');
+// Content-Disposition: attachment; filename="logo.png"
+// Content-Type: image/png
+```
diff --git a/astro/src/content/api/5x/api/response/res-clearCookie.md b/astro/src/content/api/5x/api/response/res-clearCookie.md
new file mode 100644
index 0000000000..f2738bf189
--- /dev/null
+++ b/astro/src/content/api/5x/api/response/res-clearCookie.md
@@ -0,0 +1,24 @@
+---
+title: res.clearCookie
+description: Clears the cookie with the specified name by sending a Set-Cookie header that sets its expiration date in the past.
+---
+
+res.clearCookie(name [, options])
+
+Clears the cookie with the specified `name` by sending a `Set-Cookie` header that sets its expiration date in the past.
+This instructs the client that the cookie has expired and is no longer valid. For more information
+about available `options`, see [res.cookie()](#res.cookie).
+
+
+The `expires` and `max-age` options are being ignored completely.
+
+
+
+Web browsers and other compliant clients will only clear the cookie if the given
+`options` is identical to those given to [res.cookie()](#res.cookie)
+
+
+```js
+res.cookie('name', 'tobi', { path: '/admin' });
+res.clearCookie('name', { path: '/admin' });
+```
diff --git a/astro/src/content/api/5x/api/response/res-cookie.md b/astro/src/content/api/5x/api/response/res-cookie.md
new file mode 100644
index 0000000000..ab7e81de34
--- /dev/null
+++ b/astro/src/content/api/5x/api/response/res-cookie.md
@@ -0,0 +1,95 @@
+---
+title: res.cookie
+description: Sets cookie name to value. The value parameter may be a string or object converted to JSON.
+---
+
+res.cookie(name, value [, options])
+
+Sets cookie `name` to `value`. The `value` parameter may be a string or object converted to JSON.
+
+The `options` parameter is an object that can have the following properties.
+
+
+
+| Property | Type | Description |
+| ------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `domain` | String | Domain name for the cookie. Defaults to the domain name of the app. |
+| `encode` | Function | A synchronous function used for cookie value encoding. Defaults to `encodeURIComponent`. |
+| `expires` | Date | Expiry date of the cookie in GMT. If not specified or set to 0, creates a session cookie. |
+| `httpOnly` | Boolean | Flags the cookie to be accessible only by the web server. |
+| `maxAge` | Number | Convenient option for setting the expiry time relative to the current time in milliseconds. |
+| `path` | String | Path for the cookie. Defaults to "/". |
+| `partitioned` | Boolean | Indicates that the cookie should be stored using partitioned storage. See [Cookies Having Independent Partitioned State (CHIPS)](https://developer.mozilla.org/en-US/docs/Web/Privacy/Partitioned_cookies) for more details. |
+| `priority` | String | Value of the "Priority" **Set-Cookie** attribute. |
+| `secure` | Boolean | Marks the cookie to be used with HTTPS only. |
+| `signed` | Boolean | Indicates if the cookie should be signed. |
+| `sameSite` | Boolean or String | Value of the "SameSite" **Set-Cookie** attribute. More information at [https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00#section-4.1.1](https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00#section-4.1.1). |
+
+
+
+
+All `res.cookie()` does is set the HTTP `Set-Cookie` header with the options provided.
+Any option not specified defaults to the value stated in [RFC 6265](http://tools.ietf.org/html/rfc6265).
+
+
+For example:
+
+```js
+res.cookie('name', 'tobi', { domain: '.example.com', path: '/admin', secure: true });
+res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true });
+```
+
+You can set multiple cookies in a single response by calling `res.cookie` multiple times, for example:
+
+```js
+res
+ .status(201)
+ .cookie('access_token', `Bearer ${token}`, {
+ expires: new Date(Date.now() + 8 * 3600000), // cookie will be removed after 8 hours
+ })
+ .cookie('test', 'test')
+ .redirect(301, '/admin');
+```
+
+The `encode` option allows you to choose the function used for cookie value encoding.
+Does not support asynchronous functions.
+
+Example use case: You need to set a domain-wide cookie for another site in your organization.
+This other site (not under your administrative control) does not use URI-encoded cookie values.
+
+```js
+// Default encoding
+res.cookie('some_cross_domain_cookie', 'http://mysubdomain.example.com', { domain: 'example.com' });
+// Result: 'some_cross_domain_cookie=http%3A%2F%2Fmysubdomain.example.com; Domain=example.com; Path=/'
+
+// Custom encoding
+res.cookie('some_cross_domain_cookie', 'http://mysubdomain.example.com', {
+ domain: 'example.com',
+ encode: String,
+});
+// Result: 'some_cross_domain_cookie=http://mysubdomain.example.com; Domain=example.com; Path=/;'
+```
+
+The `maxAge` option is a convenience option for setting "expires" relative to the current time in milliseconds.
+The following is equivalent to the second example above.
+
+```js
+res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true });
+```
+
+You can pass an object as the `value` parameter; it is then serialized as JSON and parsed by `bodyParser()` middleware.
+
+```js
+res.cookie('cart', { items: [1, 2, 3] });
+res.cookie('cart', { items: [1, 2, 3] }, { maxAge: 900000 });
+```
+
+When using [cookie-parser](https://www.npmjs.com/package/cookie-parser) middleware, this method also
+supports signed cookies. Simply include the `signed` option set to `true`.
+Then, `res.cookie()` will use the secret passed to `cookieParser(secret)` to sign the value.
+
+```js
+res.cookie('name', 'tobi', { signed: true });
+```
+
+Later, you may access this value through the [req.signedCookies](#req.signedCookies) object.
diff --git a/astro/src/content/api/5x/api/response/res-download.md b/astro/src/content/api/5x/api/response/res-download.md
new file mode 100644
index 0000000000..42eb6db49f
--- /dev/null
+++ b/astro/src/content/api/5x/api/response/res-download.md
@@ -0,0 +1,66 @@
+---
+title: res.download
+description: res.download provides access to data on the running file system
+---
+
+res.download(path [, filename] [, options] [, fn])
+
+
+The optional `options` argument is supported by Express v4.16.0 onwards.
+
+
+Transfers the file at `path` as an "attachment". Typically, browsers will prompt the user for download.
+By default, the `Content-Disposition` header "filename=" parameter is derived from the `path` argument, but can be overridden with the `filename` parameter.
+If `path` is relative, then it will be based on the current working directory of the process or
+the `root` option, if provided.
+
+
+This API provides access to data on the running file system. Ensure that either (a) the way in
+which the `path` argument was constructed is secure if it contains user input or (b) set the `root`
+option to the absolute path of a directory to contain access within.
+
+When the `root` option is provided, Express will validate that the relative path provided as
+`path` will resolve within the given `root` option.
+
+
+
+The following table provides details on the `options` parameter.
+
+
+The optional `options` argument is supported by Express v4.16.0 onwards.
+
+
+
+
+| Property | Description | Default | Availability |
+| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------ |
+| `maxAge` | Sets the max-age property of the `Cache-Control` header in milliseconds or a string in [ms format](https://www.npmjs.org/package/ms) | 0 | 4.16+ |
+| `root` | Root directory for relative filenames. | | 4.18+ |
+| `lastModified` | Sets the `Last-Modified` header to the last modified date of the file on the OS. Set `false` to disable it. | Enabled | 4.16+ |
+| `headers` | Object containing HTTP headers to serve with the file. The header `Content-Disposition` will be overridden by the `filename` argument. | | 4.16+ |
+| `dotfiles` | Option for serving dotfiles. Possible values are "allow", "deny", "ignore". | "ignore" | 4.16+ |
+| `acceptRanges` | Enable or disable accepting ranged requests. | `true` | 4.16+ |
+| `cacheControl` | Enable or disable setting `Cache-Control` response header. | `true` | 4.16+ |
+| `immutable` | Enable or disable the `immutable` directive in the `Cache-Control` response header. If enabled, the `maxAge` option should also be specified to enable caching. The `immutable` directive will prevent supported clients from making conditional requests during the life of the `maxAge` option to check if the file has changed. | `false` | 4.16+ |
+
+
+
+The method invokes the callback function `fn(err)` when the transfer is complete
+or when an error occurs. If the callback function is specified and an error occurs,
+the callback function must explicitly handle the response process either by
+ending the request-response cycle, or by passing control to the next route.
+
+```js
+res.download('/report-12345.pdf');
+
+res.download('/report-12345.pdf', 'report.pdf');
+
+res.download('/report-12345.pdf', 'report.pdf', (err) => {
+ if (err) {
+ // Handle error, but keep in mind the response may be partially-sent
+ // so check res.headersSent
+ } else {
+ // decrement a download credit, etc.
+ }
+});
+```
diff --git a/astro/src/content/api/5x/api/response/res-end.md b/astro/src/content/api/5x/api/response/res-end.md
new file mode 100644
index 0000000000..1d59764120
--- /dev/null
+++ b/astro/src/content/api/5x/api/response/res-end.md
@@ -0,0 +1,15 @@
+---
+title: res.end
+description: Ends the response process. This method actually comes from Node core, specifically the response.end method of http.ServerResponse.
+---
+
+res.end([data[, encoding]][, callback])
+
+Ends the response process. This method actually comes from Node core, specifically the [response.end() method of http.ServerResponse](https://nodejs.org/api/http.html#responseenddata-encoding-callback).
+
+Use to quickly end the response without any data. If you need to respond with data, instead use methods such as [res.send()](#res.send) and [res.json()](#res.json).
+
+```js
+res.end();
+res.status(404).end();
+```
diff --git a/astro/src/content/api/5x/api/response/res-format.md b/astro/src/content/api/5x/api/response/res-format.md
new file mode 100644
index 0000000000..92e7c40e45
--- /dev/null
+++ b/astro/src/content/api/5x/api/response/res-format.md
@@ -0,0 +1,57 @@
+---
+title: res.format
+description: Performs content-negotiation on the Accept HTTP header on the request object, when present.
+---
+
+
+
+Performs content-negotiation on the `Accept` HTTP header on the request object, when present.
+It uses [req.accepts()](#req.accepts) to select a handler for the request, based on the acceptable
+types ordered by their quality values. If the header is not specified, the first callback is invoked.
+When no match is found, the server responds with 406 "Not Acceptable", or invokes the `default` callback.
+
+The `Content-Type` response header is set when a callback is selected. However, you may alter
+this within the callback using methods such as `res.set()` or `res.type()`.
+
+The following example would respond with `{ "message": "hey" }` when the `Accept` header field is set
+to "application/json" or "\*/json" (however, if it is "\*/\*", then the response will be "hey").
+
+```js
+res.format({
+ 'text/plain'() {
+ res.send('hey');
+ },
+
+ 'text/html'() {
+ res.send('hey
');
+ },
+
+ 'application/json'() {
+ res.send({ message: 'hey' });
+ },
+
+ default() {
+ // log the request and respond with 406
+ res.status(406).send('Not Acceptable');
+ },
+});
+```
+
+In addition to canonicalized MIME types, you may also use extension names mapped
+to these types for a slightly less verbose implementation:
+
+```js
+res.format({
+ text() {
+ res.send('hey');
+ },
+
+ html() {
+ res.send('hey
');
+ },
+
+ json() {
+ res.send({ message: 'hey' });
+ },
+});
+```
diff --git a/astro/src/content/api/5x/api/response/res-get.md b/astro/src/content/api/5x/api/response/res-get.md
new file mode 100644
index 0000000000..300dd9d1a9
--- /dev/null
+++ b/astro/src/content/api/5x/api/response/res-get.md
@@ -0,0 +1,14 @@
+---
+title: res.get
+description: Returns the HTTP response header specified by field.
+---
+
+res.get(field)
+
+Returns the HTTP response header specified by `field`.
+The match is case-insensitive.
+
+```js
+res.get('Content-Type');
+// => "text/plain"
+```
diff --git a/astro/src/content/api/5x/api/response/res-headersSent.md b/astro/src/content/api/5x/api/response/res-headersSent.md
new file mode 100644
index 0000000000..ed9b41069e
--- /dev/null
+++ b/astro/src/content/api/5x/api/response/res-headersSent.md
@@ -0,0 +1,16 @@
+---
+title: res.headersSent
+description: Boolean property that indicates if the app sent HTTP headers for the response.
+---
+
+
+
+Boolean property that indicates if the app sent HTTP headers for the response.
+
+```js
+app.get('/', (req, res) => {
+ console.log(res.headersSent); // false
+ res.send('OK');
+ console.log(res.headersSent); // true
+});
+```
diff --git a/astro/src/content/api/5x/api/response/res-json.md b/astro/src/content/api/5x/api/response/res-json.md
new file mode 100644
index 0000000000..40d6c0c083
--- /dev/null
+++ b/astro/src/content/api/5x/api/response/res-json.md
@@ -0,0 +1,18 @@
+---
+title: res.json
+description: Sends a JSON response. This method sends a response (with the correct content-type) that is the parameter converted to a
+---
+
+res.json([body])
+
+Sends a JSON response. This method sends a response (with the correct content-type) that is the parameter converted to a
+JSON string using [JSON.stringify()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify).
+
+The parameter can be any JSON type, including object, array, string, Boolean, number, or null,
+and you can also use it to convert other values to JSON.
+
+```js
+res.json(null);
+res.json({ user: 'tobi' });
+res.status(500).json({ error: 'message' });
+```
diff --git a/astro/src/content/api/5x/api/response/res-jsonp.md b/astro/src/content/api/5x/api/response/res-jsonp.md
new file mode 100644
index 0000000000..2e19c08337
--- /dev/null
+++ b/astro/src/content/api/5x/api/response/res-jsonp.md
@@ -0,0 +1,37 @@
+---
+title: res.jsonp
+description: Sends a JSON response with JSONP support. This method is identical to res.json,
+---
+
+res.jsonp([body])
+
+Sends a JSON response with JSONP support. This method is identical to `res.json()`,
+except that it opts-in to JSONP callback support.
+
+```js
+res.jsonp(null);
+// => callback(null)
+
+res.jsonp({ user: 'tobi' });
+// => callback({ "user": "tobi" })
+
+res.status(500).jsonp({ error: 'message' });
+// => callback({ "error": "message" })
+```
+
+By default, the JSONP callback name is simply `callback`. Override this with the
+jsonp callback name setting.
+
+The following are some examples of JSONP responses using the same code:
+
+```js
+// ?callback=foo
+res.jsonp({ user: 'tobi' });
+// => foo({ "user": "tobi" })
+
+app.set('jsonp callback name', 'cb');
+
+// ?cb=foo
+res.status(500).jsonp({ error: 'message' });
+// => foo({ "error": "message" })
+```
diff --git a/astro/src/content/api/5x/api/response/res-links.md b/astro/src/content/api/5x/api/response/res-links.md
new file mode 100644
index 0000000000..db6aaba927
--- /dev/null
+++ b/astro/src/content/api/5x/api/response/res-links.md
@@ -0,0 +1,25 @@
+---
+title: res.links
+description: Joins the links provided as properties of the parameter to populate the response Link HTTP header field
+---
+
+res.links(links)
+
+Joins the `links` provided as properties of the parameter to populate the response's
+`Link` HTTP header field.
+
+For example, the following call:
+
+```js
+res.links({
+ next: 'http://api.example.com/users?page=2',
+ last: 'http://api.example.com/users?page=5',
+});
+```
+
+Yields the following results:
+
+```
+Link: ; rel="next",
+ ; rel="last"
+```
diff --git a/astro/src/content/api/5x/api/response/res-locals.md b/astro/src/content/api/5x/api/response/res-locals.md
new file mode 100644
index 0000000000..d2cf8c9b85
--- /dev/null
+++ b/astro/src/content/api/5x/api/response/res-locals.md
@@ -0,0 +1,33 @@
+---
+title: res.locals
+description: Use this property to set variables accessible in templates rendered with [res.render](#res.render).
+---
+
+res.locals
+
+Use this property to set variables accessible in templates rendered with [res.render](#res.render).
+The variables set on `res.locals` are available within a single request-response cycle, and will not
+be shared between requests.
+
+
+The `locals` object is used by view engines to render a response. The object
+keys may be particularly sensitive and should not contain user-controlled
+input, as it may affect the operation of the view engine or provide a path to
+cross-site scripting. Consult the documentation for the used view engine for
+additional considerations.
+
+
+In order to keep local variables for use in template rendering between requests, use
+[app.locals](#app.locals) instead.
+
+This property is useful for exposing request-level information such as the request path name,
+authenticated user, user settings, and so on to templates rendered within the application.
+
+```js
+app.use((req, res, next) => {
+ // Make `user` and `authenticated` available in templates
+ res.locals.user = req.user;
+ res.locals.authenticated = !req.user.anonymous;
+ next();
+});
+```
diff --git a/astro/src/content/api/5x/api/response/res-location.md b/astro/src/content/api/5x/api/response/res-location.md
new file mode 100644
index 0000000000..37104a0eb3
--- /dev/null
+++ b/astro/src/content/api/5x/api/response/res-location.md
@@ -0,0 +1,22 @@
+---
+title: res.location
+description: Sets the response Location HTTP header to the specified path parameter.
+---
+
+res.location(path)
+
+Sets the response `Location` HTTP header to the specified `path` parameter.
+
+```js
+res.location('/foo/bar');
+res.location('http://example.com');
+```
+
+
+After encoding the URL, if not encoded already, Express passes the specified URL to the browser in the `Location` header,
+without any validation.
+
+Browsers take the responsibility of deriving the intended URL from the current URL
+or the referring URL, and the URL specified in the `Location` header; and redirect the user accordingly.
+
+
diff --git a/astro/src/content/api/5x/api/response/res-redirect.md b/astro/src/content/api/5x/api/response/res-redirect.md
new file mode 100644
index 0000000000..b140fdba20
--- /dev/null
+++ b/astro/src/content/api/5x/api/response/res-redirect.md
@@ -0,0 +1,56 @@
+---
+title: res.redirect
+description: Redirects to the URL derived from the specified path, with specified status, a positive integer
+---
+
+res.redirect([status,] path)
+
+Redirects to the URL derived from the specified `path`, with specified `status`, a positive integer
+that corresponds to an [HTTP status code](https://www.rfc-editor.org/rfc/rfc9110#name-status-codes).
+If not specified, `status` defaults to `302 "Found"`.
+
+```js
+res.redirect('/foo/bar');
+res.redirect('http://example.com');
+res.redirect(301, 'http://example.com');
+res.redirect('../login');
+```
+
+Redirects can be a fully-qualified URL for redirecting to a different site:
+
+```js
+res.redirect('http://google.com');
+```
+
+Redirects can be relative to the root of the host name. For example, if the
+application is on `http://example.com/admin/post/new`, the following
+would redirect to the URL `http://example.com/admin`:
+
+```js
+res.redirect('/admin');
+```
+
+Redirects can be relative to the current URL. For example,
+from `http://example.com/blog/admin/` (notice the trailing slash), the following
+would redirect to the URL `http://example.com/blog/admin/post/new`.
+
+```js
+res.redirect('post/new');
+```
+
+Redirecting to `post/new` from `http://example.com/blog/admin` (no trailing slash),
+will redirect to `http://example.com/blog/post/new`.
+
+If you found the above behavior confusing, think of path segments as directories
+(with trailing slashes) and files, it will start to make sense.
+
+Path-relative redirects are also possible. If you were on
+`http://example.com/admin/post/new`, the following would redirect to
+`http://example.com/admin/post`:
+
+```js
+res.redirect('..');
+```
+
+See also [Security best practices: Prevent open redirect
+vulnerabilities](http://expressjs.com/en/advanced/best-practice-security#prevent-open-redirects).
diff --git a/astro/src/content/api/5x/api/response/res-render.md b/astro/src/content/api/5x/api/response/res-render.md
new file mode 100644
index 0000000000..4e66066146
--- /dev/null
+++ b/astro/src/content/api/5x/api/response/res-render.md
@@ -0,0 +1,42 @@
+---
+title: res.render
+description: Renders a view and sends the rendered HTML string to the client.
+---
+
+res.render(view [, locals] [, callback])
+
+Renders a `view` and sends the rendered HTML string to the client.
+Optional parameters:
+
+- `locals`, an object whose properties define local variables for the view.
+- `callback`, a callback function. If provided, the method returns both the possible error and rendered string, but does not perform an automated response. When an error occurs, the method invokes `next(err)` internally.
+
+The `view` argument is a string that is the file path of the view file to render. This can be an absolute path, or a path relative to the `views` setting. If the path does not contain a file extension, then the `view engine` setting determines the file extension. If the path does contain a file extension, then Express will load the module for the specified template engine (via `require()`) and render it using the loaded module's `__express` function.
+
+For more information, see [Using template engines with Express](/en/guide/using-template-engines).
+
+{% include admonitions/warning.html content="The `view` argument performs file system operations like reading a file from disk and evaluating Node.js modules, and as so for security reasons should not contain input from the end-user." %}
+
+{% include admonitions/warning.html content="The `locals` object is used by view engines to render a response. The object
+keys may be particularly sensitive and should not contain user-controlled
+input, as it may affect the operation of the view engine or provide a path to
+cross-site scripting. Consult the documentation for the used view engine for
+additional considerations." %}
+
+{% include admonitions/caution.html content="The local variable `cache` enables view caching. Set it to `true`,
+to cache the view during development; view caching is enabled in production by default." %}
+
+```js
+// send the rendered view to the client
+res.render('index');
+
+// if a callback is specified, the rendered HTML string has to be sent explicitly
+res.render('index', (err, html) => {
+ res.send(html);
+});
+
+// pass a local variable to the view
+res.render('user', { name: 'Tobi' }, (err, html) => {
+ // ...
+});
+```
diff --git a/astro/src/content/api/5x/api/response/res-req.md b/astro/src/content/api/5x/api/response/res-req.md
new file mode 100644
index 0000000000..f20548a045
--- /dev/null
+++ b/astro/src/content/api/5x/api/response/res-req.md
@@ -0,0 +1,9 @@
+---
+title: res.req
+description: This property holds a reference to the
+---
+
+res.req
+
+This property holds a reference to the request object
+that relates to this response object.
diff --git a/astro/src/content/api/5x/api/response/res-send.md b/astro/src/content/api/5x/api/response/res-send.md
new file mode 100644
index 0000000000..dd1797ff42
--- /dev/null
+++ b/astro/src/content/api/5x/api/response/res-send.md
@@ -0,0 +1,44 @@
+---
+title: res.send
+description: Sends the HTTP response.
+---
+
+res.send([body])
+
+Sends the HTTP response.
+
+The `body` parameter can be a `Buffer` object, a `String`, an object, `Boolean`, or an `Array`.
+For example:
+
+```js
+res.send(Buffer.from('whoop'));
+res.send({ some: 'json' });
+res.send('some html
');
+res.status(404).send('Sorry, we cannot find that!');
+res.status(500).send({ error: 'something blew up' });
+```
+
+This method performs many useful tasks for simple non-streaming responses:
+For example, it automatically assigns the `Content-Length` HTTP response header field
+and provides automatic HEAD and HTTP cache freshness support.
+
+When the parameter is a `Buffer` object, the method sets the `Content-Type`
+response header field to "application/octet-stream", unless previously defined as shown below:
+
+```js
+res.set('Content-Type', 'text/html');
+res.send(Buffer.from('some html
'));
+```
+
+When the parameter is a `String`, the method sets the `Content-Type` to "text/html":
+
+```js
+res.send('some html
');
+```
+
+When the parameter is an `Array` or `Object`, Express responds with the JSON representation:
+
+```js
+res.send({ user: 'tobi' });
+res.send([1, 2, 3]);
+```
diff --git a/astro/src/content/api/5x/api/response/res-sendFile.md b/astro/src/content/api/5x/api/response/res-sendFile.md
new file mode 100644
index 0000000000..750532497f
--- /dev/null
+++ b/astro/src/content/api/5x/api/response/res-sendFile.md
@@ -0,0 +1,91 @@
+---
+title: res.sendFile
+description: res.sendFile transfers the file at the given path. Sets the Content-Type response HTTP header field based on the filename extension
+---
+
+res.sendFile(path [, options] [, fn])
+
+
+`res.sendFile()` is supported by Express v4.8.0 onwards.
+
+
+Transfers the file at the given `path`. Sets the `Content-Type` response HTTP header field
+based on the filename's extension. Unless the `root` option is set in
+the options object, `path` must be an absolute path to the file.
+
+
+This API provides access to data on the running file system. Ensure that either (a) the way in
+which the `path` argument was constructed into an absolute path is secure if it contains user
+input or (b) set the `root` option to the absolute path of a directory to contain access within.
+
+When the `root` option is provided, the `path` argument is allowed to be a relative path,
+including containing `..`. Express will validate that the relative path provided as `path` will
+resolve within the given `root` option.
+
+
+
+The following table provides details on the `options` parameter.
+
+
+
+| Property | Description | Default | Availability |
+| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------ |
+| `maxAge` | Sets the max-age property of the `Cache-Control` header in milliseconds or a string in [ms format](https://www.npmjs.org/package/ms) | 0 | |
+| `root` | Root directory for relative filenames. | | |
+| `lastModified` | Sets the `Last-Modified` header to the last modified date of the file on the OS. Set `false` to disable it. | Enabled | 4.9.0+ |
+| `headers` | Object containing HTTP headers to serve with the file. | | |
+| `dotfiles` | Option for serving dotfiles. Possible values are "allow", "deny", "ignore". | "ignore" | |
+| `acceptRanges` | Enable or disable accepting ranged requests. | `true` | 4.14+ |
+| `cacheControl` | Enable or disable setting `Cache-Control` response header. | `true` | 4.14+ |
+| `immutable` | Enable or disable the `immutable` directive in the `Cache-Control` response header. If enabled, the `maxAge` option should also be specified to enable caching. The `immutable` directive will prevent supported clients from making conditional requests during the life of the `maxAge` option to check if the file has changed. | `false` | 4.16+ |
+
+
+
+The method invokes the callback function `fn(err)` when the transfer is complete
+or when an error occurs. If the callback function is specified and an error occurs,
+the callback function must explicitly handle the response process either by
+ending the request-response cycle, or by passing control to the next route.
+
+Here is an example of using `res.sendFile` with all its arguments.
+
+```js
+app.get('/file/:name', (req, res, next) => {
+ const options = {
+ root: path.join(__dirname, 'public'),
+ dotfiles: 'deny',
+ headers: {
+ 'x-timestamp': Date.now(),
+ 'x-sent': true,
+ },
+ };
+
+ const fileName = req.params.name;
+ res.sendFile(fileName, options, (err) => {
+ if (err) {
+ next(err);
+ } else {
+ console.log('Sent:', fileName);
+ }
+ });
+});
+```
+
+The following example illustrates using
+`res.sendFile` to provide fine-grained support for serving files:
+
+```js
+app.get('/user/:uid/photos/:file', (req, res) => {
+ const uid = req.params.uid;
+ const file = req.params.file;
+
+ req.user.mayViewFilesFrom(uid, (yes) => {
+ if (yes) {
+ res.sendFile(`/uploads/${uid}/${file}`);
+ } else {
+ res.status(403).send("Sorry! You can't see that.");
+ }
+ });
+});
+```
+
+For more information, or if you have issues or concerns, see [send](https://github.com/pillarjs/send).
diff --git a/astro/src/content/api/5x/api/response/res-sendStatus.md b/astro/src/content/api/5x/api/response/res-sendStatus.md
new file mode 100644
index 0000000000..ae77bd6f46
--- /dev/null
+++ b/astro/src/content/api/5x/api/response/res-sendStatus.md
@@ -0,0 +1,20 @@
+---
+title: res.sendStatus
+description: Sets the response HTTP status code to statusCode and sends the registered status message as the text response body. If an unknown status code is specified, the response body will be just the code number.
+---
+
+res.sendStatus(statusCode)
+
+Sets the response HTTP status code to `statusCode` and sends the registered status message as the text response body. If an unknown status code is specified, the response body will just be the code number.
+
+```js
+res.sendStatus(404);
+```
+
+
+Some versions of Node.js will throw when `res.statusCode` is set to an
+invalid HTTP status code (outside of the range `100` to `599`). Consult
+the HTTP server documentation for the Node.js version being used.
+
+
+[More about HTTP Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
diff --git a/astro/src/content/api/5x/api/response/res-set.md b/astro/src/content/api/5x/api/response/res-set.md
new file mode 100644
index 0000000000..6d2b01e63e
--- /dev/null
+++ b/astro/src/content/api/5x/api/response/res-set.md
@@ -0,0 +1,21 @@
+---
+title: res.set
+description: Sets the response HTTP header field to value.
+---
+
+res.set(field [, value])
+
+Sets the response's HTTP header `field` to `value`.
+To set multiple fields at once, pass an object as the parameter.
+
+```js
+res.set('Content-Type', 'text/plain');
+
+res.set({
+ 'Content-Type': 'text/plain',
+ 'Content-Length': '123',
+ ETag: '12345',
+});
+```
+
+Aliased as `res.header(field [, value])`.
diff --git a/astro/src/content/api/5x/api/response/res-status.md b/astro/src/content/api/5x/api/response/res-status.md
new file mode 100644
index 0000000000..445fed30fb
--- /dev/null
+++ b/astro/src/content/api/5x/api/response/res-status.md
@@ -0,0 +1,15 @@
+---
+title: res.status
+description: Sets the HTTP status for the response.
+---
+
+res.status(code)
+
+Sets the HTTP status for the response.
+It is a chainable alias of Node's [response.statusCode](https://nodejs.org/api/http.html#http_response_statuscode).
+
+```js
+res.status(403).end();
+res.status(400).send('Bad Request');
+res.status(404).sendFile('/absolute/path/to/404.png');
+```
diff --git a/astro/src/content/api/5x/api/response/res-type.md b/astro/src/content/api/5x/api/response/res-type.md
new file mode 100644
index 0000000000..b566a8d143
--- /dev/null
+++ b/astro/src/content/api/5x/api/response/res-type.md
@@ -0,0 +1,18 @@
+---
+title: res.type
+description: Sets the Content-Type HTTP header to the MIME type as determined by the specified type. If type contains the slash character, then it sets the Content-Type to the exact value.
+---
+
+res.type(type)
+
+Sets the `Content-Type` HTTP header to the MIME type as determined by the specified `type`. If `type` contains the "/" character, then it sets the `Content-Type` to the exact value of `type`, otherwise it is assumed to be a file extension and the MIME type is looked up using the `contentType()` method of the `mime-types` package.
+
+```js
+res.type('.html'); // => 'text/html'
+res.type('html'); // => 'text/html'
+res.type('json'); // => 'application/json'
+res.type('application/json'); // => 'application/json'
+res.type('png'); // => image/png:
+```
+
+Aliased as `res.contentType(type)`.
diff --git a/astro/src/content/api/5x/api/response/res-vary.md b/astro/src/content/api/5x/api/response/res-vary.md
new file mode 100644
index 0000000000..164bed9285
--- /dev/null
+++ b/astro/src/content/api/5x/api/response/res-vary.md
@@ -0,0 +1,12 @@
+---
+title: res.vary
+description: Adds the field to the Vary response header, if it is not there already.
+---
+
+res.vary(field)
+
+Adds the field to the `Vary` response header, if it is not there already.
+
+```js
+res.vary('User-Agent').render('docs');
+```
diff --git a/astro/src/content/api/5x/api/response/response.md b/astro/src/content/api/5x/api/response/response.md
new file mode 100644
index 0000000000..ac989a33d8
--- /dev/null
+++ b/astro/src/content/api/5x/api/response/response.md
@@ -0,0 +1,135 @@
+---
+title: Properties
+description: section markdown="1">
+---
+
+Response
+
+The `res` object represents the HTTP response that an Express app sends when it gets an HTTP request.
+
+In this documentation and by convention,
+the object is always referred to as `res` (and the HTTP request is `req`) but its actual name is determined
+by the parameters to the callback function in which you're working.
+
+For example:
+
+```js
+app.get('/user/:id', (req, res) => {
+ res.send(`user ${req.params.id}`);
+});
+```
+
+But you could just as well have:
+
+```js
+app.get('/user/:id', (request, response) => {
+ response.send(`user ${request.params.id}`);
+});
+```
+
+The `res` object is an enhanced version of Node's own response object
+and supports all [built-in fields and methods](https://nodejs.org/api/http.html#http_class_http_serverresponse).
+
+Properties
+
+
+ {% include api/en/5x/res-app.md %}
+
+
+
+ {% include api/en/5x/res-headersSent.md %}
+
+
+
+ {% include api/en/5x/res-locals.md %}
+
+
+
+ {% include api/en/5x/res-req.md %}
+
+
+Methods
+
+
+ {% include api/en/5x/res-append.md %}
+
+
+
+ {% include api/en/5x/res-attachment.md %}
+
+
+
+ {% include api/en/5x/res-cookie.md %}
+
+
+
+ {% include api/en/5x/res-clearCookie.md %}
+
+
+
+ {% include api/en/5x/res-download.md %}
+
+
+
+ {% include api/en/5x/res-end.md %}
+
+
+
+ {% include api/en/5x/res-format.md %}
+
+
+
+ {% include api/en/5x/res-get.md %}
+
+
+
+ {% include api/en/5x/res-json.md %}
+
+
+
+ {% include api/en/5x/res-jsonp.md %}
+
+
+
+ {% include api/en/5x/res-links.md %}
+
+
+
+ {% include api/en/5x/res-location.md %}
+
+
+
+ {% include api/en/5x/res-redirect.md %}
+
+
+
+ {% include api/en/5x/res-render.md %}
+
+
+
+ {% include api/en/5x/res-send.md %}
+
+
+
+ {% include api/en/5x/res-sendFile.md %}
+
+
+
+ {% include api/en/5x/res-sendStatus.md %}
+
+
+
+ {% include api/en/5x/res-set.md %}
+
+
+
+ {% include api/en/5x/res-status.md %}
+
+
+
+ {% include api/en/5x/res-type.md %}
+
+
+
+ {% include api/en/5x/res-vary.md %}
+
diff --git a/astro/src/content/api/5x/api/router/overview.md b/astro/src/content/api/5x/api/router/overview.md
new file mode 100644
index 0000000000..e961fa8eb6
--- /dev/null
+++ b/astro/src/content/api/5x/api/router/overview.md
@@ -0,0 +1,66 @@
+---
+title: Methods
+description: section markdown="1">
+---
+
+Router
+
+
+A `router` object is an instance of middleware and routes. You can think of it
+as a "mini-application," capable only of performing middleware and routing
+functions. Every Express application has a built-in app router.
+
+A router behaves like middleware itself, so you can use it as an argument to
+[app.use()](#app.use) or as the argument to another router's [use()](#router.use) method.
+
+The top-level `express` object has a [Router()](#express.router) method that creates a new `router` object.
+
+Once you've created a router object, you can add middleware and HTTP method routes (such as `get`, `put`, `post`,
+and so on) to it just like an application. For example:
+
+```js
+// invoked for any requests passed to this router
+router.use((req, res, next) => {
+ // .. some logic here .. like any other middleware
+ next();
+});
+
+// will handle any request that ends in /events
+// depends on where the router is "use()'d"
+router.get('/events', (req, res, next) => {
+ // ..
+});
+```
+
+You can then use a router for a particular root URL in this way separating your routes into files or even mini-apps.
+
+```js
+// only requests to /calendar/* will be sent to our "router"
+app.use('/calendar', router);
+```
+
+Keep in mind that any middleware applied to a router will run for all requests on that router's path, even those that aren't part of the router.
+
+
+
+Methods
+
+
+ {% include api/en/5x/router-all.md %}
+
+
+
+ {% include api/en/5x/router-METHOD.md %}
+
+
+
+ {% include api/en/5x/router-param.md %}
+
+
+
+ {% include api/en/5x/router-route.md %}
+
+
+
+ {% include api/en/5x/router-use.md %}
+
diff --git a/astro/src/content/api/5x/api/router/router-METHOD.md b/astro/src/content/api/5x/api/router/router-METHOD.md
new file mode 100644
index 0000000000..a4eb343c90
--- /dev/null
+++ b/astro/src/content/api/5x/api/router/router-METHOD.md
@@ -0,0 +1,71 @@
+---
+title: router.METHOD
+description: The router.METHOD methods provide the routing functionality in Express, where METHOD is one of the HTTP methods, such as GET, PUT, POST, and so on, in lowercase
+---
+
+router.METHOD(path, [callback, ...] callback)
+
+The `router.METHOD()` methods provide the routing functionality in Express,
+where METHOD is one of the HTTP methods, such as GET, PUT, POST, and so on,
+in lowercase. Thus, the actual methods are `router.get()`, `router.post()`,
+`router.put()`, and so on.
+
+
+ The `router.get()` function is automatically called for the HTTP `HEAD` method in
+ addition to the `GET` method if `router.head()` was not called for the
+ path before `router.get()`.
+
+
+You can provide multiple callbacks, and all are treated equally, and behave just
+like middleware, except that these callbacks may invoke `next('route')`
+to bypass the remaining route callback(s). You can use this mechanism to perform
+pre-conditions on a route then pass control to subsequent routes when there is no
+reason to proceed with the route matched.
+
+The following snippet illustrates the most simple route definition possible.
+Express translates the path strings to regular expressions, used internally
+to match incoming requests. Query strings are _not_ considered when performing
+these matches, for example "GET /" would match the following route, as would
+"GET /?name=tobi".
+
+```js
+router.get('/', (req, res) => {
+ res.send('hello world');
+});
+```
+
+You can also use regular expressions—useful if you have very specific
+constraints, for example the following would match "GET /commits/71dbb9c" as well
+as "GET /commits/71dbb9c..4c084f9".
+
+```js
+router.get(/^\/commits\/(\w+)(?:\.\.(\w+))?$/, (req, res) => {
+ const from = req.params[0];
+ const to = req.params[1] || 'HEAD';
+ res.send(`commit range ${from}..${to}`);
+});
+```
+
+You can use `next` primitive to implement a flow control between different
+middleware functions, based on a specific program state. Invoking `next` with
+the string `'router'` will cause all the remaining route callbacks on that router
+to be bypassed.
+
+The following example illustrates `next('router')` usage.
+
+```js
+function fn(req, res, next) {
+ console.log('I come here');
+ next('router');
+}
+router.get('/foo', fn, (req, res, next) => {
+ console.log('I dont come here');
+});
+router.get('/foo', (req, res, next) => {
+ console.log('I dont come here');
+});
+app.get('/foo', (req, res) => {
+ console.log(' I come here too');
+ res.end('good');
+});
+```
diff --git a/astro/src/content/api/5x/api/router/router-Router.md b/astro/src/content/api/5x/api/router/router-Router.md
new file mode 100644
index 0000000000..de2867f15c
--- /dev/null
+++ b/astro/src/content/api/5x/api/router/router-Router.md
@@ -0,0 +1,5 @@
+---
+title: Router
+---
+
+Router([options])
diff --git a/astro/src/content/api/5x/api/router/router-all.md b/astro/src/content/api/5x/api/router/router-all.md
new file mode 100644
index 0000000000..6a0461bc82
--- /dev/null
+++ b/astro/src/content/api/5x/api/router/router-all.md
@@ -0,0 +1,36 @@
+---
+title: router.all
+description: This method is just like the router.METHOD methods, except that it matches all HTTP methods (verbs).
+---
+
+router.all(path, [callback, ...] callback)
+
+This method is just like the `router.METHOD()` methods, except that it matches all HTTP methods (verbs).
+
+This method is extremely useful for
+mapping "global" logic for specific path prefixes or arbitrary matches.
+For example, if you placed the following route at the top of all other
+route definitions, it would require that all routes from that point on
+would require authentication, and automatically load a user. Keep in mind
+that these callbacks do not have to act as end points; `loadUser`
+can perform a task, then call `next()` to continue matching subsequent
+routes.
+
+```js
+router.all('{*splat}', requireAuthentication, loadUser);
+```
+
+Or the equivalent:
+
+```js
+router.all('{*splat}', requireAuthentication);
+router.all('{*splat}', loadUser);
+```
+
+Another example of this is white-listed "global" functionality. Here,
+the example is much like before, but it only restricts paths prefixed with
+"/api":
+
+```js
+router.all('/api/{*splat}', requireAuthentication);
+```
diff --git a/astro/src/content/api/5x/api/router/router-param.md b/astro/src/content/api/5x/api/router/router-param.md
new file mode 100644
index 0000000000..184e0792e4
--- /dev/null
+++ b/astro/src/content/api/5x/api/router/router-param.md
@@ -0,0 +1,67 @@
+---
+title: router.param
+description: Adds callback triggers to route parameters, where name is the name of the parameter and callback is the callback function. Although name is technically optional, it is required.
+---
+
+router.param(name, callback)
+
+Adds callback triggers to route parameters, where `name` is the name of the parameter and `callback` is the callback function. Although `name` is technically optional, using this method without it is deprecated starting with Express v4.11.0 (see below).
+
+The parameters of the callback function are:
+
+- `req`, the request object.
+- `res`, the response object.
+- `next`, indicating the next middleware function.
+- The value of the `name` parameter.
+- The name of the parameter.
+
+
+Unlike `app.param()`, `router.param()` does not accept an array of route parameters.
+
+
+For example, when `:user` is present in a route path, you may map user loading logic to automatically provide `req.user` to the route, or perform validations on the parameter input.
+
+```js
+router.param('user', (req, res, next, id) => {
+ // try to get the user details from the User model and attach it to the request object
+ User.find(id, (err, user) => {
+ if (err) {
+ next(err);
+ } else if (user) {
+ req.user = user;
+ next();
+ } else {
+ next(new Error('failed to load user'));
+ }
+ });
+});
+```
+
+Param callback functions are local to the router on which they are defined. They are not inherited by mounted apps or routers, nor are they triggered for route parameters inherited from parent routers. Hence, param callbacks defined on `router` will be triggered only by route parameters defined on `router` routes.
+
+A param callback will be called only once in a request-response cycle, even if the parameter is matched in multiple routes, as shown in the following examples.
+
+```js
+router.param('id', (req, res, next, id) => {
+ console.log('CALLED ONLY ONCE');
+ next();
+});
+
+router.get('/user/:id', (req, res, next) => {
+ console.log('although this matches');
+ next();
+});
+
+router.get('/user/:id', (req, res) => {
+ console.log('and this matches too');
+ res.end();
+});
+```
+
+On `GET /user/42`, the following is printed:
+
+```
+CALLED ONLY ONCE
+although this matches
+and this matches too
+```
diff --git a/astro/src/content/api/5x/api/router/router-route.md b/astro/src/content/api/5x/api/router/router-route.md
new file mode 100644
index 0000000000..f3d9d42075
--- /dev/null
+++ b/astro/src/content/api/5x/api/router/router-route.md
@@ -0,0 +1,54 @@
+---
+title: router.route
+description: Returns an instance of a single route which you can then use to handle HTTP verbs
+---
+
+router.route(path)
+
+Returns an instance of a single route which you can then use to handle HTTP verbs
+with optional middleware. Use `router.route()` to avoid duplicate route naming and
+thus typing errors.
+
+Building on the `router.param()` example above, the following code shows how to use
+`router.route()` to specify various HTTP method handlers.
+
+```js
+const router = express.Router();
+
+router.param('user_id', (req, res, next, id) => {
+ // sample user, would actually fetch from DB, etc...
+ req.user = {
+ id,
+ name: 'TJ',
+ };
+ next();
+});
+
+router
+ .route('/users/:user_id')
+ .all((req, res, next) => {
+ // runs for all HTTP verbs first
+ // think of it as route specific middleware!
+ next();
+ })
+ .get((req, res, next) => {
+ res.json(req.user);
+ })
+ .put((req, res, next) => {
+ // just an example of maybe updating the user
+ req.user.name = req.params.name;
+ // save user ... etc
+ res.json(req.user);
+ })
+ .post((req, res, next) => {
+ next(new Error('not implemented'));
+ })
+ .delete((req, res, next) => {
+ next(new Error('not implemented'));
+ });
+```
+
+This approach re-uses the single `/users/:user_id` path and adds handlers for
+various HTTP methods.
+
+{% include admonitions/note.html content="When you use `router.route()`, middleware ordering is based on when the _route_ is created, not when method handlers are added to the route. For this purpose, you can consider method handlers to belong to the route to which they were added." %}
diff --git a/astro/src/content/api/5x/api/router/router-use.md b/astro/src/content/api/5x/api/router/router-use.md
new file mode 100644
index 0000000000..6e31cf7f22
--- /dev/null
+++ b/astro/src/content/api/5x/api/router/router-use.md
@@ -0,0 +1,111 @@
+---
+title: router.use
+description: Uses the specified middleware function or functions, with optional mount path that defaults to slash.
+---
+
+router.use([path], [function, ...] function)
+
+Uses the specified middleware function or functions, with optional mount path `path`, that defaults to "/".
+
+This method is similar to [app.use()](#app.use). A simple example and use case is described below.
+See [app.use()](#app.use) for more information.
+
+Middleware is like a plumbing pipe: requests start at the first middleware function defined
+and work their way "down" the middleware stack processing for each path they match.
+
+```js
+const express = require('express');
+const app = express();
+const router = express.Router();
+
+// simple logger for this router's requests
+// all requests to this router will first hit this middleware
+router.use((req, res, next) => {
+ console.log('%s %s %s', req.method, req.url, req.path);
+ next();
+});
+
+// this will only be invoked if the path starts with /bar from the mount point
+router.use('/bar', (req, res, next) => {
+ // ... maybe some additional /bar logging ...
+ next();
+});
+
+// always invoked
+router.use((req, res, next) => {
+ res.send('Hello World');
+});
+
+app.use('/foo', router);
+
+app.listen(3000);
+```
+
+The "mount" path is stripped and is _not_ visible to the middleware function.
+The main effect of this feature is that a mounted middleware function may operate without
+code changes regardless of its "prefix" pathname.
+
+The order in which you define middleware with `router.use()` is very important.
+They are invoked sequentially, thus the order defines middleware precedence. For example,
+usually a logger is the very first middleware you would use, so that every request gets logged.
+
+```js
+const logger = require('morgan');
+
+router.use(logger());
+router.use(express.static(path.join(__dirname, 'public')));
+router.use((req, res) => {
+ res.send('Hello');
+});
+```
+
+Now suppose you wanted to ignore logging requests for static files, but to continue
+logging routes and middleware defined after `logger()`. You would simply move the call to `express.static()` to the top,
+before adding the logger middleware:
+
+```js
+router.use(express.static(path.join(__dirname, 'public')));
+router.use(logger());
+router.use((req, res) => {
+ res.send('Hello');
+});
+```
+
+Another example is serving files from multiple directories,
+giving precedence to "./public" over the others:
+
+```js
+app.use(express.static(path.join(__dirname, 'public')));
+app.use(express.static(path.join(__dirname, 'files')));
+app.use(express.static(path.join(__dirname, 'uploads')));
+```
+
+The `router.use()` method also supports named parameters so that your mount points
+for other routers can benefit from preloading using named parameters.
+
+**NOTE**: Although these middleware functions are added via a particular router, _when_
+they run is defined by the path they are attached to (not the router). Therefore,
+middleware added via one router may run for other routers if its routes
+match. For example, this code shows two different routers mounted on the same path:
+
+```js
+const authRouter = express.Router();
+const openRouter = express.Router();
+
+authRouter.use(require('./authenticate').basic(usersdb));
+
+authRouter.get('/:user_id/edit', (req, res, next) => {
+ // ... Edit user UI ...
+});
+openRouter.get('/', (req, res, next) => {
+ // ... List users ...
+});
+openRouter.get('/:user_id', (req, res, next) => {
+ // ... View user ...
+});
+
+app.use('/users', authRouter);
+app.use('/users', openRouter);
+```
+
+Even though the authentication middleware was added via the `authRouter` it will run on the routes defined by the `openRouter` as well since both routers were mounted on `/users`. To avoid this behavior, use different paths for each router.
diff --git a/astro/src/content/api/5x/api/router/router.md b/astro/src/content/api/5x/api/router/router.md
new file mode 100644
index 0000000000..e961fa8eb6
--- /dev/null
+++ b/astro/src/content/api/5x/api/router/router.md
@@ -0,0 +1,66 @@
+---
+title: Methods
+description: section markdown="1">
+---
+
+Router
+
+
+A `router` object is an instance of middleware and routes. You can think of it
+as a "mini-application," capable only of performing middleware and routing
+functions. Every Express application has a built-in app router.
+
+A router behaves like middleware itself, so you can use it as an argument to
+[app.use()](#app.use) or as the argument to another router's [use()](#router.use) method.
+
+The top-level `express` object has a [Router()](#express.router) method that creates a new `router` object.
+
+Once you've created a router object, you can add middleware and HTTP method routes (such as `get`, `put`, `post`,
+and so on) to it just like an application. For example:
+
+```js
+// invoked for any requests passed to this router
+router.use((req, res, next) => {
+ // .. some logic here .. like any other middleware
+ next();
+});
+
+// will handle any request that ends in /events
+// depends on where the router is "use()'d"
+router.get('/events', (req, res, next) => {
+ // ..
+});
+```
+
+You can then use a router for a particular root URL in this way separating your routes into files or even mini-apps.
+
+```js
+// only requests to /calendar/* will be sent to our "router"
+app.use('/calendar', router);
+```
+
+Keep in mind that any middleware applied to a router will run for all requests on that router's path, even those that aren't part of the router.
+
+
+
+Methods
+
+
+ {% include api/en/5x/router-all.md %}
+
+
+
+ {% include api/en/5x/router-METHOD.md %}
+
+
+
+ {% include api/en/5x/router-param.md %}
+
+
+
+ {% include api/en/5x/router-route.md %}
+
+
+
+ {% include api/en/5x/router-use.md %}
+
diff --git a/astro/src/content/blog/en/2024-07-16-welcome-post.md b/astro/src/content/blog/en/2024-07-16-welcome-post.md
new file mode 100644
index 0000000000..8892e7237d
--- /dev/null
+++ b/astro/src/content/blog/en/2024-07-16-welcome-post.md
@@ -0,0 +1,28 @@
+---
+title: Welcome to The Express Blog!
+description: Introducing the new Express blog — a primary platform for announcements, updates, and communication from the Express technical committee.
+tags: ['announcements']
+authors:
+ - name: Rand McKinney
+ github: crandmck
+ - name: Chris Del
+ github: chrisdel101
+---
+
+Welcome to the new Express blog! The blog is meant to be a primary means of communication for the Express technical committee (TC). While we currently have other channels such as X, LinkedIn, and of course GitHub, there's no authoritative "soapbox" for announcements and general communication.
+
+Initially, the Express blog will be a venue:
+
+- For periodic announcements of new releases, pre-releases, plans, and ongoing work on the project.
+- For the Express TC to discuss issues of particular importance to the Express community.
+- To highlight security issues or other urgent information.
+
+Eventually, we hope the blog will evolve into a more general communication hub for the entire Express community; for example to share examples, tips, and experiences with the Express ecosystem and other information that's not simply technical documentation or GitHub discussion.
+
+Initially, posts will be written by TC members (potentially collaborating others), mainly because we don't have bandwidth to review general posts from the broader community. Eventually, we would love to open up the blog for broader contributions, but for now the focus is on trying to release Express 5.0, and the reality of an open-source project is that everyone has finite time to contribute.
+
+Express TC member [Ulises Gascón](https://github.com/UlisesGascon) suggested a number of interesting topics for blog posts in [expressjs.com issue 1500](https://github.com/expressjs/expressjs.com/issues/1500), but there are undoubtedly many others.
+
+If you have an idea for a post, feel free to pitch the idea! You can add a comment to [expressjs.com issue 1500](https://github.com/expressjs/expressjs.com/issues/1500) or open a new issue, and then after appropriate discussion, open a PR. We've also written up simple [instructions to create a blog post](/en/blog/write-post).
+
+Happy blogging!
diff --git a/astro/src/content/blog/en/2024-09-29-security-releases.md b/astro/src/content/blog/en/2024-09-29-security-releases.md
new file mode 100644
index 0000000000..4e72a82fad
--- /dev/null
+++ b/astro/src/content/blog/en/2024-09-29-security-releases.md
@@ -0,0 +1,139 @@
+---
+title: September 2024 Security Releases
+description: Security releases for Express, body-parser, send, serve-static, and path-to-regexp have been published. We recommend that all users upgrade as soon as possible.
+tags: ['security']
+authors:
+ - name: Ulises Gascón
+ github: UlisesGascon
+---
+
+Recently, the Express team has been made aware of a number of security vulnerabilities in the Express project. We have released a number of patches to address these vulnerabilities.
+
+{% include admonitions/warning.html
+content="We strongly recommend that you upgrade these modules to the recommended (or latest) version as soon as possible."
+%}
+
+The following vulnerabilities have been addressed:
+
+- [High severity vulnerability CVE-2024-45590 in body-parser middleware](#high-severity-vulnerability-cve-2024-45590-in-body-parser-middleware)
+- [High severity vulnerability CVE-2024-47178 in basic-auth-connect middleware](#high-severity-vulnerability-cve-2024-47178-in-basic-auth-connect-middleware)
+- [Moderate severity vulnerability CVE-2024-43796 in Express core](#moderate-severity-vulnerability-cve-2024-43796-in-express-core)
+- [Moderate severity vulnerability CVE-2024-43799 in send utility module](#moderate-severity-vulnerability-cve-2024-43799-in-send-utility-module)
+- [Moderate severity vulnerability CVE-2024-43800 in serve-static middleware](#moderate-severity-vulnerability-cve-2024-43800-in-serve-static-middleware)
+- [Moderate severity vulnerability CVE-2024-45296 in path-to-regexp utility module](#moderate-severity-vulnerability-cve-2024-45296-in-path-to-regexp-utility-module)
+
+## High severity vulnerability CVE-2024-45590 in body-parser middleware
+
+**[body-parser](https://www.npmjs.com/package/body-parser) version `<1.20.3` is vulnerable to denial of service when URL-encoding is enabled**
+
+A malicious actor using a specially-crafted payload could flood the server with a large number of requests, resulting in denial of service.
+
+**Affected versions**: `<1.20.3`
+
+**Patched versions**: `>=1.20.3`
+
+This vulnerability was discovered during the [OSTIF audit to Express](https://github.com/expressjs/security-wg/issues/6) and was mitigated by [the Express security triage team](https://github.com/expressjs/security-wg?tab=readme-ov-file#security-triage-team).
+
+For more details, see [GHSA-qwcr-r2fm-qrc7](https://github.com/expressjs/body-parser/security/advisories/GHSA-qwcr-r2fm-qrc7).
+
+## High severity vulnerability CVE-2024-47178 in basic-auth-connect middleware
+
+**[basic-auth-connect](https://www.npmjs.com/package/basic-auth-connect) uses a timing-unsafe equality comparison**
+
+basic-auth-connect `<1.1.0` uses a timing-unsafe equality comparison that can leak timing information
+
+**Affected versions**
+
+- `<1.1.0`
+
+**Patched versions**
+
+- `>=1.1.0`
+
+This vulnerability was discovered during the [OSTIF audit to Express](https://github.com/expressjs/security-wg/issues/6) and was mitigated by [the Express Securty triage team](https://github.com/expressjs/security-wg?tab=readme-ov-file#security-triage-team).
+
+More details area available in [GHSA-7p89-p6hx-q4fw](https://github.com/expressjs/basic-auth-connect/security/advisories/GHSA-7p89-p6hx-q4fw)
+
+## Moderate severity vulnerability CVE-2024-43796 in Express core
+
+The core **[express](https://www.npmjs.com/package/express) package is vulnerable to cross-site scripting (XSS) attack via `response.redirect()`**.
+
+In Express version <4.20.0, passing untrusted user input—even after sanitizing it—to `response.redirect()` may execute untrusted code.
+
+**Affected versions**:
+
+- `<4.20.0`
+- `>=5.0.0-alpha.1`, `<5.0.0`
+
+**Patched versions**:
+
+- `>=4.20.0`
+- `>=5.0.0`
+
+This vulnerability was discovered during the [OSTIF audit of Express](https://github.com/expressjs/security-wg/issues/6) and was mitigated by [the Express security triage team](https://github.com/expressjs/security-wg?tab=readme-ov-file#security-triage-team).
+
+For more details, see [GHSA-qw6h-vgh9-j6wx](https://github.com/expressjs/express/security/advisories/GHSA-qw6h-vgh9-j6wx).
+
+## Moderate severity vulnerability CVE-2024-43799 in send utility module
+
+The **[send](https://www.npmjs.com/package/send) utility module is vulnerable to template injection that can lead to vulnerability to cross-site scripting (XSS) attack**.
+
+Passing untrusted user input—even after sanitizing it—to `SendStream.redirect()` can execute untrusted code.
+
+**Affected versions**: `< 0.19.0`
+
+**Patched versions**: `>=0.19.0`
+
+This vulnerability was discovered during the [OSTIF audit of Express](https://github.com/expressjs/security-wg/issues/6) and was mitigated by [the Express security triage team](https://github.com/expressjs/security-wg?tab=readme-ov-file#security-triage-team).
+
+For more details, see [GHSA-m6fv-jmcg-4jfg](https://github.com/pillarjs/send/security/advisories/GHSA-m6fv-jmcg-4jfg).
+
+## Moderate severity vulnerability CVE-2024-43800 in serve-static middleware
+
+The **[serve-static](https://www.npmjs.com/package/serve-static) middleware module is vulnerable to template injection that can lead to vulnerability to cross-site scripting (XSS) attack**.
+
+Passing untrusted user input—even after sanitizing it—to `redirect()` can execute untrusted code.
+
+**Affected versions**:
+
+- `< 1.16.0`
+- `>=2.0.0`, `<2.1.0`
+
+**Patched versions**:
+
+- `>=1.16.0`
+- `>=2.1.0`
+
+This vulnerability was discovered during the [OSTIF audit of Express](https://github.com/expressjs/security-wg/issues/6) and was mitigated by [the Express security triage team](https://github.com/expressjs/security-wg?tab=readme-ov-file#security-triage-team).
+
+For more details, see [GHSA-cm22-4g7w-348p](https://github.com/expressjs/serve-static/security/advisories/GHSA-cm22-4g7w-348p)
+
+## Moderate severity vulnerability CVE-2024-45296 in path-to-regexp utility module
+
+The **[path-to-regexp](https://www.npmjs.com/package/path-to-regexp) utility module is vulnerable to regular expression denial of service (ReDoS) attack**.
+
+A bad regular expression is generated any time you have two parameters within a single segment, separated by something that is not a period (`.`). For example, `/:a-:b`.
+
+Using `/:a-:b` will produce the regular expression `/^\/([^\/]+?)-([^\/]+?)\/?$/`. This can be exploited by a path such as `/a${'-a'.repeat(8_000)}/a`. [OWASP](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS) has a good example of why this occurs, but in essence, the `/a` at the end ensures this route would never match, but due to naive backtracking it will still attempt every combination of the `:a-:b` on the repeated 8,000 `-a`.
+
+Because JavaScript is single-threaded and regex matching runs on the main thread, poor performance will block the event loop and can lead to a DoS. In local benchmarks, exploiting the unsafe regex will result in performance that is over 1000x worse than the safe regex. In a more realistic environment, using Express v4 and ten concurrent connections results in an average latency of ~600ms vs 1ms.
+
+**Affected versions**:
+
+- `>=4.0.0`, `<8.0.0`
+- `>=0.2.0`, `<1.9.0`
+- `<0.1.10`
+- `>=2.0.0`, `<3.3.0`
+- `>=4.0.0`, `<6.3.0`
+
+**Patched versions**:
+
+- `>=8.0.0`
+- `>=1.9.0`
+- `>=0.1.10`
+- `>=3.3.0`
+- `>=6.3.0`
+
+Thanks to [Blake Embrey](https://github.com/blakeembrey) who reported and created the security patch.
+
+For more details, see [GHSA-9wv6-86v2-598j](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-9wv6-86v2-598j)
diff --git a/astro/src/content/blog/en/2024-10-01-HeroDevs-partnership-announcement.md b/astro/src/content/blog/en/2024-10-01-HeroDevs-partnership-announcement.md
new file mode 100644
index 0000000000..11048603df
--- /dev/null
+++ b/astro/src/content/blog/en/2024-10-01-HeroDevs-partnership-announcement.md
@@ -0,0 +1,26 @@
+---
+title: Express Never Ending Support Launched by HeroDevs and Express.js
+description: The Express.js team is pleased to announce a partnership with HeroDevs to launch Express Never-Ending Support (NES), providing long-term support for applications built with legacy Express. This collaboration ensures that developers relying on older versions of the framework will continue to receive critical security and compatibility updates, allowing them to maintain and scale their applications securely, even after the framework's official end-of-life.
+tags: ['announcements']
+authors:
+ - name: Express Technical Committee
+ github: expressjs
+---
+
+The Express.js team is pleased to announce a partnership with HeroDevs to launch [Express Never-Ending Support (NES)](https://www.herodevs.com/support/express-nes), providing long-term support for applications built with legacy Express. This collaboration ensures that developers relying on older versions of the framework will continue to receive critical security and compatibility updates, allowing them to maintain and scale their applications securely, even after the framework's official end-of-life.
+
+Express.js is known for its minimalistic design and flexibility, offering developers a powerful yet lightweight framework for building web and mobile applications. Its extensive set of HTTP utility methods and middleware have made creating APIs both efficient and scalable—qualities that have made it a go-to choice for Node.js developers over the years.
+
+However, Express.js v3.x reached its end-of-life in July 2015, leaving many businesses and developers in need of support to keep their applications secure and compliant.
+
+> "We’re grateful to see HeroDevs stepping in to provide extended long-term support for Express
+>
+> Express NES ensures that the many businesses and developers who rely on Express can continue using it safely and securely, even years after its original end-of-life. This kind of ongoing commitment to the open-source ecosystem is crucial, and we’re excited to see the benefits it brings to the developer community.” — said a spokesperson for the Express Technical Committee.
+
+Express NES is designed as a drop-in replacement for legacy versions of Express.js, offering security patches, compatibility updates and compliance fixes. This solution ensures that developers can remain on legacy Express.js without becoming vulnerable to security risks and compliance issues.
+
+> “We’re thrilled to introduce Express NES as part of our continued mission to support the sustainability of key open-source tools
+>
+> Our partnership with OpenJS has enabled us to meet the needs of developers still relying on older versions of critical frameworks. Express NES ensures that they can continue building and maintaining their applications without the risk of security vulnerabilities or loss of compliance.” — Joe Eames, VP of Partnership at HeroDevs.
+
+For more information on Express NES and how to get started, visit [HeroDevs’ website](https://www.herodevs.com/support/express-nes).
diff --git a/astro/src/content/blog/en/2024-10-15-v5-release.md b/astro/src/content/blog/en/2024-10-15-v5-release.md
new file mode 100644
index 0000000000..a1af3bea75
--- /dev/null
+++ b/astro/src/content/blog/en/2024-10-15-v5-release.md
@@ -0,0 +1,138 @@
+---
+title: 'Introducing Express v5: A New Era for the Node.js Framework'
+tags: ['announcements']
+authors:
+ - name: Wes Todd
+ github: wesleytodd
+ - name: Express Technical Committee
+ github: expressjs
+description: Announcing the release of Express version 5
+---
+
+Ten years ago (July 2014) the [Express v5 release pull request](https://github.com/expressjs/express/pull/2237) was opened, and now at long last it's been merged and published!
+
+We want to recognize the work of all our contributors, especially [Doug Wilson](https://github.com/dougwilson), who spent the last ten years ensuring Express was the most stable project around. Without his contributions and those of many others, this release could not have happened.
+
+Eight months ago we went public with a plan to move [Express forward](https://github.com/expressjs/discussions/issues/160). This plan included re-committing to the governance outlined years ago and adding more contributors to help kickstart progress. Many people may not realize that robust project governance is critical to the health of a large open-source project. We want to thank the [OpenJS Foundation Cross Project
+Council](https://github.com/openjs-foundation/cross-project-council/) and its members for helping us put together this plan.
+
+## So what about v5?
+
+This release is designed to be boring!
+That may sound odd, but we've intentionally kept it simple to unblock the ecosystem and enable more impactful changes in future releases. This is also about signaling to the Node.js ecosystem that Express is moving again.
+The focus of this release is on dropping old Node.js version support, addressing security concerns, and simplifying maintenance.
+
+Before going into the changes in this release, let's address why it was released v5 on the `next` dist-tag. As part of reviving the project, we started a [Security working group](https://github.com/expressjs/security-wg) and [security triage team](https://github.com/expressjs/security-wg?tab=readme-ov-file#security-triage-team) to address the growing needs around open source supply chain security. We undertook a security audit (more details to come on that) and uncovered some problems that needed to be addressed. Thus, in addition to the "normal" work done in public issues, we also did a lot of security work in private forks.
+This security work required orchestration when releasing, to ensure the code and CVE reports went out together. You can find a summary of the most recent vulnerabilities patched in [our security release notes](/en/blog/2024-09-29-security-releases).
+
+While we weren't able to simultaneously release v5, this blog post, the changelog, and documentation, we felt it was most important to have a secure and stable release.
+
+As soon as possible, we'll provide more details on our long-term support (LTS) plans, including when the release will move from `next` to `latest`. For now, if you are uncomfortable being on the bleeding edge (even if it is a rather dull edge) then you should wait to upgrade until the release is tagged `latest`. That said, we look forward to working with you to address any bugs you encounter as you upgrade.
+
+## Breaking changes
+
+The v5 release has the minimum possible number of breaking changes, listed here in order of impact to applications.
+
+- [So what about v5?](#so-what-about-v5)
+- [Breaking changes](#breaking-changes)
+ - [Ending support for old Node.js versions](#ending-support-for-old-nodejs-versions)
+ - [Changes to path matching and regular expressions](#changes-to-path-matching-and-regular-expressions)
+ - [No more regex](#no-more-regex)
+ - [Splats, optional, and captures oh my](#splats-optional-and-captures-oh-my)
+ - [Name everything](#name-everything)
+ - [Promise support](#promise-support)
+ - [Body parser changes](#body-parser-changes)
+ - [Removing deprecated method signatures](#removing-deprecated-method-signatures)
+- [Migration and security guidance](#migration-and-security-guidance)
+- [Our work is just starting](#our-work-is-just-starting)
+
+There are also a number of subtle changes: for details, see [Migrating to Express 5](/en/guide/migrating-5).
+
+### Ending support for old Node.js versions
+
+Goodbye Node.js 0.10, hello Node 18 and up!
+
+This release drops support for Node.js versions before v18. This is an important change because supporting old Node.js versions has been holding back many critical performance and maintainability changes. This change also enables more stable and maintainable continuous integration (CI), adopting new language and runtime features, and dropping dependencies that are no longer required.
+
+We recognize that this might cause difficulty for some enterprises with older or "parked" applications, and because of this we are working on a [partnership with HeroDevs](/en/blog/2024-10-01-herodevs-partnership-announcement) to offer "never-ending support" that will include critical security patches even after v4 enters end-of-life (more on these plans soon). That said, we strongly suggest that you update to modern Node.js versions as soon as possible.
+
+### Changes to path matching and regular expressions
+
+The v5 releases updates to `path-to-regexp@8.x` from `path-to-regexp@0.x`, which incorporates many years of changes. If you were using any of the 5.0.0-beta releases, a last-minute update which greatly changed the path semantics to [remove the possibility of any ReDoS attacks](https://blakeembrey.com/posts/2024-09-web-redos/). For more detailed changes, [see the `path-to-regexp` readme](https://github.com/pillarjs/path-to-regexp?tab=readme-ov-file#express--4x).
+
+#### No more regex
+
+This release no longer supports "sub-expression" regular expressions, for example `/:foo(\\d+)`.
+This is a commonly-used pattern, but we removed it for security reasons. Unfortunately, it's easy to write a regular expression that has exponential time behavior when parsing input: The dreaded regular expression denial of service (ReDoS) attack. It's very difficult to prevent this, but as a library that converts strings to regular expressions, we are on the hook for such security aspects.
+
+_How to migrate:_ The best approach to prevent ReDoS attacks is to use a robust input validation library. [There are many on `npm`](https://www.npmjs.com/search?q=validate%20express) depending on your needs. TC member Wes Todd maintains [a middleware-based "code first" OpenAPI library](https://www.npmjs.com/package/@wesleytodd/openapi) for this kind of thing.
+
+#### Splats, optional, and captures oh my
+
+This release includes simplified patterns for common route patterns. With the removal of regular expression semantics comes other small but impactful changes to how you write your routes.
+
+1. `:name?` becomes `{:name}`. Usage of `{}` for optional parts of your route means you can now do things like `/base{/:optional}/:required` and what parts are actually optional is much more explicit.
+2. `*` becomes `*name`.
+3. New reserved characters: `(`, `)`, `[`, `]`, `?`, `+`, & `!`. These have been reserved to leave room for future improvements and to prevent mistakes when migrating where those characters mean specific things in previous versions.
+
+#### Name everything
+
+This release no longer supports ordered numerical parameters.
+
+In Express v4, you could get numerical parameters using regex capture groups (for example, `/user(s?)` => `req.params[0] === 's'`). Now all parameters must be named. Along with requiring a name, Express now supports all valid JavaScript identifiers or quoted (for example, `/:"this"`).
+
+### Promise support
+
+This one may be a bit contentious, but we "promise" we're moving in the right direction. We added support for returned _rejected_ promises from errors raised in middleware. This _does not include_ calling `next` from returned _resolved_ promises. There are a lot of edge cases in old Express apps that have expectations of `Promise` behavior, and before we can run we need to walk. For most folks, this means you can now write middleware like the following:
+
+```javascript
+app.use(async (req, res, next) => {
+ req.locals.user = await getUser(req);
+ next();
+});
+```
+
+Notice that this example uses `async/await` and the `getUser` call may throw an error (if, for example, the user doesn't exist, the user database is down, and so on), but we still call `next` if it is successful. We don't need to catch the error in line anymore if we want to rely on error-handling middleware instead because the router will now catch the rejected promise and treat that as calling `next(err)`.
+
+NOTE: Best practice is to handle errors as close to the site as possible. So while this is now handled in the router, it's best to catch the error in the middleware and handle it without relying on separate error-handling middleware.
+
+### Body parser changes
+
+There are a number of `body-parser` changes:
+
+- Add option to customize the urlencoded body depth with a default value of 32 as mitigation for [CVE-2024-45590](https://nvd.nist.gov/vuln/detail/CVE-2024-45590) ([technical details](https://github.com/expressjs/body-parser/commit/b2695c4450f06ba3b0ccf48d872a229bb41c9bce))
+- Remove deprecated `bodyParser()` combination middleware
+- `req.body` is no longer always initialized to `{}`
+- `urlencoded` parser now defaults `extended` to false
+- Added support for Brotli lossless data compression
+
+### Removing deprecated method signatures
+
+Express v5 removes a number of deprecated method signatures, many of which were carried over from v3. Below are the changes you need to make:
+
+- `res.redirect('back')` and `res.location('back')`: The magic string `'back'` is no longer supported. Use `req.get('Referrer') || '/'` explicitly instead.
+- `res.send(status, body)` and `res.send(body, status)` signatures: Use `res.status(status).send(body)`.
+- `res.send(status)` signature: Use `res.sendStatus(status)` for simple status responses, or `res.status(status).send()` for sending a status code with an optional body.
+- `res.redirect(url, status)` signature: Use `res.redirect(status, url)`.
+- `res.json(status, obj)` and `res.json(obj, status)` signatures: Use `res.status(status).json(obj)`.
+- `res.jsonp(status, obj)` and `res.jsonp(obj, status)` signatures: Use `res.status(status).jsonp(obj)`.
+- `app.param(fn)`: This method has been deprecated. Instead, access parameters directly via `req.params`, or use `req.body` or `req.query` as needed.
+- `app.del('/', () => {})` method: Use `app.delete('/', () => {})` instead.
+- `req.acceptsCharset`: Use `req.acceptsCharsets` (plural).
+- `req.acceptsEncoding`: Use `req.acceptsEncodings` (plural).
+- `req.acceptsLanguage`: Use `req.acceptsLanguages` (plural).
+- `res.sendfile` method: Use `res.sendFile` instead.
+
+As a framework, we aim to ensure that the API is as consistent as possible. We've removed these deprecated signatures to make the API more predictable and easier to use. By streamlining each method to use a single, consistent signature, we simplify the developer experience and reduce confusion.
+
+## Migration and security guidance
+
+For developers looking to migrate from v4 to v5, there's a [detailed migration guide](/en/guide/migrating-5) to help you navigate through the changes and ensure a smooth upgrade process.
+
+Additionally, we’ve been working hard on a comprehensive [Threat Model](https://github.com/expressjs/security-wg/blob/main/docs/ThreatModel.md) that helps illustrate our philosophy of a "Fast, unopinionated, minimalist web framework for Node.js." It provides critical insights into areas like user input validation and security practices that are essential for safe and secure usage of Express in your applications.
+
+## Our work is just starting
+
+We see the v5 release as a milestone toward an Express ecosystem that's a stable and reliable tool for companies, governments, educators, and hobby projects. It is our commitment as the new stewards of the Express project to move the ecosystem forward with this goal in mind. If you want to support this work, which we do on a volunteer basis, please consider supporting the project and its maintainers via [our sponsorship opportunities](https://opencollective.com/express).
+
+We have an [extensive working backlog](https://github.com/expressjs/discussions/issues/266) of tasks, PRs, and issues for Express and dependencies. Naturally, we expect developers will continue to report issues to add to this backlog and open PRs moving forward, and we'll continue to collaborate with the community to triage and resolve them. We look forward to continuing to improve Express and making it useful for its users across the world.
diff --git a/astro/src/content/blog/en/2024-10-22-security-audit-milestone-achievement.md b/astro/src/content/blog/en/2024-10-22-security-audit-milestone-achievement.md
new file mode 100644
index 0000000000..36e8f8bc98
--- /dev/null
+++ b/astro/src/content/blog/en/2024-10-22-security-audit-milestone-achievement.md
@@ -0,0 +1,55 @@
+---
+title: 'Express.js Security Audit: A Milestone Achievement'
+tags: ['security', 'announcements']
+authors:
+ - name: Express Technical Committee
+ github: expressjs
+description: Celebrating the successful completion of the Express.js security audit conducted by Ada Logics and facilitated by OSTIF.
+---
+
+We are thrilled to announce the successful completion of a comprehensive security audit for Express.js, conducted by [Ada Logics](https://adalogics.com/) and facilitated by [OSTIF](https://ostif.org/). This extensive review of our framework and its core components marks a significant milestone in our commitment to ensuring the security and reliability of Express.js for our community.
+
+## A Collaborative Effort
+
+This audit was made possible through the collaboration between [the Express Security Working Group](https://github.com/expressjs/security-wg), Ada Logics, OSTIF, and the [OpenJS Foundation](https://openjsf.org/). Our focus was on thoroughly evaluating the Express.js codebase, including its dependencies and core libraries. The primary goal was to identify any potential security vulnerabilities and to strengthen the overall security posture of the framework.
+
+### Key Highlights of the Audit
+
+- **Audit Duration**: Conducted in April and May 2024.
+- **Scope**: Core Express.js codebase and critical dependencies, such as `body-parser`, `basic-auth-connect`, `serve-static`, and more.
+- **Findings**: A total of 5 security vulnerabilities were identified, all of which have been addressed and patched.
+- **Severity**: Issues ranged from moderate to high severity, impacting components like `res.redirect` and `serve-static`.
+
+## A Closer Look at the Findings
+
+The audit identified several vulnerabilities, including potential Cross-Site Scripting (XSS) risks and a Denial of Service (DoS) vulnerability in the `body-parser` middleware. Here are the key CVEs reported:
+
+- **CVE-2024-43796**: XSS in `res.redirect`—fixed in versions >= 4.20.0 and >= 5.0.0.
+- **CVE-2024-45590**: DoS in `body-parser`—patched in version >= 1.20.3.
+- **CVE-2024-47178**: Timing vulnerability in `basic-auth-connect`—patched in version >= 1.1.0.
+- **CVE-2024-43799**: XSS in the `send` utility module—patched in version >= 0.19.0.
+- **CVE-2024-43800**: XSS in `serve-static`—fixed in versions >= 1.16.0 and >= 2.1.0.
+
+Each of these vulnerabilities was promptly addressed by our dedicated [security triage team](https://github.com/expressjs/security-wg?tab=readme-ov-file#security-triage-team), ensuring that users remain protected against known threats.
+
+For full details on the audit results, you can access the [official audit report here](https://ostif.org/wp-content/uploads/2024/10/expressjs-2024-security-audit-report.pdf).
+
+## A Commitment to Transparency and Security
+
+At Express, security is a top priority, and we believe in the importance of transparency when it comes to vulnerabilities and their resolution. This audit not only highlights our proactive approach but also reinforces our ongoing commitment to building a secure web framework for all.
+
+We strongly recommend all users update to the latest versions of the affected packages to benefit from the recent security fixes. For more information on the patches and how to upgrade, please refer to our [September 2024 Security Release announcement](/en/blog/2024-09-29-security-releases).
+
+## A Word of Thanks
+
+This audit would not have been possible without the efforts and expertise of many individuals and organizations. We want to extend our gratitude to:
+
+- The team at Ada Logics for their diligent review and insights.
+- OSTIF for their coordination and support throughout the audit process.
+- The OpenJS Foundation for sponsoring this important initiative.
+- Our Express.js community, who continue to support and trust us with their projects.
+- [Jordan Harband](https://github.com/ljharb) for his amazing support while we needed changes in [qs](https://www.npmjs.com/package/qs).
+
+Together, we’ve made Express.js stronger, more resilient, and ready for the challenges ahead. We look forward to continuing to serve our community with a focus on excellence and security.
+
+Thank you for being a part of this journey with us!
diff --git a/astro/src/content/blog/en/2025-01-09-rewind-2024-triumphs-and-2025-vision.md b/astro/src/content/blog/en/2025-01-09-rewind-2024-triumphs-and-2025-vision.md
new file mode 100644
index 0000000000..02a74e94f6
--- /dev/null
+++ b/astro/src/content/blog/en/2025-01-09-rewind-2024-triumphs-and-2025-vision.md
@@ -0,0 +1,80 @@
+---
+title: 'A New Chapter for Express.js: Triumphs of 2024 and an ambitious 2025'
+tags: ['announcements']
+authors:
+ - name: Express Technical Committee
+ github: expressjs
+description: Explore the transformative journey of Express.js in 2024, marked by governance improvements, the long-awaited release of Express 5.0, and heightened security measures. Look into the ambitious plans for 2025, including performance optimizations, scoped packages, and a bold roadmap for sustained growth in the Node.js ecosystem.
+---
+
+As we step into the new year, it’s almost impossible to ignore the unmistakable energy coursing through the Express.js community. The past twelve months have proven both foundational and forward-looking: an era of governance overhauls, technical triumphs, and security enhancements that not only shaped 2024 but also laid the groundwork for what promises to be a transformative 2025.
+In this long-form recap and forecast, we’ll journey through the story of Express.js with its evolution, its hurdles, and the new heights it’s poised to reach.
+
+---
+
+## A Transformative 2024
+
+Few could have predicted just how pivotal 2024 would be for the Express.js project. From the revitalization of its governance structures to the unveiling of long-awaited features, it was a year that solidified the framework’s role as a mainstay in the Node.js ecosystem.
+
+### Governance and Community Milestones
+
+Central to the project’s growth was the [Express Forward Plan](https://github.com/expressjs/discussions/issues/160), devised to ensure strategic alignment and long-term sustainability. This year also saw the introduction of a new generation of Technical Committee (TC) members, each bringing fresh insights and energy to the community. Those members include [Blake Embrey](https://github.com/blakeembrey), [Chris de Almeida](https://github.com/ctcpip), [Jean Burellier](https://github.com/sheplu), [Jon Church](https://github.com/jonchurch), [Linus Unnebäck](https://github.com/LinusU), [Rand McKinney](https://github.com/crandmck), [Ulises Gascón](https://github.com/ulisesgascon), and [Wes Todd](https://github.com/wesleytodd). By defining a clear path and transparent processes, the community was able to collaborate on ambitious updates more cohesively than ever before. A revitalized release process further streamlined how new versions are planned and executed, eliminating much of the guesswork and inconsistent timing that had previously challenged contributors.
+
+In parallel, the [Security Working Group](https://github.com/expressjs/discussions/issues/165) took shape. Express.js, widely recognized for its importance to the broader Node.js landscape, formally introduced a [security triage team](https://github.com/expressjs/security-wg#security-triage-team) dedicated to proactively identifying and resolving vulnerabilities. This forward-thinking approach was bolstered by the adoption of a [Threat Model for Express.js](https://github.com/expressjs/express/pull/5526), underscoring the project’s commitment to robust, future-proof security.
+
+As if these achievements weren’t enough, Express.js proudly reached [Impact Project status](https://github.com/openjs-foundation/cross-project-council/pull/1404) under the OpenJS Foundation. This acknowledgment affirmed the significance of the framework to the JavaScript ecosystem and showcased the community’s tireless efforts in ensuring its enduring relevance.
+
+### Technical Advancements and the Release of Express 5.0
+
+Naturally, 2024 will forever be remembered as the year when Express.js finally introduced its much-anticipated [Express 5.0](/en/blog/2024-10-15-v5-release). After more than a decade of community discussions and behind-the-scenes experimentation, this release brought modern features and a future-oriented architecture to the framework, acting as a catalyst for the next chapter of Express.js development.
+
+But the story did not end there. Even before the release of Express 5.0 was fully established, the community had already begun charting the course for [Express 6.0](https://github.com/expressjs/discussions/issues/267), reflecting an unwavering commitment to innovation. Guiding critical decisions throughout 2024 were new [decision framework](https://github.com/expressjs/discussions/issues/285), which helped the Technical Committee tackle pressing matters such as [engine usage](https://github.com/expressjs/discussions/issues/286) and [dependency management](https://github.com/expressjs/discussions/issues/279). Collectively, these measures fostered transparency and agility, ensuring that Express.js continues to evolve in response to the community’s most urgent needs.
+
+### Maintenance, Tooling, and Collaboration
+
+Express.js also deepened its relationship with the Node.js community by re-integrating into the [Node.js CITGM project](https://github.com/expressjs/express/issues/5489). This move ensured broader ecosystem compatibility and provided developers with further validation that they can rely on Express.js as a dependable cornerstone of their Node.js applications.
+
+### A Heightened Security Posture
+
+Above all, 2024 will stand out for Express.js’s vigorous approach to security. In partnership with the [OpenJS Foundation](https://openjsf.org/) and [OSTIF](https://ostif.org/), the project undertook a comprehensive [security audit](/en/blog/2024-10-22-security-audit-milestone-achievement) that yielded critical insights and propelled immediate improvements. The sense of proactive vigilance extended to the adoption of the [OSSF Scorecard](https://github.com/expressjs/discussions/issues/162), implemented at an organizational level to keep track of security metrics and maintain focus on ongoing enhancements.
+
+Throughout the year, maintainers rapidly responded to disclosed vulnerabilities such as [CVE-2024-43796](https://github.com/expressjs/express/security/advisories/GHSA-qw6h-vgh9-j6wx), [CVE-2024-45590](https://github.com/expressjs/body-parser/security/advisories/GHSA-qwcr-r2fm-qrc7), and [CVE-2024-47178](https://github.com/expressjs/basic-auth-connect/security/advisories/GHSA-7p89-p6hx-q4fw). Each instance underscored the community’s readiness to defend the framework’s integrity and safeguard its user base. In a further demonstration of long-term commitment, Express.js teamed up with [HeroDevs](https://www.herodevs.com/) to establish [Never-Ending Support (NES)](https://openjsf.org/blog/at-the-openjs-foundation-were-excited-to-announce-), offering an extended maintenance plan that reaffirms Express.js as a reliable foundation for developers now and in the years to come.
+
+---
+
+## A Bold Vision for 2025
+
+While 2024 laid a sturdy bedrock, the Express.js Technical Committee is not resting on its laurels. The newly revealed roadmap for 2025—bolstered by the [Sovereign Tech Fund (STF)](https://www.sovereign.tech/)—embodies a spirit of forward momentum. It promises notable strides in security, performance, and general developer experience, with each initiative building on the insights gained over the past year.
+
+### Automating npm Releases
+
+At the forefront of this plan is the automation of npm releases, an endeavor designed to free maintainers from manual steps and human error. By streamlining the publishing process, the project can achieve faster turnaround times for patches and new features, preserving the stability that developers have come to expect from Express.js. It’s an internal shift with massive external benefits: smoother upgrades, more frequent releases, and a deeper reservoir of confidence for users.
+
+### Introducing Scoped Packages
+
+Express.js will also explore a transition toward scoped packages. By clearly delineating which modules fall under the Express.js umbrella, the maintainers hope to reduce confusion and foster an environment more conducive to organized expansion. As new packages and features are proposed, scoping will make it simpler to track official tools and ensure that community contributions meet consistent quality standards.
+
+### Strengthening Security Reporting and Procedures
+
+Since security remains one of the project’s primary pillars, 2025 will see a significant push to refine how vulnerabilities are reported and managed. Building upon the success of the Security Working Group, the new process will introduce transparent guidelines for reporting potential issues and a consistent triage routine for mitigating them. Additional training for both the Security Triage group and the Technical Committee will further cultivate a shared culture of readiness. Moreover, Express.js is poised to integrate [OSSF Scorecard](https://github.com/expressjs/discussions/issues/162) even more deeply into daily operations, ensuring that both maintainers and users have real-time insights into the project’s health.
+
+### Performance Monitoring and Deep-Level Optimizations
+
+Performance is another focal point. By systematically monitoring the framework’s speed and responsiveness—along with that of its dependencies—the Express.js team aims to pinpoint bottlenecks more rapidly. Over time, insights from these monitoring efforts will drive deeper optimizations in the core Express.js code and its core libraries. These improvements, expected to come to fruition by mid-2026, promise a faster, more scalable framework that can handle the heaviest production workloads with ease.
+
+### Phasing Out Legacy Techniques and Enhancing Documentation
+
+A future of agility and resilience depends on eliminating outdated techniques that invite complexity and fragility. As a result, Express.js will begin phasing out monkey-patching and passthrough APIs that rely too heavily on Node.js internals. This modernization strategy not only reduces technical debt but also ensures that Express.js remains aligned with Node.js updates going forward.
+
+In tandem, the project will make a concerted effort to bolster its security documentation. Through updated guides and best practices, maintainers hope to demystify crucial topics like secure session handling, input validation, and access control. The goal is to arm developers—from novices to seasoned engineers—with the knowledge they need to protect their applications against an ever-evolving threat landscape.
+
+---
+
+## The Road Ahead
+
+As Express.js steps into 2025, it does so with a powerful sense of purpose. The achievements of the past year—culminating in the official release of Express 5.0 and wide-reaching governance enhancements—serve as a sturdy foundation for what’s to come. Yet, the framework’s leadership knows there is always more to build, more to secure, and more to imagine.
+
+Through automated releases, scopes for packages, rigorous security protocols, performance monitoring, and an ongoing effort to modernize core APIs, Express.js is evolving in real-time. And it isn’t just about technology; it’s about forging a collaborative environment where contributors can rely on transparent processes, robust training, and a supportive governance structure.
+
+Whether you’re a seasoned maintainer, an occasional contributor, or a newcomer to this thriving ecosystem, your voice matters. Join the [Express.js GitHub Discussions](https://github.com/expressjs/discussions), attend open meetings, and stay tuned for updates on [Express.js blog](https://expressjs.com/) as we finalize timetables for these initiatives. Each advancement, no matter how technical, flows from a common aspiration: to sustain Express.js as a fast, safe, and influential framework for millions of developers worldwide.
+Together, we’ll keep the spirit of 2024 alive—pushing boundaries, refining practices, and laying the path to a future where Express.js remains at the heart of modern web development.
diff --git a/astro/src/content/blog/en/2025-03-31-v5-1-latest-release.md b/astro/src/content/blog/en/2025-03-31-v5-1-latest-release.md
new file mode 100644
index 0000000000..149dcf439e
--- /dev/null
+++ b/astro/src/content/blog/en/2025-03-31-v5-1-latest-release.md
@@ -0,0 +1,170 @@
+---
+title: 'Express@5.1.0: Now the Default on npm with LTS Timeline'
+tags: ['announcements']
+authors:
+ - name: Express Technical Committee
+ github: expressjs
+description: Express 5.1.0 is now the default on npm, and we're introducing an official LTS schedule for the v4 and v5 release lines.
+---
+
+Express v5.0.0 was released on September 9th last year, but we didn't make it the `latest` release on npm. Many asked us
+why and when it would be, and frankly we were not ready at the time to take that jump. If you have not followed the news
+from the project this past year, we have been [hard at work reviving the project](/en/blog/2025-01-09-rewind-2024-triumphs-and-2025-vision/)
+and when we pushed the initial v5 release there were many loose ends still hanging. So first lets quickly go over some
+of those loose ends.
+
+### Documentation updates
+
+We had not updated the docs, provided migration guides, or even fully reviewed some of the stagnated v4/5 docs in a long
+time. Since then we have had tons of great contributors help get things into better shape. As with any volunteer based
+Open Source project, we love contributions to help us improve so as you upgrade please continue to open PRs to fix
+anything we missed.
+
+You can find our [v5 docs](/en/5x/api) and our [migration guide](/en/guide/migrating-5) on the website.
+
+### Migration Support
+
+We know that migrating between versions can be challenging, especially when it involves significant changes in a widely used framework like Express. That's why we have worked on a solution to simplify part of the process and reduce the impact on developers.
+
+Thanks to the incredible efforts of [Sebastian](https://github.com/bjohansebas) and [Filip](https://github.com/kjugi), we have developed a new [codemod package](https://www.npmjs.com/package/@expressjs/codemod) specifically designed to facilitate the transition from Express v4 to v5, as well as future major versions. This package automates many of the necessary code changes, minimizing manual effort and making the upgrade as smooth and efficient as possible.
+
+However, we understand that not all changes can be automated. Some breaking changes, such as the [new Path Route Matching syntax](/en/guide/migrating-5#path-syntax), require manual modifications by developers. You can read more about all of the breaking changes which came with v5 in our [original release announcement](/en/blog/2024-10-15-v5-release).
+
+For more details on the migration process and how to use the codemod package, check the [repository’s README](https://github.com/expressjs/codemod#readme) and the [migration guide](/en/guide/migrating-5).
+
+### Ecosystem compatibility
+
+The Express ecosystem is one of its strongest assets. It goes back to the early days of Node.js and is the backbone
+that keeps express popular. When it goes [10 years without a major release](/en/blog/2024-10-15-v5-release)
+everything from middleware to documentation needed updates. We wanted to make sure folks had
+some time to get all of that updated before we had everyone moving over. Particularly we care about our very large
+beginner user base who may not know the blog post they are reading is not compatible with what they get from
+`npm i express`.
+
+We recognize that some friction is inevitable during major upgrades, but thanks to work from ecosystem partners
+like [Kamil](https://github.com/kamilmysliwiec) from NestJS [working to update `express` before we went `latest`](https://github.com/expressjs/express/issues/5944#issuecomment-2523074127)
+we will hopefully be ahead of the curve. And as I said above, we always welcome help to make this transition easier for
+those who follow after you, PRs are the best support you can give.
+
+### Long Term Support
+
+We had been discussing how to support v4 now that v5 was out, but we had not defined a clear guideline or expectation,
+and we had (still don't have) end user docs on our plans here. While we still have progress to make here, we have a
+[proposed LTS strategy ](https://github.com/expressjs/discussions/pull/352) which will be the basis for our forthcoming
+docs. Input is very welcome on this so we can make sure it is clearly communicated and acceptable to the community.
+
+Additionally since then [we have announced a partnership with HeroDevs](/en/blog/2024-10-01-herodevs-partnership-announcement) to help companies who are less capable of
+updating. More information on how this will work when v4 EOL will come when we get closer to that time.
+
+---
+
+## Support Phases and Going latest
+
+What does it mean to "go latest"? If you are unfamiliar with how npm `dist-tags` work, the `latest` tag is what users
+will get when they run `npm install express`. This is important because it means it is the "default installed version"
+and will trigger the transition of nearly 17 million weekly downloads from our current latest v4.21.2 to v5. As we start
+this transition we want users, companies, and other organizations to know exactly what it means for support. To help
+with this we have developed an LTS strategy which defines our 3 support phases and set's target dates for when v4 will
+enter EOL.
+
+Express major versions will go through three supported phases:
+
+- `CURRENT`: A new major version is designated as `CURRENT` upon release. It is available but not the `latest` version
+ on npm for a minimum of 3 months.
+- `ACTIVE`: After the minimum 3 month period and the TC agrees it is stable and secure, the `ACTIVE` version is
+ tagged `latest` on npm for a minimum of 12 months.
+- `MAINTENANCE`: When a new major version becomes `ACTIVE`, the previous major version enters `MAINTENANCE` for 12 months.
+
+### CURRENT
+
+- New majors will go through a short period of hardening to ensure stability, security, and ecosystem libraries/resources
+ compatibility.
+- We will strive to ensure no breaking changes are included, but reserve the right to make security or high priority
+ fixes of breaking nature within this period.
+- `CURRENT` lines will receive all types of active work including: bug fixes, security patches, new features, and
+ deprecation notices.
+- Users are recommended to use `CURRENT` lines and to upgrade as quickly as their risk profile allows
+
+### ACTIVE
+
+- `ACTIVE` lines will receive all types of active work including: bug fixes, security patches, new features, and
+ deprecation notices.
+- For users, `ACTIVE` lines are considered the most stable and well supported version at any given time.
+
+### MAINTENANCE
+
+- `MAINTENANCE` lines will only receive security patches or high priority bug fixes.
+- Users are highly encouraged to upgrade to a `CURRENT` or `ACTIVE` release.
+
+### Proposed Schedule
+
+For the existing release lines, we will set the following phase dates:
+
+
+
+| Major | CURRENT | ACTIVE | MAINTENANCE | EOL |
+| ----- | ------------------------------- | ---------- | ----------------------------- | ----------------------------- |
+| 4.x | | | 2025-04-01 | \*no sooner than 2026-10-01 |
+| 5.x | 2024-09-11 | 2025-03-31 | \*\*no sooner than 2026-04-01 | \*\*no sooner than 2027-04-01 |
+| 6.x | \*\*\*no sooner than 2026-01-01 | | | |
+
+
+
+As you can see, this means that v5.1.0 being tagged `latest` indicates that we moved from `CURRENT` to `ACTIVE` which
+starts the clock on EOL for v4 by moving it to `MAINTENANCE`. We recognize that v4 is a special case having been the
+only major version for most of the history of Node.js itself. Because of this, we want to remain flexible and also
+provide a bit longer support. We want to do what is best for the ecosystem, so consider these goals not commitments.
+
+\*: v4 is a special case, and we may extend MAINTENENCE support
+\*\*: v5 MAINTENENCE and EOL dates are determined by when v6 is released, these dates reflect the earliest dates if we
+were to ship v6 on 2025-10-01
+\*\*\* : v6 work has not officially started yet, this is simply the earliest date we can ship based on our proposed policy
+
+---
+
+## Finally, what changed in v5.1.0
+
+This release primarily focused on tech debt from supporting so many old Node.js versions and other things that stagnated but were not landed before v5.0.0 went out.
+
+### Express 5.1.0 Main Changes
+
+- Add support for `Uint8Array` in `res.send()`
+- Transitioned all remaining dependencies to use `^` ranges instead of locked versions
+- Add package.json funding field to highlight our OpenCollective
+- Added support for ETag option in `res.sendFile()`
+- Added support for adding multiple links with the same rel with `res.links()`
+- Performance: Use loop for acceptParams
+- See [Changelog v5.1.0](https://github.com/expressjs/express/releases/tag/v5.1.0)
+
+### Dependencies updated
+
+We also invested time to prepare several releases in the packages that Express depend on. Most of this packages are used by other libraries and framework as individual libraries.
+
+- [body-parser@2.2.0](https://github.com/expressjs/body-parser/releases/tag/v2.2.0)
+ - Remove legacy node.js support checks for Brotli & `AsyncLocalStorage`
+ - Remove `unpipe` & `destroy`
+- [router@2.2.0](https://github.com/pillarjs/router/releases/tag/v2.2.0)
+ - Restore `debug`. Now with the `router` scope instead of `express`.
+ - Remove legacy node.js support checks for `setImmediate`
+ - Deprecate non-native promise support
+ - Remove `after`, `safe-buffer`, `array-flatten`, `setprotoypeof`, `methods`, `utils-merge`
+- [finalhandler@2.1.0](https://github.com/pillarjs/finalhandler/releases/tag/v2.1.0)
+ - Remove legacy node.js support checks for `headersSent`, `setImmediate`, & http2 support
+ - Remove `unpipe`
+- [serve-static@2.2.0](https://github.com/expressjs/serve-static/releases/tag/v2.2.0)
+
+---
+
+## Thanks and What's Next
+
+Thanks so much to everyone involved in Express over the past year, the work all our contributors have put in is
+incredible, and we couldn't do it without them. If you are not able to become a contributor yourself, please consider
+asking your companies to support the project financially on [OpenCollective](https://opencollective.com/express).
+
+As we look ahead, we’re excited to keep building momentum. If you haven’t read it yet, our [Rewind 2024 + 2025 Vision blog post](/en/blog/2025-01-09-rewind-2024-triumphs-and-2025-vision) lays out where we’ve been and where we're headed. This includes performances scoped packages, better automation, security hardening, and more.
+
+One major initiative is our new [Performance Working Group](https://github.com/expressjs/discussions/pull/306), focused on identifying and fixing long-standing bottlenecks in Express. We're grateful to be kicking this off with support from the [Sovereign Tech Fund (STF)](https://www.sovereign.tech/), who are helping us invest in long-term sustainability and performance of core infrastructure. Additionally, we will be working to [improve our Typescript DX](https://github.com/expressjs/discussions/issues/192) and taking next steps to [improve the website](https://github.com/expressjs/expressjs.com/issues/1787).
+
+And yes, v6 discussions are already starting to heat up. Keep an eye out for updates, and as always, see you in the issues!
+
+Big thanks to [@wesleytodd](https://github.com/wesleytodd), [@blakeembrey](https://github.com/blakeembrey), [@bjohansebas](https://github.com/bjohansebas), [@UlisesGascon](https://github.com/UlisesGascon), [@Phillip9587](https://github.com/Phillip9587), [@carpasse](https://github.com/carpasse), [@jonchurch](https://github.com/jonchurch), [@ctcpip](https://github.com/ctcpip), [@inigomarquinez](https://github.com/inigomarquinez), [@carlosstenzel](https://github.com/carlosstenzel), [@crandmck](https://github.com/crandmck), [@chrisdel101](https://github.com/chrisdel101), [@dpopp07](https://github.com/dpopp07), [@Ayoub-Mabrouk](https://github.com/Ayoub-Mabrouk), [@jonkoops](https://github.com/jonkoops), [@IamLizu](https://github.com/IamLizu), [@marco-ippolito](https://github.com/marco-ippolito), [@ipreencekmr](https://github.com/ipreencekmr), [@ShubhamOulkar](https://github.com/ShubhamOulkar), [@raksbisht](https://github.com/raksbisht), [@jeffreybaird](https://github.com/jeffreybaird), [@dougwilson](https://github.com/dougwilson), [@mertcanaltin](https://github.com/mertcanaltin), [@GeorgeShvab](https://github.com/GeorgeShvab), [@RobinTail](https://github.com/RobinTail), [@EvanHahn](https://github.com/EvanHahn), [@rhodgkins](https://github.com/rhodgkins), [@cengizcmataraci](https://github.com/cengizcmataraci), [@Shantanugupta43](https://github.com/Shantanugupta43), [@italojs](https://github.com/italojs), [@ljharb](https://github.com/ljharb), [@MaoShizhong](https://github.com/MaoShizhong), [@aroyan](https://github.com/aroyan), [@Binilkks](https://github.com/Binilkks), [@danielgindi](https://github.com/danielgindi), [@papandreou](https://github.com/papandreou), [@jsoref](https://github.com/jsoref), [@bigbigDreamer](https://github.com/bigbigDreamer), [@broofa](https://github.com/broofa), [@CommanderRoot](https://github.com/CommanderRoot), [@andvea](https://github.com/andvea), [@juanarbol](https://github.com/juanarbol), [@agungjati](https://github.com/agungjati), [@alexandercerutti](https://github.com/alexandercerutti), [@pr4j3sh](https://github.com/pr4j3sh), [@hamirmahal](https://github.com/hamirmahal), [@slagiewka](https://github.com/slagiewka), [@Abdel-Monaam-Aouini](https://github.com/Abdel-Monaam-Aouini), [@sazk07](https://github.com/sazk07), [@bhavya3024](https://github.com/bhavya3024), [@joshbuker](https://github.com/joshbuker), [@almic](https://github.com/almic), [@FDrag0n](https://github.com/FDrag0n), [@Dmitry-Kondar](https://github.com/Dmitry-Kondar), [@attrid](https://github.com/attrid), [@kristof-low](https://github.com/kristof-low), [@gireeshpunathil](https://github.com/gireeshpunathil), [@UzairJ99](https://github.com/UzairJ99), [@choi2021](https://github.com/choi2021), [@hayden36](https://github.com/hayden36), [@joharkhan99](https://github.com/joharkhan99), [@peterh-capella](https://github.com/peterh-capella), [@johnburnett](https://github.com/johnburnett), [@nicolasgandrade](https://github.com/nicolasgandrade), [@axhuwastaken](https://github.com/axhuwastaken), [@abhijeetpandit7](https://github.com/abhijeetpandit7), [@peterdanwan](https://github.com/peterdanwan), [@rehmansheikh222](https://github.com/rehmansheikh222), [@corydalis10](https://github.com/corydalis10), [@mgsantos177](https://github.com/mgsantos177), [@wilyJ80](https://github.com/wilyJ80), [@LuiGeeDev](https://github.com/LuiGeeDev), [@juliogarciape](https://github.com/juliogarciape), [@aelmardhi](https://github.com/aelmardhi), [@Ahmed1monm](https://github.com/Ahmed1monm), [@erensarac](https://github.com/erensarac), [@tomasz13nocon](https://github.com/tomasz13nocon), [@tianbuyung](https://github.com/tianbuyung), [@GreyTearsDev](https://github.com/GreyTearsDev), [@aastha-cse](https://github.com/aastha-cse), [@krzysdz](https://github.com/krzysdz), [@Miguelrom](https://github.com/Miguelrom), [@bnoordhuis](https://github.com/bnoordhuis), [@MehfoozurRehman](https://github.com/MehfoozurRehman), [@EasonLin0716](https://github.com/EasonLin0716), [@grjan7](https://github.com/grjan7), [@mishrasur7](https://github.com/mishrasur7), [@gregfenton](https://github.com/gregfenton), [@zareefhasan](https://github.com/zareefhasan), [@Tejas150](https://github.com/Tejas150), [@jpricardo](https://github.com/jpricardo), [@nikeee](https://github.com/nikeee), [@dotnetCarpenter](https://github.com/dotnetCarpenter), [@engpetermwangi](https://github.com/engpetermwangi), [@msimerson](https://github.com/msimerson), [@fetsorn](https://github.com/fetsorn), [@manoharreddyporeddy](https://github.com/manoharreddyporeddy), [@lancatlin](https://github.com/lancatlin), [@mifi](https://github.com/mifi), [@meowingwhitey](https://github.com/meowingwhitey), [@sheplu](https://github.com/sheplu), [@krsriq](https://github.com/krsriq), [@ravibisht](https://github.com/ravibisht), [@wojtekmaj](https://github.com/wojtekmaj), [@aqeelat](https://github.com/aqeelat), [@melikhov-dev](https://github.com/melikhov-dev), [@alexstrat](https://github.com/alexstrat), [@isnifer](https://github.com/isnifer), [@TorstenDittmann](https://github.com/TorstenDittmann), [@Uzlopak](https://github.com/Uzlopak), [@gurgunday](https://github.com/gurgunday), [@kurtextrem](https://github.com/kurtextrem), [@hdtmccallie](https://github.com/hdtmccallie), [@proudparrot2](https://github.com/proudparrot2), [@bewinsnw](https://github.com/bewinsnw), [@jonboulle](https://github.com/jonboulle), [@alexander-akait](https://github.com/alexander-akait), [@alxndrsn](https://github.com/alxndrsn), [@DimitriPapadopoulos](https://github.com/DimitriPapadopoulos), [@greggman](https://github.com/greggman), [@jkbach](https://github.com/jkbach), [@julien-c](https://github.com/julien-c), [@risu729](https://github.com/risu729), [@JohnSimumatik](https://github.com/JohnSimumatik), [@dhouck](https://github.com/dhouck), [@pedro-php](https://github.com/pedro-php), [@aminerol](https://github.com/aminerol), [@robertsky](https://github.com/robertsky), [@ipetrouchtchak-fi](https://github.com/ipetrouchtchak-fi), [@tinhochu](https://github.com/tinhochu), [@Lord-Kamina](https://github.com/Lord-Kamina), [@joshkel](https://github.com/joshkel), [@raiandexter0607](https://github.com/raiandexter0607), [@NateEag](https://github.com/NateEag), [@rmhaiderali](https://github.com/rmhaiderali), [@ljeda](https://github.com/ljeda)
diff --git a/astro/src/content/blog/en/2025-05-16-express-cleanup-legacy-packages.md b/astro/src/content/blog/en/2025-05-16-express-cleanup-legacy-packages.md
new file mode 100644
index 0000000000..500d48cb51
--- /dev/null
+++ b/astro/src/content/blog/en/2025-05-16-express-cleanup-legacy-packages.md
@@ -0,0 +1,48 @@
+---
+title: 'Spring Cleaning in Express.js: Deprecations and the Path Ahead'
+tags: ['announcements']
+authors:
+ - name: Express Technical Committee
+ github: expressjs
+description: As part of a broader effort to modernize and streamline Express.js, we’ve deprecated several outdated packages including csurf, connect-multiparty, and path-match. Learn why we made these changes and what it means for the future of the framework.
+---
+
+As Express.js continues to power web applications across the world, it's important that we maintain a clean, reliable, and modern codebase. In that spirit, we've done a bit of spring cleaning.
+
+Over the past few weeks, we've evaluated legacy packages within the Express.js ecosystem — some of which have become outdated, unmaintained, or misaligned with modern best practices. As a result, we’ve officially deprecated several of them.
+
+## 🚨 Packages Deprecated
+
+Here are the key packages we’ve deprecated:
+
+- [`csurf`](https://www.npmjs.com/package/csurf): A CSRF middleware that’s long been difficult to maintain and is better handled today through frameworks or custom implementations that align with your architecture.
+- [`connect-multiparty`](https://www.npmjs.com/package/connect-multiparty): A multipart form-data parser that relies on deprecated libraries and hasn’t aged well.
+- [`path-match`](https://www.npmjs.com/package/path-match): A route-matching utility that has been superseded by more modern and maintained alternatives.
+
+Each of these packages was originally created to solve real problems—but time has moved on, and the ecosystem has evolved.
+
+## 🤔 Why This Matters
+
+Maintaining deprecated or inactive dependencies introduces technical debt and security risk. By formally deprecating these packages, we:
+
+- Encourage developers to adopt better-maintained and more secure solutions.
+- Reduce confusion around which tools are actively supported by Express.
+- Focus our efforts on modernizing the core and surrounding ecosystem.
+
+## 🗂️ What You Should Do
+
+If your application depends on any of these packages, now is a great time to look for alternatives. For instance:
+
+- Consider finding a modern CSRF protection strategy on [npm](https://www.npmjs.com/search?q=csurf) that aligns with your specific needs.
+- Use up-to-date multipart parsers like [`multer`](https://www.npmjs.com/package/multer).
+- Replace path-match logic with standard [`path-to-regexp`](https://www.npmjs.com/package/path-to-regexp).
+
+## 📘 What's Next
+
+We're not stopping here. This cleanup is part of a broader effort to streamline Express.js, prepare for the future, and clarify what is and isn’t officially supported.
+
+👉 A full discussion of these changes can be found [expressjs/discussions#134](https://github.com/expressjs/discussions/issues/134).
+
+📢 Stay tuned—we'll continue to post updates and insights as we modernize the Express ecosystem.
+
+💚Thanks to the community for your continued trust and support.
diff --git a/astro/src/content/blog/en/2025-05-19-security-releases.md b/astro/src/content/blog/en/2025-05-19-security-releases.md
new file mode 100644
index 0000000000..f66906eb1e
--- /dev/null
+++ b/astro/src/content/blog/en/2025-05-19-security-releases.md
@@ -0,0 +1,51 @@
+---
+title: May 2025 Security Releases
+description: Security release for Multer has been published. We recommend that all users upgrade as soon as possible.
+tags: ['security']
+authors:
+ - name: Ulises Gascón
+ github: UlisesGascon
+---
+
+The Express team has released a new major version of [Multer](https://www.npmjs.com/package/multer) addressing two high-severity security vulnerabilities. This update improves the reliability and security of handling file uploads in Express applications.
+
+{% include admonitions/warning.html
+content="We strongly recommend that you upgrade to Multer v2.0.0 or later as soon as possible."
+%}
+
+The following vulnerabilities have been addressed:
+
+- [High severity vulnerability CVE-2025-47935 in Multer middleware](#high-severity-vulnerability-cve-2025-47935-in-multer-middleware)
+- [High severity vulnerability CVE-2025-47944 in Multer middleware](#high-severity-vulnerability-cve-2025-47944-in-multer-middleware)
+
+## High severity vulnerability CVE-2025-47935 in Multer middleware
+
+**[Multer](https://www.npmjs.com/package/multer) versions `<2.0.0` are vulnerable to denial of service due to a memory leak caused by improper stream handling.**
+
+When the HTTP request stream emits an error, the internal `busboy` stream is not closed, violating Node.js stream safety guidance.
+
+This leads to unclosed streams accumulating over time, consuming memory and file descriptors. Under sustained or repeated failure conditions, this can result in denial of service, requiring manual server restarts to recover. All users of Multer handling file uploads are potentially impacted.
+
+**Affected versions**: `<2.0.0`
+**Patched version**: `>=2.0.0`
+
+For more details, see [GHSA-44fp-w29j-9vj5](https://github.com/expressjs/multer/security/advisories/GHSA-44fp-w29j-9vj5).
+
+## High severity vulnerability CVE-2025-47944 in Multer middleware
+
+**[Multer](https://www.npmjs.com/package/multer) versions `>=1.4.4-lts.1` and `<2.0.0` are vulnerable to a denial of service via a malformed multipart request.**
+
+A specially crafted request can cause an unhandled exception inside Multer, resulting in a crash of the server process.
+
+**Affected versions**: `>=1.4.4-lts.1` and `<2.0.0`
+**Patched version**: `>=2.0.0`
+
+For more details, see [GHSA-4pg4-qvpc-4q3h](https://github.com/expressjs/multer/security/advisories/GHSA-4pg4-qvpc-4q3h).
+
+---
+
+**Multer v2.0.0** also introduces a breaking change:
+
+- The minimum supported Node.js version is now **10.16.0**.
+
+We recommend upgrading to the latest version of Multer immediately to secure your applications.
diff --git a/astro/src/content/blog/en/2025-06-05-vulnerability-reporting-process-overhaul.md b/astro/src/content/blog/en/2025-06-05-vulnerability-reporting-process-overhaul.md
new file mode 100644
index 0000000000..f227665d72
--- /dev/null
+++ b/astro/src/content/blog/en/2025-06-05-vulnerability-reporting-process-overhaul.md
@@ -0,0 +1,84 @@
+---
+title: How Express.js Rebuilt Its Vulnerability Reporting Process
+description: Express.js has overhauled its vulnerability reporting workflow with a unified process, consolidated documentation, and GitHub Security Advisories enabled across all repositories.
+tags: ['security']
+authors:
+ - name: Ulises Gascón
+ github: UlisesGascon
+---
+
+The Express.js project has completed a major milestone in its ongoing commitment to security: the implementation of a formal, centralized vulnerability reporting and response process.
+
+Until recently, security reports were typically handled over email — an approach that worked in the early days but no longer scaled with the growing complexity and user base of Express. This informal system introduced potential delays, inconsistent handling, and increased the risk of issues being missed or misunderstood.
+
+Thanks to support from the [Sovereign Tech Fund](https://sovereign.tech), the Express.js Security Working Group has now completed a ground-up overhaul of how we manage vulnerability reports.
+
+## 🛠️ Key Improvements
+
+### Formalized Vulnerability Reporting Workflow
+
+A comprehensive runbook and process flow have been created to guide maintainers through each step of triaging, confirming, and addressing reported security issues.
+
+- [View the documentation](https://github.com/expressjs/security-wg/blob/main/docs/incident_response_plan.md)
+- [Security Report Handling Flowchart](https://github.com/expressjs/security-wg/blob/main/docs/incident_response_plan.md#security-report-handling-flowchart)
+
+### Unified Security Policy Across Repositories
+
+All Express.js repositories now share a single, unified `SECURITY.md` policy to ensure consistency and remove confusion for reporters and maintainers alike.
+
+- [View the unified Security Policy](https://github.com/expressjs/.github/blob/master/SECURITY.md)
+
+### GitHub Security Advisories Enabled
+
+Security Advisories are now enabled across all Express.js repositories, allowing for secure, private vulnerability reporting through GitHub’s built-in system.
+
+- [How to report a security bug using GitHub Security Advisory](https://github.com/expressjs/.github/blob/master/SECURITY.md#reporting-security-bugs-via-github-security-advisory-preferred)
+
+### Clear Maintainer Responsibilities
+
+Expectations around ownership and response timelines have been clarified and published to reduce ambiguity and improve responsiveness.
+
+> A [Security triage team member](https://github.com/expressjs/security-wg#security-triage-team) or [the repo captain](https://github.com/expressjs/discussions/blob/master/docs/contributing/captains_and_committers.md) will acknowledge your report as soon as possible.
+>
+> After the initial reply to your report, the security team will
+> endeavor to keep you informed of the progress towards a fix and full
+> announcement, and may ask for additional information or guidance.
+>
+> _[Security Policy](https://github.com/expressjs/.github/blob/master/SECURITY.md)_
+
+## 🛡️ Express is Now Covered Under the OpenJS Foundation CNA
+
+As of June 2025, the [OpenJS Foundation](https://openjsf.org/) is officially a [CVE Numbering Authority (CNA)](https://openjsf.org/blog/openjs-foundation-cna), empowered to assign CVE identifiers for security vulnerabilities across its hosted projects—including Express.
+
+What this means for the community:
+
+- Security vulnerabilities in Express can now receive official CVE IDs through OpenJS, improving transparency and coordination.
+- The foundation provides support and tooling to streamline the vulnerability disclosure process, particularly for maintainers and security researchers.
+- For critical issues, the CNA helps ensure that disclosures follow best practices and are recorded in global vulnerability databases.
+
+Please refer to [Express’s Security Policy](https://github.com/expressjs/express/security/policy) for the correct disclosure process. If needed, escalation routes through the OpenJS CNA are now available.
+
+This advancement is part of a broader effort to strengthen the security of JavaScript’s open-source ecosystem—especially for widely used, community-driven projects like Express.
+
+Learn more:
+
+- [OpenJS Foundation is now a CNA – Official Blog Post](https://openjsf.org/blog/openjs-foundation-cna)
+- [Socket.dev Coverage: OpenJS Foundation Becomes a CNA](https://socket.dev/blog/openjs-foundation-is-now-a-cna)
+
+## 👀 Coming Soon: Bug Bounty Program in the Works
+
+To further enhance the security of our ecosystem and encourage responsible vulnerability disclosure, the Express.js team has begun exploring participation in a community-focused bug bounty initiative—powered by the [Sovereign Tech Resilience program](https://www.sovereign.tech/programs/bug-resilience).
+
+This collaboration aims to:
+
+- Reward contributors for discovering and responsibly reporting security issues
+- Improve our ability to address vulnerabilities quickly and transparently
+- Strengthen long-term resilience for users and maintainers alike
+
+Join the conversation and share your thoughts in [expressjs/discussions#345 – Bug Bounty Proposal](https://github.com/expressjs/discussions/issues/345)
+
+## Why This Matters
+
+Security is a shared responsibility — and one that must evolve as the project grows. With these updates, Express.js has laid the foundation for a more reliable, scalable, and transparent vulnerability response system.
+
+We’re grateful to the [OpenJS Foundation](https://openjsf.org/) and the [Sovereign Tech Fund](https://www.sovereign.tech/) for their support and are excited to share this progress with the broader community.
diff --git a/astro/src/content/blog/en/2025-07-18-security-releases.md b/astro/src/content/blog/en/2025-07-18-security-releases.md
new file mode 100644
index 0000000000..2e716847b9
--- /dev/null
+++ b/astro/src/content/blog/en/2025-07-18-security-releases.md
@@ -0,0 +1,27 @@
+---
+title: June 2025 Security Releases
+description: Security update for Multer released. All users are encouraged to upgrade.
+tags: ['security']
+authors:
+ - name: Ulises Gascón
+ github: UlisesGascon
+---
+
+The Express team has released a new patch version of [Multer](https://www.npmjs.com/package/multer), addressing a high-severity vulnerability that could lead to a Denial of Service (DoS) attack.
+
+{% include admonitions/warning.html
+content="We strongly recommend that all users upgrade to Multer v2.0.1 or later immediately."
+%}
+
+This release addresses the following vulnerability:
+
+### High severity vulnerability CVE-2025-48997 in Multer middleware
+
+**[Multer](https://www.npmjs.com/package/multer) versions `>=1.4.4-lts.1` and `<2.0.1` are vulnerable to a Denial of Service (DoS) attack.**
+
+An attacker can trigger this vulnerability by sending an upload request with an empty string as the field name. This malformed request causes an unhandled exception, leading to a crash of the server process.
+
+**Affected versions**: `>=1.4.4-lts.1` and `<2.0.1`
+**Patched version**: `2.0.1`
+
+For more details, see [GHSA-g5hg-p3ph-g8qg](https://github.com/expressjs/multer/security/advisories/GHSA-g5hg-p3ph-g8qg).
diff --git a/astro/src/content/blog/en/2025-07-31-security-releases.md b/astro/src/content/blog/en/2025-07-31-security-releases.md
new file mode 100644
index 0000000000..694e5c7ac4
--- /dev/null
+++ b/astro/src/content/blog/en/2025-07-31-security-releases.md
@@ -0,0 +1,47 @@
+---
+title: July 2025 Security Releases
+description: Security releases for Multer and On-headers has been published. We recommend that all users upgrade as soon as possible.
+tags: ['security']
+authors:
+ - name: Ulises Gascón
+ github: UlisesGascon
+---
+
+import Alert from '@components/primitives/Alert/Alert.astro';
+
+The Express team has released a new patch version of [Multer](https://www.npmjs.com/package/multer) addressing a high-severity security vulnerability, and a new minor version of [on-headers](https://www.npmjs.com/package/on-headers) addressing a low-severity security vulnerability.
+
+
+We recommend upgrading to the latest version of Multer and On-headers immediately to secure your applications.
+
+
+The following vulnerabilities have been addressed:
+
+- [High severity vulnerability CVE-2025-7338 in Multer middleware](#high-severity-vulnerability-cve-2025-7338-in-multer-middleware)
+- [Low severity vulnerability CVE-2025-7339 in On-header middleware](#low-severity-vulnerability-cve-2025-7339-in-on-header-middleware)
+
+## High severity vulnerability CVE-2025-7338 in Multer middleware
+
+**[Multer](https://www.npmjs.com/package/multer) versions `>=1.4.4-lts.1` and `<2.0.2` are vulnerable to denial of service via unhandled exception from malformed request.**
+
+This request causes an unhandled exception, leading to a crash of the process.
+
+**Affected versions**: `>=1.4.4-lts.1, <2.0.2`
+**Patched version**: `2.0.2`
+
+For more details, see [GHSA-fjgf-rc76-4x9p](https://github.com/expressjs/multer/security/advisories/GHSA-fjgf-rc76-4x9p).
+
+## Low severity vulnerability CVE-2025-7339 in On-header middleware
+
+**[On-headers](https://www.npmjs.com/package/on-headers) versions `<1.1.0` is vulnerable to http response header manipulation**
+
+A bug in on-headers versions `<1.1.0` may result in response headers being inadvertently modified when an array is passed to `response.writeHead()`
+
+**Affected versions**: `<1.1.0`
+**Patched version**: `1.1.0`
+
+For more details, see [GHSA-76c9-3jph-rj3q](https://github.com/jshttp/on-headers/security/advisories/GHSA-76c9-3jph-rj3q).
+
+---
+
+We recommend upgrading to the latest version of Multer and On-headers immediately to secure your applications.
diff --git a/astro/src/content/blog/en/2025-12-01-security-releases.mdx b/astro/src/content/blog/en/2025-12-01-security-releases.mdx
new file mode 100644
index 0000000000..fb2ce9abf4
--- /dev/null
+++ b/astro/src/content/blog/en/2025-12-01-security-releases.mdx
@@ -0,0 +1,35 @@
+---
+title: November 2025 Security Releases
+description: Security release for body-parser has been published. We recommend that all users upgrade as soon as possible.
+tags: ['security']
+authors:
+ - name: Ulises Gascón
+ github: UlisesGascon
+---
+
+import Alert from '@components/primitives/Alert/Alert.astro';
+
+The Express team has released a new patch version of [body-parser](https://www.npmjs.com/package/body-parser) addressing a moderate-severity security vulnerability.
+
+
+ We recommend upgrading to the latest version of body-parser to secure your applications.
+
+
+The following vulnerabilities have been addressed:
+
+- [CVE-2025-13466 in body-parser middleware (Moderate)](#cve-2025-13466-in-body-parser-middleware-moderate)
+
+## CVE-2025-13466 in Body-parser middleware (Moderate)
+
+**[body-parser](https://www.npmjs.com/package/body-parser) version `2.2.0` is vulnerable to denial of service when url encoding is used**
+
+body-parser 2.2.0 is vulnerable to denial of service due to inefficient handling of URL-encoded bodies with very large numbers of parameters. An attacker can send payloads containing thousands of parameters within the default 100KB request size limit, causing elevated CPU and memory usage. This can lead to service slowdown or partial outages under sustained malicious traffic.
+
+**Affected versions**: `2.2.0`
+**Patched version**: `>= 2.2.1`
+
+For more details, see [GHSA-wqch-xfxh-vrr4](https://github.com/expressjs/body-parser/security/advisories/GHSA-wqch-xfxh-vrr4).
+
+---
+
+We recommend upgrading to the latest version of body-parser to secure your applications.
diff --git a/astro/src/content/blog/en/2026-02-27-security-releases.mdx b/astro/src/content/blog/en/2026-02-27-security-releases.mdx
new file mode 100644
index 0000000000..2f76d635e6
--- /dev/null
+++ b/astro/src/content/blog/en/2026-02-27-security-releases.mdx
@@ -0,0 +1,47 @@
+---
+title: February 2026 Security Releases
+description: Security release for multer has been published. We recommend that all users upgrade as soon as possible.
+tags: ['security']
+authors:
+ - name: Ulises Gascón
+ github: UlisesGascon
+---
+
+import Alert from '@components/primitives/Alert/Alert.astro';
+
+The Express team has released a new patch version of [multer](https://www.npmjs.com/package/multer) addressing two high-severity security vulnerabilities.
+
+
+ We recommend upgrading to the latest version of multer to secure your applications.
+
+
+The following vulnerabilities have been addressed:
+
+- [CVE-2026-3304 in multer middleware (High)](#cve-2026-3304-in-multer-middleware-high)
+- [CVE-2026-2359 in multer middleware (High)](#cve-2026-2359-in-multer-middleware-high)
+
+## CVE-2026-3304 in multer middleware (High)
+
+**[multer](https://www.npmjs.com/package/multer) versions `<2.1.0` are vulnerable to denial of service via incomplete cleanup**
+
+A vulnerability in Multer versions `<2.1.0` allows an attacker to trigger a Denial of Service (DoS) by sending malformed requests, potentially causing resource exhaustion.
+
+**Affected versions**: `< 2.1.0`
+**Patched version**: `>= 2.1.0`
+
+For more details, see [GHSA-xf7r-hgr6-v32p](https://github.com/expressjs/multer/security/advisories/GHSA-xf7r-hgr6-v32p).
+
+## CVE-2026-2359 in multer middleware (High)
+
+**[multer](https://www.npmjs.com/package/multer) versions `<2.1.0` are vulnerable to denial of service via resource exhaustion**
+
+A vulnerability in Multer versions `<2.1.0` allows an attacker to trigger a Denial of Service (DoS) by dropping connection during file upload, potentially causing resource exhaustion.
+
+**Affected versions**: `< 2.1.0`
+**Patched version**: `>= 2.1.0`
+
+For more details, see [GHSA-v52c-386h-88mc](https://github.com/expressjs/multer/security/advisories/GHSA-v52c-386h-88mc).
+
+---
+
+We recommend upgrading to the latest version of multer to secure your applications.
diff --git a/astro/src/content/blog/en/write-post.md b/astro/src/content/blog/en/write-post.md
new file mode 100644
index 0000000000..9678b64120
--- /dev/null
+++ b/astro/src/content/blog/en/write-post.md
@@ -0,0 +1,52 @@
+---
+layout: post
+title: How to write a blog post
+description: Learn how to propose and write a blog post for the Express.js blog, including submission guidelines and steps to contribute your content.
+---
+
+
+
+If you have an idea for a blog post, follow these steps to propose it and potentially get it published!
+
+1. ### Propose your post
+
+ Before taking the time to write a post, please confirm that we will be able to publish it. We're looking for topics specifically related to Express, and so we want to pre-approve all posts. For the moment, this means we aren't accepting any unsolicited posts. To propose a blog post, [open an issue](https://github.com/expressjs/expressjs.com/issues) entitled `Blog post proposal: `.
+
+1. ### Fork the repository
+
+ If the Express TC accepts your proposal, start to write your post by forking the [expressjs.com](https://github.com/expressjs/expressjs.com) repository and cloning it to your local machine. Once you open a pull request, you'll be able to preview your post on GitHub. See step six below.
+
+ Optional: To run the site locally and preview your post before opening a PR, see the [setup instructions in the README](https://github.com/expressjs/expressjs.com?tab=readme-ov-file#expressjscom).
+ {: .doc-box .doc-info}
+
+1. ### Create a new file
+
+ Create a new file in the `_posts` directory named using following the format: `YYYY-MM-DD-title.md`.
+
+1. ### Add the required front matter
+
+ Copy the following front matter, including the dotted lines, and paste it at the top of file you just created. Replace the placeholder values with as desired.
+
+ ```markdown
+ ---
+ title:
+ sub_title:
+ description:
+ tags:
+ authors:
+ - name:
+ github:
+ ---
+ ```
+
+ The `github` property of an author is optional. Including your username only (not your full profile URL) will ensure that your blog post links out to it.
+
+1. ### Add your content
+
+ Finally, start writing your content below the front matter. Use standard markdown formatting.
+
+1. ### Open a pull request (PR)
+
+ Once you open a PR, you will be able to preview your results: There will be a section on the page entitled `Deploy Preview for expressjscom-preview ready!` Click the link to see the site rendered from your fork/branch.
+
+ You can use this feature over multiple commits to refine your post by making a `draft` pull request. Once it's ready for review, switch it to a formal PR.
diff --git a/astro/src/content/docs/de/3x/api.md b/astro/src/content/docs/de/3x/api.md
new file mode 100644
index 0000000000..810fc3625b
--- /dev/null
+++ b/astro/src/content/docs/de/3x/api.md
@@ -0,0 +1,22 @@
+---
+title: Express 3.x - API-Referenz
+description: Access the API reference for Express.js version 3.x, noting that this version is end-of-life and no longer maintained - includes details on modules and methods.
+---
+
+
+
+
+ **Express 3.x WIRD NICHT MEHR GEWARTET**
+
+Bekannte und unbekannte Probleme bei Sicherheit und Leistung in 3.x wurden seit dem letzten Update (1. August 2015) noch nicht behoben. Es wird dringend empfohlen, die aktuelle Version von Express zu verwenden.
+
+If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/en/support#commercial-support-options).
+
+
+
+
3.x-API
+
+
+{% include api/en/3x/app.md %}
+
+
diff --git a/astro/src/content/docs/de/4x/advanced/best-practice-performance.md b/astro/src/content/docs/de/4x/advanced/best-practice-performance.md
new file mode 100644
index 0000000000..cf631586a0
--- /dev/null
+++ b/astro/src/content/docs/de/4x/advanced/best-practice-performance.md
@@ -0,0 +1,307 @@
+---
+title: Leistungsspezifische Best Practices für Express-Anwendungen in Produktionsumgebungen
+description: Discover performance and reliability best practices for Express apps in production, covering code optimizations and environment setups for optimal performance.
+---
+
+# Best Practices in Produktionsumgebungen: Leistung und Zuverlässigkeit
+
+In diesem Beitrag werden Best Practices in Bezug auf Leistung und Zuverlässigkeit für Express-Anwendungen behandelt, die in der Produktionsumgebung bereitgestellt werden.
+
+Dieses Thema gehört sicherlich zur "DevOps"-Welt und deckt traditionelle Entwicklungs- und Betriebsprozesse ab. Entsprechend sind die Informationen hier in zwei Teile unterteilt:
+
+- Things to do in your code (the dev part):
+ - Für statische Dateien Middleware verwenden
+ - Keine synchronen Funktionen verwenden
+ - [Do logging correctly](#do-logging-correctly)
+ - [Handle exceptions properly](#handle-exceptions-properly)
+- Things to do in your environment / setup (the ops part):
+ - NODE_ENV auf "production" festlegen
+ - Automatischen Neustart Ihrer Anwendung sicherstellen
+ - Anwendung in einem Cluster ausführen
+ - Anforderungsergebnisse im Cache speichern
+ - Load Balancer verwenden
+ - Reverse Proxy verwenden
+
+## Things to do in your code {#in-code}
+
+Dies sind einige Beispiele für Maßnahmen, die Sie an Ihrem Code vornehmen können, um die Anwendungsleistung zu verbessern:
+
+- Für statische Dateien Middleware verwenden
+- Keine synchronen Funktionen verwenden
+- [Do logging correctly](#do-logging-correctly)
+- [Handle exceptions properly](#handle-exceptions-properly)
+
+### GZIP-Komprimierung verwenden
+
+Mit der GZIP-Komprimierung lässt sich die Größe des Antworthauptteils deutlich verringern und somit die Geschwindigkeit der Webanwendung erhöhen. Verwenden Sie die Middleware [compression](https://www.npmjs.com/package/compression) für die GZIP-Komprimierung in Ihrer Express-Anwendung. Beispiel:
+
+```js
+const compression = require('compression');
+const express = require('express');
+const app = express();
+
+app.use(compression());
+```
+
+Bei Websites mit hohem Datenverkehr in Produktionsumgebungen lässt sich die Komprimierung am besten installieren, indem sie auf Reverse Proxy-Ebene implementiert wird (siehe [Reverse Proxy verwenden](#proxy)). In diesem Fall wird die Middleware "compression" nicht benötigt. Details zur Aktivierung der GZIP-Komprimierung in Nginx siehe [Modul ngx_http_gzip_module](http://nginx.org/en/docs/http/ngx_http_gzip_module) in der Nginx-Dokumentation.
+
+### Keine synchronen Funktionen verwenden
+
+Synchrone Funktionen und Methoden belasten den Ausführungsprozess, bis sie zurückgegeben werden. Ein einzelner Aufruf für eine synchrone Funktion kann in wenigen Mikrosekunden oder Millisekunden zurückgegeben werden. Bei Websites mit hohem Datenverkehr hingegen summieren sich diese Aufrufe und verringern die Leistung der Anwendung. Sie sollten also deren Verwendung in Produktionsumgebungen vermeiden.
+
+Auch wenn Node und viele andere Module synchrone und asynchrone Versionen ihrer Funktionen bieten, sollten Sie in Produktionsumgebungen immer die asynchrone Version verwenden. Nur beim ersten Systemstart ist die Verwendung einer synchronen Funktion begründet.
+
+You can use the `--trace-sync-io` command-line flag to print a warning and a stack trace whenever your application uses a synchronous API. Auch wenn Sie diese natürlich nicht in der Produktionsumgebung verwenden werden, soll dadurch trotzdem sichergestellt werden, dass Ihr Code in der Produktionsumgebung eingesetzt werden kann. Weitere Informationen hierzu siehe [Wöchentliches Update für io.js 2.1.0](https://nodejs.org/en/blog/weekly-updates/weekly-update.2015-05-22/#2-1-0).
+
+### Do logging correctly
+
+Im Allgemeinen gibt es für die Protokollierung Ihrer Anwendung zwei Gründe: 1) Debugging und 2) Protokollierung von Anwendungsaktivitäten (im Wesentlichen alles andere, außer Debugging). Die Verwendung von`console.log()` oder `console.err()` zur Ausgabe von Protokollnachrichten an das Terminal ist in der Entwicklung gängige Praxis. But [these functions are synchronous](https://nodejs.org/api/console#console) when the destination is a terminal or a file, so they are not suitable for production, unless you pipe the output to another program.
+
+#### Für Debuggingzwecke
+
+Wenn Sie die Protokollierung für Debuggingzwecke nutzen, sollten Sie statt `console.log()` besser ein spezielles Debuggingmodul wie [debug](https://www.npmjs.com/package/debug) verwenden. Mit einem solchen Modul können Sie über die Umgebungsvariable DEBUG steuern, welche Debugnachrichten an `console.err()` gesendet werden (falls vorhanden). Um Ihre Anwendung rein asynchron zu halten, können Sie trotzdem `console.err()` per Pipe zu einem anderen Programm umleiten. Sie nehmen dann aber kein Debugging in der Produktionsumgebung vor, richtig?
+
+#### Für Anwendungsaktivitäten
+
+If you're logging app activity (for example, tracking traffic or API calls), instead of using `console.log()`, use a logging library like [Pino](https://www.npmjs.com/package/pino), which is the fastest and most efficient option available.
+
+### Ausnahmebedingungen ordnungsgemäß handhaben
+
+Node-Anwendungen stürzen ab, wenn eine nicht abgefangene Ausnahmebedingung vorkommt. Wenn diese Ausnahmebedingungen nicht behandelt und entsprechende Maßnahmen eingeleitet werden, stürzt Ihre Express-Anwendung ab und geht offline. Wenn Sie dem nachfolgenden Rat in [Sicherstellen, dass Ihre Anwendung automatisch neu gestartet wird](#restart) folgen, wird Ihre Anwendung nach einem Absturz wiederhergestellt. Glücklicherweise haben Express-Anwendungen nur eine kurze Initialisierungszeit. Nevertheless, you want to avoid crashing in the first place, and to do that, you need to handle exceptions properly.
+
+Mit folgenden Verfahren stellen Sie sicher, dass alle Ausnahmebedingungen gehandhabt werden:
+
+- ["try-catch" verwenden](#try-catch)
+- ["Promises" verwenden](#promises)
+
+Um näher auf diese Themen eingehen zu können, müssen Sie sich ein grundlegendes Verständnis der Fehlerbehandlung in Node und Express aneignen: Verwendung von Error-first-Callbacks und Propagieren von Fehlern in Middleware. Node verwendet die Konvention "Error-first-Callback" für die Rückgabe von Fehlern von asynchronen Funktionen, bei denen der erste Parameter zur Callback-Funktion das Fehlerobjekt ist, gefolgt von Ergebnisdaten in den nachfolgenden Parametern. Um anzugeben, dass kein Fehler vorliegt, müssen Sie "null" als ersten Parameter übergeben. Die Callback-Funktion muss der Konvention "Error-first-Callback" folgen, um den Fehler sinnvoll bearbeiten zu können. In Express hat sich bewährt, die Funktion "next()" zu verwenden, um Fehler über die Middleware-Chain zu propagieren.
+
+Weitere Informationen zu den Grundlagen der Fehlerbehandlung siehe:
+
+- [Fehlerbehandlung in Node.js](https://www.tritondatacenter.com/node-js/production/design/errors)
+
+#### "try-catch" verwenden
+
+"try-catch" ist ein JavaScript-Sprachkonstrukt, mit dem Sie Ausnahmebedingungen in synchronem Code abfangen können. Verwenden Sie "try-catch" beispielsweise, um JSON-Parsing-Fehler wie unten gezeigt zu bearbeiten.
+
+Dies ist ein Beispiel zur Verwendung von "try-catch", um eine potenzielle "process-crashing"-Ausnahmebedingung zu handhaben.
+Diese Middlewarefunktion akzeptiert einen Abfragefeldparameter mit dem Namen "params", der ein JSON-Objekt ist.
+
+```js
+app.get('/search', (req, res) => {
+ // Simulating async operation
+ setImmediate(() => {
+ const jsonStr = req.query.params;
+ try {
+ const jsonObj = JSON.parse(jsonStr);
+ res.send('Success');
+ } catch (e) {
+ res.status(400).send('Invalid JSON string');
+ }
+ });
+});
+```
+
+"try-catch" funktioniert jedoch nur in synchronem Code. Da die Node-Plattform primär asynchron ist (insbesondere in einer Produktionsumgebung), lassen sich mit "try-catch" nicht besonders viele Ausnahmebedingungen abfangen.
+
+#### "Promises" verwenden
+
+When an error is thrown in an `async` function or a rejected promise is awaited inside an `async` function, those errors will be passed to the error handler as if calling `next(err)`
+
+```js
+app.get('/', async (req, res, next) => {
+ const data = await userData(); // If this promise fails, it will automatically call `next(err)` to handle the error.
+
+ res.send(data);
+});
+
+app.use((err, req, res, next) => {
+ res.status(err.status ?? 500).send({ error: err.message });
+});
+```
+
+Also, you can use asynchronous functions for your middleware, and the router will handle errors if the promise fails, for example:
+
+```js
+app.use(async (req, res, next) => {
+ req.locals.user = await getUser(req);
+
+ next(); // This will be called if the promise does not throw an error.
+});
+```
+
+Best practice is to handle errors as close to the site as possible. So while this is now handled in the router, it’s best to catch the error in the middleware and handle it without relying on separate error-handling middleware.
+
+#### What not to do
+
+Sie sollten _auf keinen_ Fall per Listener das Ereignis `uncaughtException` überwachen, das ausgegeben wird, wenn eine Ausnahmebedingung bis zurück zur Ereignisschleife bestehen bleibt. Durch das Hinzufügen eines Ereignislisteners für `uncaughtException` verändert sich das Standardverhalten des Prozesses, über das eine Ausnahmebedingung festgestellt wird. Das Ausführen einer Anwendung nach einer nicht abgefangenen Ausnahmebedingung ist aber eine durchaus riskante Vorgehensweise und wird nicht empfohlen, da der Prozessstatus störanfällig und unvorhersehbar wird.
+
+Außerdem wird die Verwendung von `uncaughtException` offiziell als [grobes Vorgehen](https://nodejs.org/api/process#process_event_uncaughtexception) angesehen, sodass es den [Vorschlag](https://github.com/nodejs/node-v0.x-archive/issues/2582) gibt, die Funktion aus dem Kern zu entfernen. Das Überwachen von `uncaughtException` per Listener ist also keine gute Idee. Daher empfehlen wir Dinge wie Mehrfachprozesse und Supervisoren: Ein Absturz und anschließender Neustart ist häufig die zuverlässigste Art der Fehlerbehebung.
+
+Zudem empfehlen wir, [domains](https://nodejs.org/api/domain) nicht zu verwenden. Mit diesem Modul, das zudem veraltet ist, lässt sich das Problem in der Regel nicht lösen.
+
+## Things to do in your environment / setup {#in-environment}
+
+Dies sind einige Beispiele für Maßnahmen, die Sie an Ihrer Systemumgebung vornehmen können, um die Anwendungsleistung zu verbessern:
+
+- NODE_ENV auf "production" festlegen
+- Automatischen Neustart Ihrer Anwendung sicherstellen
+- Anwendung in einem Cluster ausführen
+- Anforderungsergebnisse im Cache speichern
+- Load Balancer verwenden
+- Reverse Proxy verwenden
+
+### NODE_ENV auf "production" festlegen
+
+In der Umgebungsvariablen NODE_ENV wird die Umgebung angegeben, in der eine Anwendung ausgeführt wird (in der Regel ist dies die Entwicklungs- oder Produktionsumgebung). One of the simplest things you can do to improve performance is to set NODE_ENV to `production`.
+
+Durch das Festlegen von NODE_ENV auf "production" führt Express Folgendes aus:
+
+- Speichern von Anzeigevorlagen im Cache.
+- Speichern von CSS-Dateien, die aus CSS-Erweiterungen generiert wurden, im Cache.
+- Generieren von weniger ausführlichen Fehlernachrichten.
+
+[Tests indicate](https://www.dynatrace.com/news/blog/the-drastic-effects-of-omitting-node-env-in-your-express-js-applications/) that just doing this can improve app performance by a factor of three!
+
+Wenn Sie umgebungsspezifischen Code schreiben müssen, können Sie den Wert von NODE_ENV mit `process.env.NODE_ENV` überprüfen. Beachten Sie, dass die Überprüfung des Werts seiner Umgebungsvariablen eine leistungsbezogene Penalisierung nach sich zieht.
+
+In einer Entwicklungsumgebung wird die Umgebungsvariable in der Regel in Ihrer interaktiven Shell festgelegt, indem Sie beispielsweise `export` oder Ihre Datei `.bash_profile` verwenden. But in general, you shouldn't do that on a production server; instead, use your OS's init system (systemd). Der nächste Abschnitt enthält weitere Details zur Verwendung des Init-Systems im Allgemeinen. Die Festlegung von NODE_ENV ist jedoch für das Leistungsverhalten so wichtig (und so einfach durchzuführen), dass hier besonders darauf eingegangen wird.
+
+Verwenden Sie bei systemd die Anweisung `Environment` in Ihrer Einheitendatei. Beispiel:
+
+```sh
+# /etc/systemd/system/myservice.service
+Environment=NODE_ENV=production
+```
+
+For more information, see [Using Environment Variables In systemd Units](https://www.flatcar.org/docs/latest/setup/systemd/environment-variables/).
+
+### Automatischen Neustart Ihrer Anwendung sicherstellen
+
+In der Produktionsumgebung sollte die Anwendung nie offline sein. Das bedeutet, dass Sie sicherstellen müssen, dass die Anwendung bei einem Absturz der Anwendung oder des Servers immer wieder neu gestartet wird. Auch wenn man hofft, das keines dieser Ereignisse jemals eintritt, muss man doch mit beiden Möglichkeiten rechnen und:
+
+- einen Prozessmanager verwenden, um die Anwendung (und Node) bei einem Absturz neu zu starten.
+- das Init-System Ihres Betriebssystems verwenden, um den Prozessmanager bei einem Absturz des Betriebssystems neu zu starten. Außerdem kann das Init-System auch ohne einen Prozessmanager verwendet werden.
+
+Node-Anwendungen stürzen ab, wenn eine nicht abgefangene Ausnahmebedingung auftritt. Als Erstes müssen Sie in einem solchen Fall sicherstellen, dass Ihre Anwendung ausreichend getestet wurde und in der Lage ist, alle Ausnahmebedingungen zu handhaben (weitere Informationen siehe [Ausnahmebedingungen ordnungsgemäß handhaben](#exceptions)). Die sicherste Maßnahme ist jedoch, einen Mechanismus zu implementieren, über den bei einem Absturz der Anwendung ein automatischer Neustart der Anwendung ausgeführt wird.
+
+#### Prozessmanager verwenden
+
+In Entwicklungumgebungen wird die Anwendung einfach über die Befehlszeile mit `node server.js` oder einer vergleichbaren Datei gestartet. In der Produktionsumgebung hingegen ist durch diese Vorgehensweise die Katastrophe bereits vorprogrammiert. Wenn die Anwendung abstürzt, ist sie solange offline, bis Sie sie erneut starten. Um sicherzustellen, dass Ihre Anwendung nach einem Absturz neu gestartet wird, sollten Sie einen Prozessmanager verwenden. Ein Prozessmanager ist ein "Container" für Anwendungen, der die Bereitstellung erleichtert, eine hohe Verfügbarkeit sicherstellt und die Verwaltung der Anwendung zur Laufzeit ermöglicht.
+
+Neben einem Neustart der Anwendung nach einem Absturz bietet ein Prozessmanager noch weitere Möglichkeiten:
+
+- Einblicke in die Laufzeitleistung und die Ressourcennutzung
+- Dynamische Änderung der Einstellungen zur Verbesserung des Leistungsverhaltens
+- Control clustering (pm2).
+
+Historically, it was popular to use a Node.js process manager like [PM2](https://github.com/Unitech/pm2). See their documentation if you wish to do this. However, we recommend using your init system for process management.
+
+#### Init-System verwenden
+
+Als nächste Ebene der Zuverlässigkeit müssen Sie sicherstellen, dass Ihre Anwendung bei einem Serverneustart neu gestartet wird. Systeme können immer wieder aus verschiedenen Gründen abstürzen. Um sicherzustellen, dass Ihre Anwendung bei einem Serverabsturz neu gestartet wird, können Sie das in Ihr Betriebssystem integrierte Init-System verwenden. The main init system in use today is [systemd](https://wiki.debian.org/systemd).
+
+Es gibt zwei Möglichkeiten, Init-Systeme mit Ihrer Express-Anwendung zu verwenden:
+
+- Ausführung Ihrer Anwendung in einem Prozessmanager und Installation des Prozessmanagers als Service mit dem Init-System. Der Prozessmanager wird neu gestartet, wenn Ihre Anwendung abstürzt. Dies ist die empfohlene Vorgehensweise.
+- Ausführung Ihrer Anwendung (und von Node) direkt mit dem Init-System. Diese Vorgehensweise ist zwar etwas einfacher, Sie profitieren jedoch nicht von den zusätzlichen Vorteilen des Einsatzes eines Prozessmanagers.
+
+##### systemd
+
+"systemd" ist ein Linux-System und Service-Manager. Die meisten wichtigen Linux-Distributionen haben "systemd" als Init-Standardsystem übernommen.
+
+Eine "systemd"-Servicekonfigurationsdatei wird als _Einheitendatei_ bezeichnet, die die Endung ".service" hat. Dies ist ein Beispiel für eine Einheitendatei zur direkten Verwaltung einer Node-Anwendung (ersetzen Sie den Text in Fettdruck durch Werte für Ihr System und Ihre Anwendung): Replace the values enclosed in `` for your system and app:
+
+```sh
+[Unit]
+Description=
+
+[Service]
+Type=simple
+ExecStart=/usr/local/bin/node
+WorkingDirectory=
+
+User=nobody
+Group=nogroup
+
+# Environment variables:
+Environment=NODE_ENV=production
+
+# Allow many incoming connections
+LimitNOFILE=infinity
+
+# Allow core dumps for debugging
+LimitCORE=infinity
+
+StandardInput=null
+StandardOutput=syslog
+StandardError=syslog
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
+```
+
+Weitere Informationen zu "systemd" siehe [systemd-Referenz (Man-Page)](http://www.freedesktop.org/software/systemd/man/systemd.unit).
+
+### Anwendung in einem Cluster ausführen
+
+In einem Multi-Core-System können Sie die Leistung einer Node-Anwendung mehrmals erhöhen, indem Sie einen Cluster von Prozessen starten. Ein Cluster führt mehrere Instanzen der Anwendung aus, idealerweise eine Instanz auf jedem CPU-Core.
+
+
+
+Wichtig. Da die Anwendungsinstanzen als separate Prozesse ausgeführt werden, nutzen sie nicht dieselbe Hauptspeicherkapazität gemeinsam. Das heißt, Objekte befinden sich für jede Instanz der Anwendung auf lokaler Ebene. Daher kann der Status im Anwendungscode nicht beibehalten werden. Sie können jedoch einen speicherinternen Datenspeicher wie [Redis](http://redis.io/) verwenden, um sitzungsrelevante Daten und Statusinformationen zu speichern. Diese Einschränkung trifft im Wesentlichen auf alle Formen der horizontalen Skalierung zu, unabhängig davon, ob es sich um Clustering mit mehreren Prozessen oder mehreren physischen Servern handelt.
+
+Bei in Gruppen zusammengefassten Anwendungen (geclusterte Anwendungen) können Verarbeitungsprozesse einzeln ausfallen, ohne dass sich dies auf die restlichen Prozesse auswirkt. Neben den Leistungsvorteilen ist die Fehlerisolierung ein weiterer Grund, einen Cluster von Anwendungsprozessen auszuführen. Wenn ein Verarbeitungsprozess abstürzt, müssen Sie sicherstellen, dass das Ereignis protokolliert und ein neuer Prozess mithilfe von "cluster.fork()" gestartet wird.
+
+#### Clustermodule von Node verwenden
+
+Clustering is made possible with Node's [cluster module](https://nodejs.org/api/cluster). Dadurch wird ein Masterprozess eingeleitet, um Verarbeitungsprozesse zu starten und eingehende Verbindungen auf die Verarbeitungsprozesse zu verteilen.
+
+#### Using PM2
+
+If you deploy your application with PM2, then you can take advantage of clustering _without_ modifying your application code. You should ensure your [application is stateless](https://pm2.keymetrics.io/docs/usage/specifics/#stateless-apps) first, meaning no local data is stored in the process (such as sessions, websocket connections and the like).
+
+When running an application with PM2, you can enable **cluster mode** to run it in a cluster with a number of instances of your choosing, such as the matching the number of available CPUs on the machine. You can manually change the number of processes in the cluster using the `pm2` command line tool without stopping the app.
+
+To enable cluster mode, start your application like so:
+
+```bash
+# Start 4 worker processes
+$ pm2 start npm --name my-app -i 4 -- start
+# Auto-detect number of available CPUs and start that many worker processes
+$ pm2 start npm --name my-app -i max -- start
+```
+
+This can also be configured within a PM2 process file (`ecosystem.config.js` or similar) by setting `exec_mode` to `cluster` and `instances` to the number of workers to start.
+
+Once running, the application can be scaled like so:
+
+```bash
+# Add 3 more workers
+$ pm2 scale my-app +3
+# Scale to a specific number of workers
+$ pm2 scale my-app 2
+```
+
+For more information on clustering with PM2, see [Cluster Mode](https://pm2.keymetrics.io/docs/usage/cluster-mode/) in the PM2 documentation.
+
+### Anforderungsergebnisse im Cache speichern
+
+Eine weitere Strategie zur Verbesserung des Leistungsverhaltens in Produktionsumgebungen ist das Speichern von Anforderungergebnissen im Cache. Ihre Anwendung muss also diese Operation nicht wiederholt ausführen, um dieselbe Anforderung wiederholt zu bedienen.
+
+Use a caching server like [Varnish](https://www.varnish-cache.org/) or [Nginx](https://blog.nginx.org/blog/nginx-caching-guide) (see also [Nginx Caching](https://serversforhackers.com/nginx-caching/)) to greatly improve the speed and performance of your app.
+
+### Load Balancer verwenden
+
+Unabhängig davon, wie gut eine Anwendung optimiert wurde, kann eine Einzelinstanz nur eine begrenzte Arbeitslast oder einen begrenzten Datenverkehr handhaben. Eine Möglichkeit, eine Anwendung zu skalieren, ist die Ausführung mehrerer Instanzen dieser Anwendung und die Verteilung des Datenverkehrs über eine Lastausgleichsfunktion (Load Balancer) vorzunehmen. Die Einrichtung eines solchen Load Balancer kann helfen, Leistung und Geschwindigkeit Ihrer Anwendung zu verbessern.
+
+Ein Load Balancer ist in der Regel ein Reverse Proxy, der den Datenverkehr zu und von mehreren Anwendungsinstanzen und Servern koordiniert. You can easily set up a load balancer for your app by using [Nginx](https://nginx.org/en/docs/http/load_balancing) or [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts).
+
+Bei einer solchen Lastverteilung müssen Sie sicherstellen, dass Anforderungen, die einer bestimmten Sitzungs-ID zugeordnet sind, mit dem Prozess verbunden sind, von dem sie ursprünglich stammen. Dies wird auch als _Sitzungsaffinität_ oder _Affine Sitzungen_ bezeichnet und kann durch den obigen Vorschlag, einen Datenspeicher wie Redis für Sitzungsdaten zu verwenden (je nach Anwendung), umgesetzt werden. Eine Beschreibung hierzu siehe [Mehrere Knoten verwenden](https://socket.io/docs/v4/using-multiple-nodes/).
+
+### Reverse Proxy verwenden
+
+Ein Reverse Proxy befindet sich vor einer Webanwendung und führt Unterstützungsoperationen für die Anforderungen aus (außer das Weiterleiten von Anforderungen an die Anwendung). Fehlerseiten, Komprimierungen und Caching bearbeiten, Dateien bereitstellen und Lastverteilungen vornehmen.
+
+Durch die Übergabe von Tasks, die keine Kenntnis des Anwendungsstatus erfordern, an einen Reverse Proxy muss Express keine speziellen Anwendungstasks mehr ausführen. For this reason, it is recommended to run Express behind a reverse proxy like [Nginx](https://www.nginx.org/) or [HAProxy](https://www.haproxy.org/) in production.
diff --git a/astro/src/content/docs/de/4x/advanced/best-practice-security.md b/astro/src/content/docs/de/4x/advanced/best-practice-security.md
new file mode 100644
index 0000000000..32fdb44395
--- /dev/null
+++ b/astro/src/content/docs/de/4x/advanced/best-practice-security.md
@@ -0,0 +1,282 @@
+---
+title: Sicherheitsspezifische Best Practices für Express-Anwendungen in Produktionsumgebungen
+description: Discover crucial security best practices for Express apps in production, including using TLS, input validation, secure cookies, and preventing vulnerabilities.
+---
+
+# Best Practices in Produktionsumgebungen: Sicherheit
+
+## Überblick
+
+Der Begriff _"Produktion"_ bezieht sich auf die Phase im Softwarelebenszyklus, in der eine Anwendung oder API für Endbenutzer oder Verbraucher allgemein verfügbar ist. Im Gegensatz dazu wird in der Phase _"Entwicklung"_ noch aktiv Code geschrieben und getestet. Die Anwendung ist in dieser Phase noch nicht für externen Zugriff verfügbar. Die entsprechenden Systemumgebungen werden als _Produktionsumgebungen_ und _Entwicklungsumgebungen_ bezeichnet.
+
+Entwicklungs- und Produktionsumgebungen werden in der Regel unterschiedlich konfiguriert und weisen deutliche Unterschiede bei den Anforderungen auf. Was in der Entwicklung funktioniert, muss in der Produktion nicht unbedingt akzeptabel sein. Beispiel: In einer Entwicklungsumgebung ist eine ausführliche Protokollierung von Fehlern für Debuggingzwecke sinnvoll. Dieselbe Vorgehensweise kann in einer Produktionsumgebung jedoch zu einem Sicherheitsproblem führen. In einer Entwicklungsumgebung müssen Sie sich keine Gedanken zu Themen wie Skalierbarkeit, Zuverlässigkeit und Leistung machen, während dies in einer Produktionsumgebung kritische Faktoren sind.
+
+{% capture security-note %}
+
+If you believe you have discovered a security vulnerability in Express, please see
+[Security Policies and Procedures](/en/resources/contributing#security-policies-and-procedures).
+
+{% endcapture %}
+
+{% include admonitions/note.html content=security-note %}
+
+In diesem Beitrag werden einige der Best Practices in Bezug auf das Thema Sicherheit für Express-Anwendungen behandelt, die in der Produktionsumgebung bereitgestellt werden.
+
+- [Best Practices in Produktionsumgebungen: Sicherheit](#best-practices-in-produktionsumgebungen-sicherheit)
+ - [Überblick](#überblick)
+ - [Verwenden Sie keine veralteten oder anfälligen Versionen von Express](#verwenden-sie-keine-veralteten-oder-anfälligen-versionen-von-express)
+ - [TLS verwenden](#tls-verwenden)
+ - [Do not trust user input](#do-not-trust-user-input)
+ - [Prevent open redirects](#prevent-open-redirects)
+ - ["Helmet" verwenden](#helmet-verwenden)
+ - [Reduce fingerprinting](#reduce-fingerprinting)
+ - [Cookies sicher verwenden](#cookies-sicher-verwenden)
+ - [Verwenden Sie nicht den standardmäßigen Namen des Sitzungscookies](#verwenden-sie-nicht-den-standardmäßigen-namen-des-sitzungscookies)
+ - [Cookie-Sicherheitsoptionen festlegen](#cookie-sicherheitsoptionen-festlegen)
+ - [Prevent brute-force attacks against authorization](#prevent-brute-force-attacks-against-authorization)
+ - [Ensure your dependencies are secure](#ensure-your-dependencies-are-secure)
+ - [Vermeiden Sie andere Schwachstellen](#vermeiden-sie-andere-schwachstellen)
+ - [Weitere Überlegungen](#weitere-überlegungen)
+
+## Verwenden Sie keine veralteten oder anfälligen Versionen von Express
+
+Express 2.x und 3.x werden nicht mehr gepflegt. Sicherheits- und Leistungsprobleme in diesen Versionen werden nicht mehr behoben. Verwenden Sie diese Versionen nicht! Wenn Sie noch nicht auf Version 4 umgestellt haben, befolgen Sie die Anweisungen im [Migrationshandbuch](/en/guide/migrating-4).
+
+Stellen Sie außerdem sicher, dass Sie keine anfälligen Express-Versionen verwenden, die auf der [Seite mit den Sicherheitsupdates](/en/advanced/security-updates) aufgelistet sind. Falls doch, führen Sie ein Update auf eines der stabileren Releases durch, bevorzugt das aktuelle Release.
+
+## TLS verwenden
+
+Wenn über Ihre Anwendung vertrauliche Daten bearbeitet oder übertragen werden, sollten Sie [Transport Layer Security](https://en.wikipedia.org/wiki/Transport_Layer_Security) (TLS) verwenden, um die Verbindung und die Daten zu schützen. Diese Technologie verschlüsselt Daten, bevor sie vom Client zum Server gesendet werden. Dadurch lassen sich einige gängige (und einfache) Hackerattacken vermeiden. Auch wenn Ajax- und POST-Anforderungen nicht sofort offensichtlich und in Browsern "versteckt" zu sein scheinen, ist deren Netzverkehr anfällig für das [Ausspionieren von Paketen](https://en.wikipedia.org/wiki/Packet_analyzer) und [Man-in-the-Middle-Attacken](https://en.wikipedia.org/wiki/Man-in-the-middle_attack).
+
+Möglicherweise sind Sie mit SSL-Verschlüsselung (Secure Socket Layer) bereits vertraut. [TLS ist einfach der nächste Entwicklungsschritt bei SSL](). In anderen Worten: Wenn Sie bisher SSL verwendet haben, sollten Sie ein Upgrade auf TLS in Erwägung ziehen. Generell empfehlen wir für TLS den Nginx-Server. Eine gute Referenz zum Konfigurieren von TLS auf Nginx (und anderen Servern) ist [Empfohlene Serverkonfigurationen (Mozilla Wiki)](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations).
+
+Ein handliches Tool zum Abrufen eines kostenloses TLS-Zertifikats ist außerdem [Let's Encrypt](https://letsencrypt.org/about/), eine kostenlose, automatisierte und offene Zertifizierungsstelle der [Internet Security Research Group (ISRG)](https://www.abetterinternet.org/).
+
+## Do not trust user input
+
+For web applications, one of the most critical security requirements is proper user input validation and handling. This comes in many forms and we will not cover all of them here.
+Ultimately, the responsibility for validating and correctly handling the types of user input your application accepts is yours.
+
+### Prevent open redirects
+
+An example of potentially dangerous user input is an _open redirect_, where an application accepts a URL as user input (often in the URL query, for example `?url=https://example.com`) and uses `res.redirect` to set the `location` header and
+return a 3xx status.
+
+An application must validate that it supports redirecting to the incoming URL to avoid sending users to malicious links such as phishing websites, among other risks.
+
+Here is an example of checking URLs before using `res.redirect` or `res.location`:
+
+```js
+app.use((req, res) => {
+ try {
+ if (new Url(req.query.url).host !== 'example.com') {
+ return res.status(400).end(`Unsupported redirect to host: ${req.query.url}`);
+ }
+ } catch (e) {
+ return res.status(400).end(`Invalid url: ${req.query.url}`);
+ }
+ res.redirect(req.query.url);
+});
+```
+
+## "Helmet" verwenden
+
+[Helmet](https://www.npmjs.com/package/helmet) kann beim Schutz Ihrer Anwendung gegen einige gängige Schwachstellen hilfreiche Dienste leisten, indem die HTTP-Header entsprechend konfiguriert werden.
+
+Helmet is a middleware function that sets security-related HTTP response headers. Helmet sets the following headers by default:
+
+- `Content-Security-Policy`: A powerful allow-list of what can happen on your page which mitigates many attacks
+- `Cross-Origin-Opener-Policy`: Helps process-isolate your page
+- `Cross-Origin-Resource-Policy`: Blocks others from loading your resources cross-origin
+- `Origin-Agent-Cluster`: Changes process isolation to be origin-based
+- `Referrer-Policy`: Controls the [`Referer`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) header
+- `Strict-Transport-Security`: Tells browsers to prefer HTTPS
+- `X-Content-Type-Options`: Avoids [MIME sniffing](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing)
+- `X-DNS-Prefetch-Control`: Controls DNS prefetching
+- `X-Download-Options`: Forces downloads to be saved (Internet Explorer only)
+- `X-Frame-Options`: Legacy header that mitigates [Clickjacking](https://en.wikipedia.org/wiki/Clickjacking) attacks
+- `X-Permitted-Cross-Domain-Policies`: Controls cross-domain behavior for Adobe products, like Acrobat
+- `X-Powered-By`: Info about the web server. Removed because it could be used in simple attacks
+- `X-XSS-Protection`: Legacy header that tries to mitigate [XSS attacks](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting), but makes things worse, so Helmet disables it
+
+Each header can be configured or disabled. To read more about it please go to [its documentation website][helmet].
+
+Installieren Sie "Helmet" wie alle anderen Module:
+
+```bash
+$ npm install helmet
+```
+
+So verwenden Sie "Helmet" in Ihrem Code:
+
+```js
+// ...
+
+const helmet = require('helmet');
+app.use(helmet());
+
+// ...
+```
+
+## Reduce fingerprinting
+
+It can help to provide an extra layer of security to reduce the ability of attackers to determine
+the software that a server uses, known as "fingerprinting." Though not a security issue itself,
+reducing the ability to fingerprint an application improves its overall security posture.
+Server software can be fingerprinted by quirks in how it responds to specific requests, for example in
+the HTTP response headers.
+
+Ein bewährtes Verfahren ist also, diesen Header mit der Methode `app.disable()` zu deaktivieren:
+
+```js
+app.disable('x-powered-by');
+```
+
+{% capture powered-advisory %}
+
+Disabling the `X-Powered-By header` does not prevent
+a sophisticated attacker from determining that an app is running Express. It may
+discourage a casual exploit, but there are other ways to determine an app is running
+Express.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=powered-advisory %}
+
+Express also sends its own formatted "404 Not Found" messages and formatter error
+response messages. These can be changed by
+[adding your own not found handler](/en/starter/faq#how-do-i-handle-404-responses)
+and
+[writing your own error handler](/en/guide/error-handling#writing-error-handlers):
+
+```js
+// last app.use calls right before app.listen():
+
+// custom 404
+app.use((req, res, next) => {
+ res.status(404).send("Sorry can't find that!");
+});
+
+// custom error handler
+app.use((err, req, res, next) => {
+ console.error(err.stack);
+ res.status(500).send('Something broke!');
+});
+```
+
+## Cookies sicher verwenden
+
+Um sicherzustellen, dass Cookies Ihre Anwendung nicht für Angriffsmöglichkeiten öffnen, sollten Sie den standardmäßigen Namen des Sitzungscookies nicht verwenden und die Cookie-Sicherheitsoptionen entsprechend festlegen.
+
+Es gibt zwei wesentliche Middleware-Cookie-Sitzungsmodule:
+
+- [express-session](https://www.npmjs.com/package/express-session), das in Express 3.x integrierte `express.session`-Middleware ersetzt.
+- [cookie-session](https://www.npmjs.com/package/cookie-session), das in Express 3.x integrierte `express.cookieSession`-Middleware ersetzt.
+
+Der Hauptunterschied zwischen diesen beiden Modulen liegt darin, wie die Cookie-Sitzungsdaten gespeichert werden. Die [express-session](https://www.npmjs.com/package/express-session)-Middleware speichert Sitzungsdaten auf dem Server. Sie speichert nur die Sitzungs-ID im Cookie und nicht die Sitzungsdaten. Standardmäßig wird dabei der speicherinterne Speicher verwendet. Eine Verwendung der Middleware in der Produktionsumgebung ist nicht vorgesehen. In der Produktionsumgebung müssen Sie einen skalierbaren "Session-Store" einrichten. Siehe hierzu die Liste der [kompatiblen Session-Stores](https://github.com/expressjs/session#compatible-session-stores).
+
+Im Gegensatz dazu implementiert die [cookie-session](https://www.npmjs.com/package/cookie-session)-Middleware cookiegestützten Speicher: Sie serialisiert die gesamte Sitzung zum Cookie und nicht nur einen Sitzungsschlüssel. Diese Middleware sollten Sie nur verwenden, wenn Sitzungsdaten relativ klein sind und einfach als primitive Werte (und nicht als Objekte) codiert sind. Auch wenn Browser mindestens 4096 Byte pro Cookie unterstützen sollten, müssen Sie sicherstellen, dass dieses Limit nicht überschritten wird. Überschreiten Sie auf keinen Fall die Größe von 4093 Byte pro Domäne. Achten Sie zudem darauf, dass die Cookiedaten für den Client sichtbar sind. Wenn also ein Grund vorliegt, die Daten sicher oder unkenntlich zu machen, ist "express-session" möglicherweise die bessere Wahl.
+
+### Verwenden Sie nicht den standardmäßigen Namen des Sitzungscookies
+
+Die Verwendung des standardmäßigen Namens des Sitzungscookies kann Ihre Anwendung anfällig für Attacken machen. Das mögliche Sicherheitsproblem ist vergleichbar mit `X-Powered-By`: ein potenzieller Angreifer kann diesen Header verwenden, um einen elektronischen Fingerabdruck des Servers zu erstellen und Attacken entsprechend zu platzieren.
+
+Über [noSniff](https://github.com/helmetjs/dont-sniff-mimetype) werden `X-Content-Type-Options`-Header festgelegt, um bei Browsern MIME-Sniffing von Antworten weg vom deklarierten Inhaltstyp (declared content-type) vorzubeugen.
+
+```js
+const session = require('express-session');
+app.set('trust proxy', 1); // trust first proxy
+app.use(
+ session({
+ secret: 's3Cur3',
+ name: 'sessionId',
+ })
+);
+```
+
+### Cookie-Sicherheitsoptionen festlegen
+
+Legen Sie die folgenden Cookieoptionen fest, um die Sicherheit zu erhöhen:
+
+- `secure` - Stellt sicher, dass der Browser das Cookie nur über HTTPS sendet.
+- `httpOnly` - Stellt sicher, dass das Cookie nur über HTTP(S) und nicht über das Client-JavaScript gesendet wird und dadurch Schutz gegen Cross-Site Scripting-Attacken besteht.
+- `domain` - Gibt die Domäne des Cookies an, die für den Vergleich mit der Domäne des Servers verwendet wird, in der die URL angefordert wird. Stimmen diese beiden überein, müssen Sie das Pfadattribut überprüfen.
+- `path` - Gibt den Pfad des Cookies an, der für den Vergleich mit dem Anforderungspfad verwendet wird. Wenn dieser Pfad und die Domäne übereinstimmen, können Sie das Cookie in der Anforderung senden.
+- `expires` - Wird verwendet, um das Ablaufdatum für persistente Cookies festzulegen.
+
+Dies ist ein Beispiel zur Verwendung der [cookie-session](https://www.npmjs.com/package/cookie-session)-Middleware:
+
+```js
+const session = require('cookie-session');
+const express = require('express');
+const app = express();
+
+const expiryDate = new Date(Date.now() + 60 * 60 * 1000); // 1 hour
+app.use(
+ session({
+ name: 'session',
+ keys: ['key1', 'key2'],
+ cookie: {
+ secure: true,
+ httpOnly: true,
+ domain: 'example.com',
+ path: 'foo/bar',
+ expires: expiryDate,
+ },
+ })
+);
+```
+
+## Prevent brute-force attacks against authorization
+
+Make sure login endpoints are protected to make private data more secure.
+
+A simple and powerful technique is to block authorization attempts using two metrics:
+
+1. The number of consecutive failed attempts by the same user name and IP address.
+2. The number of failed attempts from an IP address over some long period of time. For example, block an IP address if it makes 100 failed attempts in one day.
+
+[rate-limiter-flexible](https://github.com/animir/node-rate-limiter-flexible) package provides tools to make this technique easy and fast. You can find [an example of brute-force protection in the documentation](https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#login-endpoint-protection)
+
+## Ensure your dependencies are secure
+
+Using npm to manage your application's dependencies is powerful and convenient. But the packages that you use may contain critical security vulnerabilities that could also affect your application. The security of your app is only as strong as the "weakest link" in your dependencies.
+
+Since npm@6, npm automatically reviews every install request. Also, you can use `npm audit` to analyze your dependency tree.
+
+```bash
+$ npm audit
+```
+
+If you want to stay more secure, consider [Snyk](https://snyk.io/).
+
+Snyk offers both a [command-line tool](https://www.npmjs.com/package/snyk) and a [Github integration](https://snyk.io/docs/github) that checks your application against [Snyk's open source vulnerability database](https://snyk.io/vuln/) for any known vulnerabilities in your dependencies. Install the CLI as follows:
+
+```bash
+$ npm install -g snyk
+$ cd your-app
+```
+
+Use this command to test your application for vulnerabilities:
+
+```bash
+$ snyk test
+```
+
+### Vermeiden Sie andere Schwachstellen
+
+Achten Sie auf [Node Security Project](https://npmjs.com/advisories)-Empfehlungen, die Express oder andere Module, die Ihre Anwendung nutzt, beeinträchtigen können. Im Allgemeinen ist Node Security Project aber eine exzellente Ressource mit Wissen und Tools zur Sicherheit von Node.
+
+Letztendlich können Express-Anwendungen – wie viele andere Webanwendungen auch – anfällig für eine Vielzahl webbasierter Attacken sein. Machen Sie sich deshalb mit bekannten [webspezifischen Schwachstellen](https://www.owasp.org/www-project-top-ten/) vertraut und treffen Sie die geeigneten Vorkehrungen, um diese zu vermeiden.
+
+## Weitere Überlegungen
+
+Dies sind einige weitere Empfehlungen aus der hervorragenden [Node.js Security Checklist](https://blog.risingstack.com/node-js-security-checklist/). In diesem Blogbeitrag finden Sie alle Details zu diesen Empfehlungen:
+
+- Filtern und bereinigen Sie immer Benutzereingaben, um sich gegen XS-Angriffe (Cross-Site Scripting) und Befehlsinjektionsattacken zu schützen.
+- Implementieren Sie Verteidungsmaßnahmen gegen SQL-Injection-Attacken, indem sie parametrisierte Abfragen oder vorbereitete Anweisungen einsetzen.
+- Nutzen Sie das Open-Source-Tool [sqlmap](http://sqlmap.org/), um SQL-Injection-Schwachstellen in Ihrer Anwendung zu erkennen.
+- Verwenden Sie die Tools [nmap](https://nmap.org/) und [sslyze](https://github.com/nabla-c0d3/sslyze), um die Konfiguration Ihrer SSL-Verschlüsselungen, -Schlüssel und Neuvereinbarungen sowie die Gültigkeit Ihres Zertifikats zu testen.
+- Verwenden Sie [safe-regex](https://www.npmjs.com/package/safe-regex), um sicherzustellen, dass Ihre regulären Ausdrücke nicht für [Denial-of-Service-Attacken](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS) anfällig sind.
+
+[helmet]:
diff --git a/astro/src/content/docs/de/4x/advanced/developing-template-engines.md b/astro/src/content/docs/de/4x/advanced/developing-template-engines.md
new file mode 100644
index 0000000000..354927776d
--- /dev/null
+++ b/astro/src/content/docs/de/4x/advanced/developing-template-engines.md
@@ -0,0 +1,45 @@
+---
+title: Template-Engines für Express entwickeln
+description: Learn how to develop custom template engines for Express.js using app.engine(), with examples on creating and integrating your own template rendering logic.
+---
+
+# Template-Engines für Express entwickeln
+
+Verwenden Sie die Methode `app.engine(ext, callback)`, um Ihre eigene Template-Engine zu erstellen. `ext` bezieht sich auf die Dateierweiterung, `callback` ist die Template-Engine-Funktion, die die folgenden Elemente als Parameter akzeptiert: die Position der Datei, das Optionsobjekt und die Callback-Funktion.
+
+Der folgende Code ist ein Beispiel für die Implementierung einer sehr einfachen Template-Engine für die Ausgabe von `.ntl`-Dateien.
+
+```js
+const fs = require('fs'); // this engine requires the fs module
+app.engine('ntl', (filePath, options, callback) => {
+ // define the template engine
+ fs.readFile(filePath, (err, content) => {
+ if (err) return callback(err);
+ // this is an extremely simple template engine
+ const rendered = content
+ .toString()
+ .replace('#title#', `${options.title} `)
+ .replace('#message#', `${options.message} `);
+ return callback(null, rendered);
+ });
+});
+app.set('views', './views'); // specify the views directory
+app.set('view engine', 'ntl'); // register the template engine
+```
+
+Ihre Anwendung ist jetzt in der Lage, `.ntl`-Dateien auszugeben. Erstellen Sie im Verzeichnis `views` eine Datei namens `index.ntl` mit dem folgenden Inhalt.
+
+```pug
+#title#
+#message#
+```
+
+Erstellen Sie dann in Ihrer Anwendung die folgende Route.
+
+```js
+app.get('/', (req, res) => {
+ res.render('index', { title: 'Hey', message: 'Hello there!' });
+});
+```
+
+Wenn Sie eine Anforderung zur Homepage einleiten, wird `index.ntl` im HTML-Format ausgegeben.
diff --git a/astro/src/content/docs/de/4x/advanced/healthcheck-graceful-shutdown.md b/astro/src/content/docs/de/4x/advanced/healthcheck-graceful-shutdown.md
new file mode 100644
index 0000000000..545baf7174
--- /dev/null
+++ b/astro/src/content/docs/de/4x/advanced/healthcheck-graceful-shutdown.md
@@ -0,0 +1,30 @@
+---
+title: Health Checks and Graceful Shutdown
+description: Learn how to implement health checks and graceful shutdown in Express apps to enhance reliability, manage deployments, and integrate with load balancers like Kubernetes.
+---
+
+# Health Checks and Graceful Shutdown
+
+## Graceful shutdown
+
+When you deploy a new version of your application, you must replace the previous version. The process manager you're using will first send a SIGTERM signal to the application to notify it that it will be killed. Once the application gets this signal, it should stop accepting new requests, finish all the ongoing requests, clean up the resources it used, including database connections and file locks then exit.
+
+### Beispiel
+
+```js
+const server = app.listen(port);
+
+process.on('SIGTERM', () => {
+ debug('SIGTERM signal received: closing HTTP server');
+ server.close(() => {
+ debug('HTTP server closed');
+ });
+});
+```
+
+## Health checks
+
+A load balancer uses health checks to determine if an application instance is healthy and can accept requests. For example, [Kubernetes has two health checks](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/):
+
+- `liveness`, that determines when to restart a container.
+- `readiness`, that determines when a container is ready to start accepting traffic. When a pod is not ready, it is removed from the service load balancers.
diff --git a/astro/src/content/docs/de/4x/advanced/security-updates.md b/astro/src/content/docs/de/4x/advanced/security-updates.md
new file mode 100644
index 0000000000..850aacf852
--- /dev/null
+++ b/astro/src/content/docs/de/4x/advanced/security-updates.md
@@ -0,0 +1,84 @@
+---
+title: Express-Sicherheitsupdates
+description: Review the latest security updates and patches for Express.js, including detailed vulnerability lists for different versions to help maintain a secure application.
+---
+
+# Sicherheitsupdates
+
+
+Schwachstellen bei Node.js wirken sich direkt auf Express aus. Daher sollten Sie [ein Auge auf Schwachstellen bei Node.js haben](https://nodejs.org
+/en/blog/vulnerability/) und sicherstellen, dass Sie die aktuelle stabile Version von Node.js haben.
+
+
+Die folgende Liste enthält die Express-Schwachstellen, die im angegebenen Versionsupdate behoben wurden.
+
+{% capture security-policy %}
+If you believe you have discovered a security vulnerability in Express, please see
+[Security Policies and Procedures](/en/resources/contributing#security-policies-and-procedures).
+{% endcapture %}
+
+{% include admonitions/note.html content=security-policy %}
+
+## 4.x
+
+- 4.21.2
+ - The dependency `path-to-regexp` has been updated to address a [vulnerability](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-rhx6-c78j-4q9w).
+- 4.21.1
+ - The dependency `cookie` has been updated to address a [vulnerability](https://github.com/jshttp/cookie/security/advisories/GHSA-pxg6-pf52-xh8x), This may affect your application if you use `res.cookie`.
+- 4.20.0
+ - Fixed XSS vulnerability in `res.redirect` ([advisory](https://github.com/expressjs/express/security/advisories/GHSA-qw6h-vgh9-j6wx), [CVE-2024-43796](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-43796)).
+ - The dependency `serve-static` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-cm22-4g7w-348p).
+ - The dependency `send` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-m6fv-jmcg-4jfg).
+ - The dependency `path-to-regexp` has been updated to address a [vulnerability](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-9wv6-86v2-598j).
+ - The dependency `body-parser` has been updated to addres a [vulnerability](https://github.com/advisories/GHSA-qwcr-r2fm-qrc7), This may affect your application if you had url enconding activated.
+- 4.19.0, 4.19.1
+ - Fixed open redirect vulnerability in `res.location` and `res.redirect` ([advisory](https://github.com/expressjs/express/security/advisories/GHSA-rv95-896h-c2vc), [CVE-2024-29041](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-29041)).
+- 4.17.3
+ - The dependency `qs` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-hrpp-h998-j3pp). This may affect your application if the following APIs are used: `req.query`, `req.body`, `req.param`.
+- 4.16.0
+ - The dependency `forwarded` has been updated to address a [vulnerability](https://npmjs.com/advisories/527). This may affect your application if the following APIs are used: `req.host`, `req.hostname`, `req.ip`, `req.ips`, `req.protocol`.
+ - The dependency `mime` has been updated to address a [vulnerability](https://npmjs.com/advisories/535), but this issue does not impact Express.
+ - The dependency `send` has been updated to provide a protection against a [Node.js 8.5.0 vulnerability](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/). This only impacts running Express on the specific Node.js version 8.5.0.
+- 4.15.5
+ - The dependency `debug` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:debug:20170905), but this issue does not impact Express.
+ - The dependency `fresh` has been updated to address a [vulnerability](https://npmjs.com/advisories/526). This will affect your application if the following APIs are used: `express.static`, `req.fresh`, `res.json`, `res.jsonp`, `res.send`, `res.sendfile` `res.sendFile`, `res.sendStatus`.
+- 4.15.3
+ - The dependency `ms` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:ms:20170412). This may affect your application if untrusted string input is passed to the `maxAge` option in the following APIs: `express.static`, `res.sendfile`, and `res.sendFile`.
+- 4.15.2
+ - The dependency `qs` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:qs:20170213), but this issue does not impact Express. Updating to 4.15.2 is a good practice, but not required to address the vulnerability.
+- 4.11.1
+ - Offenlegungsgefahr beim Rootpfad in `express.static`, `res.sendfile` und `res.sendFile` behoben.
+- 4.10.7
+ - Offene Umadressierungsschwachstelle in `express.static` ([Empfehlung](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)) behoben.
+- 4.8.8
+ - Schwachstellen durch Directory-Traversal-Technik in `express.static` ([Empfehlung](http://npmjs.com/advisories/32) , [CVE-2014-6394](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6394)) behoben.
+- 4.8.4
+ - Node.js 0.10 kann in bestimmten Situationen Lecks bei `fd` aufweisen, die sich auf `express.static` und `res.sendfile` auswirken. Böswillige Anforderungen können zu Lecks bei `fd` führen und letztendlich `EMFILE`-Fehler nach sich ziehen und bewirken, dass Server nicht antworten.
+- 4.8.0
+ - Sparse-Arrays mit extrem hohen Indizes in der Abfragezeichenfolge können bewirken, dass für die Prozessausführung nicht genügend Arbeitsspeicher zur Verfügung steht und es zu einem Serverabsturz kommt.
+ - Extrem verschachtelte Abfragezeichenfolgenobjekte können bewirken, dass der Prozess blockiert und der Server dadurch vorübergehend nicht antwortet.
+
+## 3.x
+
+
+ **Express 3.x WIRD NICHT MEHR GEWARTET**
+
+Bekannte und unbekannte Probleme bei Sicherheit und Leistung in 3.x wurden seit dem letzten Update (1. August 2015) noch nicht behoben. Es wird dringend empfohlen, die aktuelle Version von Express zu verwenden.
+
+If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/en/support#commercial-support-options).
+
+
+
+- 3.19.1
+ - Offenlegungsgefahr beim Rootpfad in `express.static`, `res.sendfile` und `res.sendFile` behoben.
+- 3.19.0
+ - Offene Umadressierungsschwachstelle in `express.static` ([Empfehlung](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)) behoben.
+- 3.16.10
+ - Schwachstellen durch Directory-Traversal-Technik in `express.static` behoben.
+- 3.16.6
+ - Node.js 0.10 kann in bestimmten Situationen Lecks bei `fd` aufweisen, die sich auf `express.static` und `res.sendfile` auswirken. Böswillige Anforderungen können zu Lecks bei `fd` führen und letztendlich `EMFILE`-Fehler nach sich ziehen und bewirken, dass Server nicht antworten.
+- 3.16.0
+ - Sparse-Arrays mit extrem hohen Indizes in der Abfragezeichenfolge können bewirken, dass für die Prozessausführung nicht genügend Arbeitsspeicher zur Verfügung steht und es zu einem Serverabsturz kommt.
+ - Extrem verschachtelte Abfragezeichenfolgenobjekte können bewirken, dass der Prozess blockiert und der Server dadurch vorübergehend nicht antwortet.
+- 3.3.0
+ - Die Antwort 404 bei einem nicht unterstützten Überschreibungsversuch war anfällig gegen Cross-Site Scripting-Attacken.
diff --git a/astro/src/content/docs/de/4x/api.md b/astro/src/content/docs/de/4x/api.md
new file mode 100644
index 0000000000..4ec463d229
--- /dev/null
+++ b/astro/src/content/docs/de/4x/api.md
@@ -0,0 +1,26 @@
+---
+version: 4x
+title: Express 4.x - API-Referenz
+description: Access the API reference for Express.js 4.x, detailing all modules, methods, and properties for building web applications with this version.
+---
+
+
+
+
4.x-API
+
+{% capture node-version %}
+
+Express 4.0 requires Node.js 0.10 or higher.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=node-version %}
+
+
+{% include api/en/4x/express.md %}
+{% include api/en/4x/app.md %}
+{% include api/en/4x/req.md %}
+{% include api/en/4x/res.md %}
+{% include api/en/4x/router.md %}
+
+
diff --git a/astro/src/content/docs/de/4x/guide/behind-proxies.md b/astro/src/content/docs/de/4x/guide/behind-proxies.md
new file mode 100644
index 0000000000..34def6bfcb
--- /dev/null
+++ b/astro/src/content/docs/de/4x/guide/behind-proxies.md
@@ -0,0 +1,90 @@
+---
+title: Express hinter Proxys
+description: Learn how to configure Express.js applications to work correctly behind reverse proxies, including using the trust proxy setting to handle client IP addresses.
+---
+
+# Express hinter Proxys
+
+When running an Express app behind a reverse proxy, some of the Express APIs may return different values than expected. In order to adjust for this, the `trust proxy` application setting may be used to expose information provided by the reverse proxy in the Express APIs. The most common issue is express APIs that expose the client's IP address may instead show an internal IP address of the reverse proxy.
+
+
+When configuring the `trust proxy` setting, it is important to understand the exact setup of the reverse proxy. Since this setting will trust values provided in the request, it is important that the combination of the setting in Express matches how the reverse proxy operates.
+
+
+Bei der Ausführung einer Express-Anwendung hinter einem Proxy legen Sie die Anwendungsvariable `trust proxy` (mithilfe von [app.set()](/en/4x/api#app.set)) auf einen der in der folgenden Tabelle enthaltenen Werte fest:
+
+
+ Typ Wert
+
+
+ Boolesch
+Wenn `true` angegeben wird, wird die IP-Adresse des Clients als der äußerst rechte Eintrag im Header `X-Forwarded-*` interpretiert.
+
+Wenn `false` angegeben wird, wird die Anwendung als direkte Verbindung zum Internet gesehen. Die IP-Adresse des Clients wird dann von `req.connection.remoteAddress` abgeleitet. Dies ist die Standardeinstellung.
+
+
+When setting to `true`, it is important to ensure that the last reverse proxy trusted is removing/overwriting all of the following HTTP headers: `X-Forwarded-For`, `X-Forwarded-Host`, and `X-Forwarded-Proto`, otherwise it may be possible for the client to provide any value.
+
+
+
+
+ IP addresses
+
+An IP address, subnet, or an array of IP addresses and subnets to trust as being a reverse proxy. The following list shows the pre-configured subnet names:
+
+- loopback - `127.0.0.1/8`, `::1/128`
+- linklocal - `169.254.0.0/16`, `fe80::/10`
+- uniquelocal - `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7`
+
+Sie können IP-Adressen wie folgt festlegen:
+
+```js
+app.set('trust proxy', 'loopback'); // specify a single subnet
+app.set('trust proxy', 'loopback, 123.123.123.123'); // specify a subnet and an address
+app.set('trust proxy', 'loopback, linklocal, uniquelocal'); // specify multiple subnets as CSV
+app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']); // specify multiple subnets as an array
+```
+
+Sobald die Werte angegeben wurden, werden die betreffenden IP-Adressen und Teilnetze aus dem Adressfeststellungsprozess ausgeschlossen. Die nicht vertrauenswürdige IP-Adresse, die am nächsten zum Anwendungsserver liegt, wird als IP-Adresse des Clients festgelegt. This works by checking if `req.socket.remoteAddress` is trusted. If so, then each address in `X-Forwarded-For` is checked from right to left until the first non-trusted address.
+
+
+
+
+ Zahl
+
+Use the address that is at most `n` number of hops away from the Express application. `req.socket.remoteAddress` is the first hop, and the rest are looked for in the `X-Forwarded-For` header from right to left. A value of `0` means that the first untrusted address would be `req.socket.remoteAddress`, i.e. there is no reverse proxy.
+
+
+When using this setting, it is important to ensure there are not multiple, different-length paths to the Express application such that the client can be less than the configured number of hops away, otherwise it may be possible for the client to provide any value.
+
+
+
+
+ Function
+
+Custom trust implementation.
+
+```js
+app.set('trust proxy', (ip) => {
+ if (ip === '127.0.0.1' || ip === '123.123.123.123')
+ return true; // trusted IPs
+ else return false;
+});
+```
+
+
+
+
+
+
+Enabling `trust proxy` will have the following impact:
+
+
+ Der Wert für [req.hostname](/en/api#req.hostname) wird vom Wert abgeleitet, der im Header `X-Forwarded-Host` festgelegt wurde. Dieser Wert kann vom Client oder Proxy festgelegt werden.
+ `X-Forwarded-Proto` kann vom Reverse Proxy festgelegt werden, um der Anwendung mitzuteilen, ob es sich um `https` oder `http` oder sogar um einen ungültigen Namen handelt. Dieser Wert wird durch [req.protocol](/en/api#req.protocol) abgebildet.
+
+ Als Werte für [req.ip](/en/api#req.ip) und [req.ips](/en/api#req.ips) wird die Liste der Adressen aus `X-Forwarded-For` herangezogen.
+
+
+
+Die Einstellung für `trust proxy` wird mithilfe des [proxy-addr](https://www.npmjs.com/package/proxy-addr)-Pakets implementiert. Weitere Informationen finden Sie in der zugehörigen Dokumentation.
diff --git a/astro/src/content/docs/de/4x/guide/database-integration.md b/astro/src/content/docs/de/4x/guide/database-integration.md
new file mode 100644
index 0000000000..fcd6291fc1
--- /dev/null
+++ b/astro/src/content/docs/de/4x/guide/database-integration.md
@@ -0,0 +1,509 @@
+---
+title: Datenbankintegration in Express
+description: Discover how to integrate various databases with Express.js applications, including setup examples for MongoDB, MySQL, PostgreSQL, and more.
+---
+
+# Datenbankintegration
+
+Die Herstellung einer Verbindung zwischen Datenbanken und Express-Anwendungen erfolgt einfach durch Laden eines geeigneten Node.js-Treibers für die Datenbank in Ihre Anwendung. In diesem Dokument wird in Kurzform beschrieben, wie einige der gängigsten Node.js-Module für Datenbanksysteme Ihrer Express-Anwendung hinzugefügt und verwendet werden:
+
+- [Cassandra](#cassandra)
+- [Couchbase](#couchbase)
+- [CouchDB](#couchdb)
+- [LevelDB](#leveldb)
+- [MySQL](#mysql)
+- [MongoDB](#mongo)
+- [Neo4j](#neo4j)
+- [Oracle](#oracle)
+- [PostgreSQL](#postgres)
+- [Redis](#redis)
+-
+- [SQLite](#sqlite)
+- [ElasticSearch](#elasticsearch)
+
+
+Diese Datenbanktreiber sind neben zahlreichen anderen Treibern verfügbar. Weitere Optionen finden Sie auf der [npm](https://www.npmjs.com/)-Site.
+
+
+## Cassandra
+
+**Modul**: [cassandra-driver](https://github.com/datastax/nodejs-driver)
+**Installation**
+
+### Installation
+
+```bash
+$ npm install cassandra-driver
+```
+
+### Beispiel
+
+```js
+const cassandra = require('cassandra-driver');
+const client = new cassandra.Client({ contactPoints: ['localhost'] });
+
+client.execute('select key from system.local', (err, result) => {
+ if (err) throw err;
+ console.log(result.rows[0]);
+});
+```
+
+## Couchbase
+
+**Module**: [couchnode](https://github.com/couchbase/couchnode)
+
+### Installation
+
+```bash
+$ npm install couchbase
+```
+
+### Beispiel
+
+```js
+const couchbase = require('couchbase');
+const bucket = new couchbase.Cluster('http://localhost:8091').openBucket('bucketName');
+
+// add a document to a bucket
+bucket.insert('document-key', { name: 'Matt', shoeSize: 13 }, (err, result) => {
+ if (err) {
+ console.log(err);
+ } else {
+ console.log(result);
+ }
+});
+
+// get all documents with shoe size 13
+const n1ql = 'SELECT d.* FROM `bucketName` d WHERE shoeSize = $1';
+const query = N1qlQuery.fromString(n1ql);
+bucket.query(query, [13], (err, result) => {
+ if (err) {
+ console.log(err);
+ } else {
+ console.log(result);
+ }
+});
+```
+
+## CouchDB
+
+**Modul**: [nano](https://github.com/dscape/nano)
+**Installation**
+
+### Installation
+
+```bash
+$ npm install nano
+```
+
+### Beispiel
+
+```js
+const nano = require('nano')('http://localhost:5984');
+nano.db.create('books');
+const books = nano.db.use('books');
+
+// Insert a book document in the books database
+books.insert({ name: 'The Art of war' }, null, (err, body) => {
+ if (err) {
+ console.log(err);
+ } else {
+ console.log(body);
+ }
+});
+
+// Get a list of all books
+books.list((err, body) => {
+ if (err) {
+ console.log(err);
+ } else {
+ console.log(body.rows);
+ }
+});
+```
+
+## LevelDB
+
+**Modul**: [levelup](https://github.com/rvagg/node-levelup)
+**Installation**
+
+### Installation
+
+```bash
+$ npm install level levelup leveldown
+```
+
+### Beispiel
+
+```js
+const levelup = require('levelup');
+const db = levelup('./mydb');
+
+db.put('name', 'LevelUP', (err) => {
+ if (err) return console.log('Ooops!', err);
+
+ db.get('name', (err, value) => {
+ if (err) return console.log('Ooops!', err);
+
+ console.log(`name=${value}`);
+ });
+});
+```
+
+## MySQL
+
+**Modul**: [mysql](https://github.com/felixge/node-mysql/)
+**Installation**
+
+### Installation
+
+```bash
+$ npm install mysql
+```
+
+### Beispiel
+
+```js
+const mysql = require('mysql');
+const connection = mysql.createConnection({
+ host: 'localhost',
+ user: 'dbuser',
+ password: 's3kreee7',
+ database: 'my_db',
+});
+
+connection.connect();
+
+connection.query('SELECT 1 + 1 AS solution', (err, rows, fields) => {
+ if (err) throw err;
+
+ console.log('The solution is: ', rows[0].solution);
+});
+
+connection.end();
+```
+
+## MongoDB
+
+**Modul**: [mongodb](https://github.com/mongodb/node-mongodb-native)
+**Installation**
+
+### Installation
+
+```bash
+$ npm install mongodb
+```
+
+### Example (v2.\*)
+
+```js
+const MongoClient = require('mongodb').MongoClient;
+
+MongoClient.connect('mongodb://localhost:27017/animals', (err, db) => {
+ if (err) throw err;
+
+ db.collection('mammals')
+ .find()
+ .toArray((err, result) => {
+ if (err) throw err;
+
+ console.log(result);
+ });
+});
+```
+
+### Example (v3.\*)
+
+```js
+const MongoClient = require('mongodb').MongoClient;
+
+MongoClient.connect('mongodb://localhost:27017/animals', (err, client) => {
+ if (err) throw err;
+
+ const db = client.db('animals');
+
+ db.collection('mammals')
+ .find()
+ .toArray((err, result) => {
+ if (err) throw err;
+
+ console.log(result);
+ });
+});
+```
+
+Wenn Sie nach einem Objektmodelltreiber für MongoDB suchen, schauen Sie unter [Mongoose](https://github.com/LearnBoost/mongoose) nach.
+
+## Neo4j
+
+**Module**: [neo4j-driver](https://github.com/neo4j/neo4j-javascript-driver)
+
+### Installation
+
+```bash
+$ npm install neo4j-driver
+```
+
+### Beispiel
+
+```js
+const neo4j = require('neo4j-driver');
+const driver = neo4j.driver('neo4j://localhost:7687', neo4j.auth.basic('neo4j', 'letmein'));
+
+const session = driver.session();
+
+session.readTransaction((tx) => {
+ return tx
+ .run('MATCH (n) RETURN count(n) AS count')
+ .then((res) => {
+ console.log(res.records[0].get('count'));
+ })
+ .catch((error) => {
+ console.log(error);
+ });
+});
+```
+
+## Oracle
+
+**Modul**: [oracledb](https://github.com/oracle/node-oracledb)
+
+### Installation
+
+Anmerkung: [Siehe Installations-Voraussetzungen](https://github.com/oracle/node-oracledb#-installation).
+
+```bash
+$ npm install oracledb
+```
+
+### Beispiel
+
+```js
+const oracledb = require('oracledb');
+const config = {
+ user: '',
+ password: '',
+ connectString: 'localhost:1521/orcl',
+};
+
+async function getEmployee(empId) {
+ let conn;
+
+ try {
+ conn = await oracledb.getConnection(config);
+
+ const result = await conn.execute('select * from employees where employee_id = :id', [empId]);
+
+ console.log(result.rows[0]);
+ } catch (err) {
+ console.log('Ouch!', err);
+ } finally {
+ if (conn) {
+ // conn assignment worked, need to close
+ await conn.close();
+ }
+ }
+}
+
+getEmployee(101);
+```
+
+## PostgreSQL
+
+**Modul**: [pg-promise](https://github.com/vitaly-t/pg-promise)
+**Installation**
+
+### Installation
+
+```bash
+$ npm install pg-promise
+```
+
+### Beispiel
+
+```js
+const pgp = require('pg-promise')(/* options */);
+const db = pgp('postgres://username:password@host:port/database');
+
+db.one('SELECT $1 AS value', 123)
+ .then((data) => {
+ console.log('DATA:', data.value);
+ })
+ .catch((error) => {
+ console.log('ERROR:', error);
+ });
+```
+
+## Redis
+
+**Modul**: [redis](https://github.com/mranney/node_redis)
+**Installation**
+
+### Installation
+
+```bash
+$ npm install redis
+```
+
+### Beispiel
+
+```js
+const redis = require('redis');
+const client = redis.createClient();
+
+client.on('error', (err) => {
+ console.log(`Error ${err}`);
+});
+
+client.set('string key', 'string val', redis.print);
+client.hset('hash key', 'hashtest 1', 'some value', redis.print);
+client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print);
+
+client.hkeys('hash key', (err, replies) => {
+ console.log(`${replies.length} replies:`);
+
+ replies.forEach((reply, i) => {
+ console.log(` ${i}: ${reply}`);
+ });
+
+ client.quit();
+});
+```
+
+## SQL Server
+
+**Module**: [tedious](https://github.com/tediousjs/tedious)
+
+### Installation
+
+```bash
+$ npm install tedious
+```
+
+### Beispiel
+
+```js
+const Connection = require('tedious').Connection;
+const Request = require('tedious').Request;
+
+const config = {
+ server: 'localhost',
+ authentication: {
+ type: 'default',
+ options: {
+ userName: 'your_username', // update me
+ password: 'your_password', // update me
+ },
+ },
+};
+
+const connection = new Connection(config);
+
+connection.on('connect', (err) => {
+ if (err) {
+ console.log(err);
+ } else {
+ executeStatement();
+ }
+});
+
+function executeStatement() {
+ request = new Request("select 123, 'hello world'", (err, rowCount) => {
+ if (err) {
+ console.log(err);
+ } else {
+ console.log(`${rowCount} rows`);
+ }
+ connection.close();
+ });
+
+ request.on('row', (columns) => {
+ columns.forEach((column) => {
+ if (column.value === null) {
+ console.log('NULL');
+ } else {
+ console.log(column.value);
+ }
+ });
+ });
+
+ connection.execSql(request);
+}
+```
+
+## SQLite
+
+**Modul**: [sqlite3](https://github.com/mapbox/node-sqlite3)
+**Installation**
+
+### Installation
+
+```bash
+$ npm install sqlite3
+```
+
+### Beispiel
+
+```js
+const sqlite3 = require('sqlite3').verbose();
+const db = new sqlite3.Database(':memory:');
+
+db.serialize(() => {
+ db.run('CREATE TABLE lorem (info TEXT)');
+ const stmt = db.prepare('INSERT INTO lorem VALUES (?)');
+
+ for (let i = 0; i < 10; i++) {
+ stmt.run(`Ipsum ${i}`);
+ }
+
+ stmt.finalize();
+
+ db.each('SELECT rowid AS id, info FROM lorem', (err, row) => {
+ console.log(`${row.id}: ${row.info}`);
+ });
+});
+
+db.close();
+```
+
+## ElasticSearch
+
+**Modul**: [elasticsearch](https://github.com/elastic/elasticsearch-js)
+**Installation**
+
+### Installation
+
+```bash
+$ npm install elasticsearch
+```
+
+### Beispiel
+
+```js
+const elasticsearch = require('elasticsearch');
+const client = elasticsearch.Client({
+ host: 'localhost:9200',
+});
+
+client
+ .search({
+ index: 'books',
+ type: 'book',
+ body: {
+ query: {
+ multi_match: {
+ query: 'express js',
+ fields: ['title', 'description'],
+ },
+ },
+ },
+ })
+ .then(
+ (response) => {
+ const hits = response.hits.hits;
+ },
+ (error) => {
+ console.trace(error.message);
+ }
+ );
+```
diff --git a/astro/src/content/docs/de/4x/guide/debugging.md b/astro/src/content/docs/de/4x/guide/debugging.md
new file mode 100644
index 0000000000..1d69c7bda7
--- /dev/null
+++ b/astro/src/content/docs/de/4x/guide/debugging.md
@@ -0,0 +1,126 @@
+---
+title: Debugging bei Express
+description: Learn how to enable and use debugging logs in Express.js applications by setting the DEBUG environment variable for enhanced troubleshooting.
+---
+
+# Debugging bei Express
+
+Wenn Sie alle in Express verwendeten internen Protokolle anzeigen wollen, legen Sie beim Starten Ihrer Anwendung die Umgebungsvariable `DEBUG` auf `express:*` fest.
+
+```bash
+$ DEBUG=express:* node index.js
+```
+
+Verwenden Sie unter Windows den entsprechenden Befehl.
+
+```bash
+> $env:DEBUG = "express:*"; node index.js
+```
+
+Die Ausführung dieses Befehls für die durch [express generator](/en/starter/generator) generierte Standardanwendung resultiert in folgender Ausgabe:
+
+```bash
+$ DEBUG=express:* node ./bin/www
+ express:router:route new / +0ms
+ express:router:layer new / +1ms
+ express:router:route get / +1ms
+ express:router:layer new / +0ms
+ express:router:route new / +1ms
+ express:router:layer new / +0ms
+ express:router:route get / +0ms
+ express:router:layer new / +0ms
+ express:application compile etag weak +1ms
+ express:application compile query parser extended +0ms
+ express:application compile trust proxy false +0ms
+ express:application booting in development mode +1ms
+ express:router use / query +0ms
+ express:router:layer new / +0ms
+ express:router use / expressInit +0ms
+ express:router:layer new / +0ms
+ express:router use / favicon +1ms
+ express:router:layer new / +0ms
+ express:router use / logger +0ms
+ express:router:layer new / +0ms
+ express:router use / jsonParser +0ms
+ express:router:layer new / +1ms
+ express:router use / urlencodedParser +0ms
+ express:router:layer new / +0ms
+ express:router use / cookieParser +0ms
+ express:router:layer new / +0ms
+ express:router use / stylus +90ms
+ express:router:layer new / +0ms
+ express:router use / serveStatic +0ms
+ express:router:layer new / +0ms
+ express:router use / router +0ms
+ express:router:layer new / +1ms
+ express:router use /users router +0ms
+ express:router:layer new /users +0ms
+ express:router use / <anonymous> +0ms
+ express:router:layer new / +0ms
+ express:router use / <anonymous> +0ms
+ express:router:layer new / +0ms
+ express:router use / <anonymous> +0ms
+ express:router:layer new / +0ms
+```
+
+Bei einer Anforderung an die Anwendung sind die Protokolle im Express-Code angegeben:
+
+```bash
+ express:router dispatching GET / +4h
+ express:router query : / +2ms
+ express:router expressInit : / +0ms
+ express:router favicon : / +0ms
+ express:router logger : / +1ms
+ express:router jsonParser : / +0ms
+ express:router urlencodedParser : / +1ms
+ express:router cookieParser : / +0ms
+ express:router stylus : / +0ms
+ express:router serveStatic : / +2ms
+ express:router router : / +2ms
+ express:router dispatching GET / +1ms
+ express:view lookup "index.pug" +338ms
+ express:view stat "/projects/example/views/index.pug" +0ms
+ express:view render "/projects/example/views/index.pug" +1ms
+```
+
+Wenn Sie nur die Protokolle von der Routerimplementierung sehen wollen, legen Sie den Wert für `DEBUG` auf `express:router` fest. Gleichermaßen gilt: Wenn Sie nur die Protokolle von der Anwendungsimplementierung sehen wollen, legen Sie den Wert für `DEBUG` auf `express:application` fest, usw.
+
+## Von `express` generierte Anwendungen
+
+An application generated by the `express` command uses the `debug` module and its debug namespace is scoped to the name of the application.
+
+Beispiel: Wenn Sie die Anwendung mit `$ express sample-app` generiert haben, können Sie die Debuganweisungen mit dem folgenden Befehl aktivieren:
+
+```bash
+$ DEBUG=sample-app:* node ./bin/www
+```
+
+Sie können mehrere Debug-Namespaces in einer durch Kommas getrennten Namensliste angeben:
+
+```bash
+$ DEBUG=http,mail,express:* node index.js
+```
+
+## Advanced options
+
+When running through Node.js, you can set a few environment variables that will change the behavior of the debug logging:
+
+| Name | Purpose |
+| ------------------- | ------------------------------------------------- |
+| `DEBUG` | Enables/disables specific debugging namespaces. |
+| `DEBUG_COLORS` | Whether or not to use colors in the debug output. |
+| `DEBUG_DEPTH` | Object inspection depth. |
+| `DEBUG_FD` | File descriptor to write debug output to. |
+| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. |
+
+{% capture debug-text %}
+
+The environment variables beginning with `DEBUG_` end up being
+converted into an Options object that gets used with `%o`/`%O` formatters.
+See the Node.js documentation for
+[`util.inspect()`](https://nodejs.org/api/util#util_util_inspect_object_options)
+for the complete list.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=debug-text %}
diff --git a/astro/src/content/docs/de/4x/guide/error-handling.md b/astro/src/content/docs/de/4x/guide/error-handling.md
new file mode 100644
index 0000000000..6431405f27
--- /dev/null
+++ b/astro/src/content/docs/de/4x/guide/error-handling.md
@@ -0,0 +1,289 @@
+---
+title: Fehlerbehandlung in Express
+description: Understand how Express.js handles errors in synchronous and asynchronous code, and learn to implement custom error handling middleware for your applications.
+---
+
+# Fehlerbehandlung
+
+_Error Handling_ refers to how Express catches and processes errors that
+occur both synchronously and asynchronously. Express comes with a default error
+handler so you don't need to write your own to get started.
+
+## Catching Errors
+
+It's important to ensure that Express catches all errors that occur while
+running route handlers and middleware.
+
+Errors that occur in synchronous code inside route handlers and middleware
+require no extra work. If synchronous code throws an error, then Express will
+catch and process it. Beispiel:
+
+```js
+app.get('/', (req, res) => {
+ throw new Error('BROKEN'); // Express will catch this on its own.
+});
+```
+
+Middlewarefunktionen für die Fehlerbehandlung werden in derselben Weise definiert wie andere Middlewarefunktionen, nur, dass Fehlerbehandlungsfunktionen vier anstatt drei Argumente aufweisen:
+`(err, req, res, next)`. Beispiel:
+
+```js
+app.get('/', (req, res, next) => {
+ fs.readFile('/file-does-not-exist', (err, data) => {
+ if (err) {
+ next(err); // Pass errors to Express.
+ } else {
+ res.send(data);
+ }
+ });
+});
+```
+
+Middleware für die Fehlerbehandlung wird ganz zuletzt nach allen anderen `app.use()`- und Weiterleitungsaufrufen definiert.
+Beispiel:
+
+```js
+app.get('/user/:id', async (req, res, next) => {
+ const user = await getUserById(req.params.id);
+ res.send(user);
+});
+```
+
+If `getUserById` throws an error or rejects, `next` will be called with either
+the thrown error or the rejected value. If no rejected value is provided, `next`
+will be called with a default Error object provided by the Express router.
+
+Wenn Sie Übergaben an die Funktion `next()` vornehmen (außer die Zeichenfolge `'route'`), sieht Express die aktuelle Anforderung als Fehler an und überspringt alle verbleibenden fehlerfreien Behandlungsroutinen und Middlewarefunktionen.
+
+If the callback in a sequence provides no data, only errors, you can simplify
+this code as follows:
+
+```js
+app.get('/', [
+ function (req, res, next) {
+ fs.writeFile('/inaccessible-path', 'data', next);
+ },
+ function (req, res) {
+ res.send('OK');
+ },
+]);
+```
+
+In the above example, `next` is provided as the callback for `fs.writeFile`,
+which is called with or without errors. If there is no error, the second
+handler is executed, otherwise Express catches and processes the error.
+
+Bei einem Routenhandler mit mehreren Callback-Funktionen können Sie den Parameter `route` verwenden, um den nächsten Routenhandler zu überspringen. Beispiel:
+
+```js
+app.get('/', (req, res, next) => {
+ setTimeout(() => {
+ try {
+ throw new Error('BROKEN');
+ } catch (err) {
+ next(err);
+ }
+ }, 100);
+});
+```
+
+The above example uses a `try...catch` block to catch errors in the
+asynchronous code and pass them to Express. If the `try...catch`
+block were omitted, Express would not catch the error since it is not part of the synchronous
+handler code.
+
+Use promises to avoid the overhead of the `try...catch` block or when using functions
+that return promises. Beispiel:
+
+```js
+app.get('/', (req, res, next) => {
+ Promise.resolve()
+ .then(() => {
+ throw new Error('BROKEN');
+ })
+ .catch(next); // Errors will be passed to Express.
+});
+```
+
+Since promises automatically catch both synchronous errors and rejected promises,
+you can simply provide `next` as the final catch handler and Express will catch errors,
+because the catch handler is given the error as the first argument.
+
+You could also use a chain of handlers to rely on synchronous error
+catching, by reducing the asynchronous code to something trivial. Beispiel:
+
+```js
+app.get('/', [
+ function (req, res, next) {
+ fs.readFile('/maybe-valid-file', 'utf-8', (err, data) => {
+ res.locals.data = data;
+ next(err);
+ });
+ },
+ function (req, res) {
+ res.locals.data = res.locals.data.split(',')[1];
+ res.send(res.locals.data);
+ },
+]);
+```
+
+The above example has a couple of trivial statements from the `readFile`
+call. If `readFile` causes an error, then it passes the error to Express, otherwise you
+quickly return to the world of synchronous error handling in the next handler
+in the chain. Then, the example above tries to process the data. If this fails, then the
+synchronous error handler will catch it. If you had done this processing inside
+the `readFile` callback, then the application might exit and the Express error
+handlers would not run.
+
+Whichever method you use, if you want Express error handlers to be called in and the
+application to survive, you must ensure that Express receives the error.
+
+## Die Standardfehlerbehandlungsroutine (Default Error Handler)
+
+Express ist bereits mit einer integrierten Fehlerbehandlungsroutine ausgestattet, mit der alle in der Anwendung festgestellten Fehler gehandhabt werden können. Diese Middleware für die Fehlerbehandlung wird am Ende des Middleware-Funktionsstack hinzugefügt.
+
+Wenn Sie einen Fehler an `next()` übergeben und diesen nicht mit einem Error-Handler bearbeiten, wird dieser über den integrierten Error-Handler bearbeitet. Der Fehler wird mit dem Stack-Trace zum Client geschrieben. Der Stack-Trace ist in der Produktionsumgebung nicht verfügbar.
+
+
+Legen Sie die Umgebungsvariable `NODE_ENV` auf `production` fest, um die Anwendung im Produktionsmodus auszuführen.
+
+
+When an error is written, the following information is added to the
+response:
+
+- The `res.statusCode` is set from `err.status` (or `err.statusCode`). If
+ this value is outside the 4xx or 5xx range, it will be set to 500.
+- The `res.statusMessage` is set according to the status code.
+- The body will be the HTML of the status code message when in production
+ environment, otherwise will be `err.stack`.
+- Any headers specified in an `err.headers` object.
+
+Wenn `next()` mit einem Fehler aufgerufen wird, nachdem Sie mit dem Schreiben der Antwort begonnen haben (z. B., wenn Sie beim Streamen der Antwort zum Client einen Fehler feststellen), schließt die Standardfehlerbehandlungsroutine in Express die Verbindung, und die Anforderung schlägt fehl.
+
+Wenn Sie also einen angepassten Error-Handler hinzufügen, empfiehlt es sich, eine Delegierung zur Standardfehlerbehandlungsroutine in Express vorzunehmen, wenn die Header bereits an den Client gesendet wurden:
+
+```js
+function errorHandler(err, req, res, next) {
+ if (res.headersSent) {
+ return next(err);
+ }
+ res.status(500);
+ res.render('error', { error: err });
+}
+```
+
+Note that the default error handler can get triggered if you call `next()` with an error
+in your code more than once, even if custom error handling middleware is in place.
+
+Other error handling middleware can be found at [Express middleware](/en/resources/middleware).
+
+## Writing error handlers
+
+Define error-handling middleware functions in the same way as other middleware functions,
+except error-handling functions have four arguments instead of three:
+`(err, req, res, next)`. Beispiel:
+
+```js
+app.use((err, req, res, next) => {
+ console.error(err.stack);
+ res.status(500).send('Something broke!');
+});
+```
+
+You define error-handling middleware last, after other `app.use()` and routes calls; for example:
+
+```js
+const bodyParser = require('body-parser');
+const methodOverride = require('method-override');
+
+app.use(
+ bodyParser.urlencoded({
+ extended: true,
+ })
+);
+app.use(bodyParser.json());
+app.use(methodOverride());
+app.use((err, req, res, next) => {
+ // logic
+});
+```
+
+Antworten von der Middlewarefunktion können das von Ihnen gewünschte Format aufweisen wie beispielsweise eine Fehlerseite im HTML-Format, eine einfache Nachricht oder eine JSON-Zeichenfolge.
+
+Für organisatorische Zwecke (und Frameworks der höheren Ebene) können Sie mehrere Middlewarefunktionen für die Fehlerbehandlung definieren, wie Sie dies bei regulären Middlewarefunktionen auch tun würden. Wenn Sie beispielsweise eine Fehlerbehandlungsroutine (Error-Handler) für Anforderungen über `XHR` und andere Anforderungen definieren wollen, können Sie die folgenden Befehle verwenden:
+
+```js
+const bodyParser = require('body-parser');
+const methodOverride = require('method-override');
+
+app.use(
+ bodyParser.urlencoded({
+ extended: true,
+ })
+);
+app.use(bodyParser.json());
+app.use(methodOverride());
+app.use(logErrors);
+app.use(clientErrorHandler);
+app.use(errorHandler);
+```
+
+In diesem Beispiel kann die generische `logErrors`-Funktion Anforderungs- und Fehlerinformationen in `stderr` schreiben:
+
+```js
+function logErrors(err, req, res, next) {
+ console.error(err.stack);
+ next(err);
+}
+```
+
+In diesem Beispiel wird `clientErrorHandler` wie folgt definiert. In diesem Fall wird der Fehler explizit an den nächsten Error-Handler übergeben:
+
+Notice that when _not_ calling "next" in an error-handling function, you are responsible for writing (and ending) the response. Otherwise, those requests will "hang" and will not be eligible for garbage collection.
+
+```js
+function clientErrorHandler(err, req, res, next) {
+ if (req.xhr) {
+ res.status(500).send({ error: 'Something failed!' });
+ } else {
+ next(err);
+ }
+}
+```
+
+Die `errorHandler`-Funktion "catch-all" kann wie folgt implementiert werden:
+
+```js
+function errorHandler(err, req, res, next) {
+ res.status(500);
+ res.render('error', { error: err });
+}
+```
+
+If you have a route handler with multiple callback functions, you can use the `route` parameter to skip to the next route handler. Beispiel:
+
+```js
+app.get(
+ '/a_route_behind_paywall',
+ (req, res, next) => {
+ if (!req.user.hasPaid) {
+ // continue handling this request
+ next('route');
+ } else {
+ next();
+ }
+ },
+ (req, res, next) => {
+ PaidContent.find((err, doc) => {
+ if (err) return next(err);
+ res.json(doc);
+ });
+ }
+);
+```
+
+In diesem Beispiel wird der Handler `getPaidContent` übersprungen. Alle verbleibenden Handler in `app` für `/a_route_behind_paywall` werden jedoch weiter ausgeführt.
+
+
+Aufrufe zu `next()` und `next(err)` geben an, dass der aktuelle Handler abgeschlossen ist und welchen Status er aufweist. Durch `next(err)` werden alle verbleibenden Handler in der Kette übersprungen. Ausgenommen hiervor sind die Handler, die konfiguriert sind, um Fehler wie oben beschrieben zu behandeln.
+
diff --git a/astro/src/content/docs/de/4x/guide/migrating-4.md b/astro/src/content/docs/de/4x/guide/migrating-4.md
new file mode 100644
index 0000000000..47fad43b6f
--- /dev/null
+++ b/astro/src/content/docs/de/4x/guide/migrating-4.md
@@ -0,0 +1,554 @@
+---
+title: Migration auf Express 4
+description: A guide to migrating your Express.js applications from version 3 to 4, covering changes in middleware, routing, and how to update your codebase effectively.
+---
+
+# Wechsel zu Express 4
+
+Überblick
+
+Express 4 bietet grundlegende Veränderungen im Vergleich zu Express 3. Das bedeutet, dass eine Express 3-Anwendung nicht funktioniert, wenn Sie die Express-Version in ihren Abhängigkeiten aktualisieren.
+
+In diesem Beitrag werden folgende Themen behandelt:
+
+
+
+Änderungen in Express 4
+
+In Express 4 wurden einige signifikante Änderungen vorgenommen:
+
+
+
+Siehe hierzu auch:
+
+- [Neue Features/Funktionen in 4.x.](https://github.com/expressjs/express/wiki/New-features-in-4.x)
+- [Migration von 3.x auf 4.x.](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x)
+
+
+Änderungen am Express-Core- und Middlewaresystem
+
+In Express 4 bestehen keine Abhängigkeiten mehr zu Connect. Alle integrierten Middlewarefunktionen werden aus dem Core entfernt. Ausgenommen hiervon ist die Funktion `express.static`. Das bedeutet, dass Express nun ein unabhängiges Routing- und Middleware-Web-Framework ist und Express-Versionierung und -Releases von Middleware-Updates nicht betroffen sind.
+
+Ohne integrierte Middleware müssen Sie explizit alle Middlewarefunktionen hinzufügen, die für die Ausführung Ihrer Anwendung erforderlich sind. Befolgen Sie einfach diese Schritte:
+
+1. Installieren des Moduls: `npm install --save `
+2. Anfordern des Moduls in Ihrer Anwendung: `require('modulname')`
+3. Verwendung des Moduls gemäß Dokumentation: `app.use( ... )`
+
+In der folgenden Tabelle sind Express 3-Middlewarefunktionen und deren Entsprechungen in Express 4 aufgelistet.
+
+
+
+Hier finden Sie die [komplette Liste](https://github.com/senchalabs/connect#middleware) der Express 4-Middleware.
+
+In den meisten Fällen können Sie einfach nur die Middleware der alten Version 3 durch deren Entsprechung in Express 4 ersetzen. Details hierzu finden Sie in der modulspezifischen Dokumentation in GitHub.
+
+app.use akzeptiert Parameter.
+
+In Version 4 können Sie über einen Variablenparameter den Pfad definieren, in den Middlewarefunktionen geladen werden. Dann können Sie den Wert des Parameters aus dem Routenhandler laden.
+Beispiel:
+
+```js
+app.use('/book/:id', (req, res, next) => {
+ console.log('ID:', req.params.id);
+ next();
+});
+```
+
+
+Das Routingsystem
+
+
+Anwendungen laden nun implizit Routing-Middleware. Sie müssen sich also keine Gedanken mehr über die Reihenfolge machen, in der die Middleware in Bezug auf die `router`-Middleware geladen wird.
+
+Das Routingsystem verfügt jedoch über zwei neue Funktionen, die beim Organisieren Ihrer Weiterleitungen helfen:
+
+{: .doclist }
+
+- Die neue Methode `app.route()` zum Erstellen verkettbarer Routenhandler für einen Weiterleitungspfad
+- Die neue Klasse `express.Router` zum Erstellen modular einbindbarer Routenhandler
+
+Die Methode app.route()
+
+Die neue Methode `app.route()` hilft beim Erstellen verkettbarer Routenhandler für einen Weiterleitungspfad. Da der Pfad an einer einzelnen Position angegeben wird, ist das Erstellen modularer Weiterleitungen hilfreich, da Redundanzen und Schreibfehler reduziert werden. Weitere Informationen zu Weiterleitungen finden Sie in der Dokumentation zu [`Router()`](/en/4x/api#router).
+
+Dies ist ein Beispiel für verkettete Routenhandler, die mit der Funktion `app.route()` definiert werden.
+
+```js
+app
+ .route('/book')
+ .get((req, res) => {
+ res.send('Get a random book');
+ })
+ .post((req, res) => {
+ res.send('Add a book');
+ })
+ .put((req, res) => {
+ res.send('Update the book');
+ });
+```
+
+Die Klasse express.Router
+
+Eine weitere Funktion, die beim Organisieren von Weiterleitungen hilft, ist die neue Klasse `express.Router`. Über diese Klasse können Sie modular einbindbare Routenhandler erstellen. Eine `Router`-Instanz ist ein vollständiges Middleware- und Routingsystem. Aus diesem Grund wird diese Instanz oft auch als "Mini-App" bezeichnet.
+
+Im folgenden Beispiel wird ein Router als Modul erstellt, Middleware in das Modul geladen, es werden Weiterleitungen definiert und das Modul letztendlich in einen Pfad in der Hauptanwendung eingebunden.
+
+Beispiel: Erstellen Sie eine Routerdatei namens `birds.js` mit dem folgenden Inhalt im Anwendungsverzeichnis:
+
+```js
+var express = require('express');
+var router = express.Router();
+
+// middleware specific to this router
+router.use((req, res, next) => {
+ console.log('Time: ', Date.now());
+ next();
+});
+// define the home page route
+router.get('/', (req, res) => {
+ res.send('Birds home page');
+});
+// define the about route
+router.get('/about', (req, res) => {
+ res.send('About birds');
+});
+
+module.exports = router;
+```
+
+Laden Sie dann das Routermodul in die Anwendung:
+
+```js
+var birds = require('./birds');
+
+// ...
+
+app.use('/birds', birds);
+```
+
+Die Anwendung kann nun Anforderungen an die Pfade `/birds` und `/birds/about` bearbeiten und ruft die Middleware `timeLog` auf, die speziell für diese Weiterleitung bestimmt ist.
+
+
+Weitere Änderungen
+
+In der folgenden Tabelle sind andere kleinere, aber trotzdem wichtige Änderungen in Express 4 aufgeführt:
+
+
+
+Objekt
+Beschreibung
+
+
+Node.js
+
+Express 4 erfordert Node.js 0.10.x oder höher und unterstützt nicht mehr Node.js 0.8.x.
+
+
+
+
+`http.createServer()`
+
+
+Das Modul `http` wird nicht mehr benötigt, es sei denn, Sie müssen direkt mit dem Modul arbeiten (socket.io/SPDY/HTTPS). Die Anwendung kann mithilfe der Funktion `app.listen()` gestartet werden.
+
+
+
+
+`app.configure()`
+
+
+Die Funktion `app.configure()` wurde entfernt. Verwenden Sie die Funktion `process.env.NODE_ENV` oder `app.get('env')`, um die Umgebung zu erkennen und die Anwendung entsprechend zu konfigurieren.
+
+
+
+
+`json spaces`
+
+
+Die Anwendungseigenschaft `json spaces` ist in Express 4 standardmäßig inaktiviert.
+
+
+
+
+`req.accepted()`
+
+
+Verwenden Sie `req.accepts()`, `req.acceptsEncodings()`, `req.acceptsCharsets()` und `req.acceptsLanguages()`.
+
+
+
+
+`res.location()`
+
+
+Löst keine relativen URLs mehr auf.
+
+
+
+
+`req.params`
+
+
+War bisher ein Array, ist nun ein Objekt.
+
+
+
+
+`res.locals`
+
+
+War bisher eine Funktion, ist nun ein Objekt.
+
+
+
+
+`res.headerSent`
+
+
+Geändert in `res.headersSent`.
+
+
+
+
+`app.route`
+
+
+Nun verfügbar als `app.mountpath`.
+
+
+
+
+`res.on('header')`
+
+
+Entfernt.
+
+
+
+
+`res.charset`
+
+
+Entfernt.
+
+
+
+
+`res.setHeader('Set-Cookie', val)`
+
+
+Die Funktionalität ist nun auf die Einstellung des Basis-Cookiewerts begrenzt. Verwenden Sie `res.cookie()`, um weitere Funktionalität zu erhalten.
+
+
+
+
+Beispiel für eine Anwendungsmigration
+
+Dies ist ein Beispiel für die Migration einer Express 3-Anwendung auf Express 4.
+Die dabei interessanten Dateien sind `app.js` und `package.json`.
+
+
+Anwendung der Version 3
+
+
+app.js
+
+Es wird eine Express v.3-Anwendung mit der folgenden Datei `app.js` angenommen:
+
+```js
+var express = require('express');
+var routes = require('./routes');
+var user = require('./routes/user');
+var http = require('http');
+var path = require('path');
+
+var app = express();
+
+// all environments
+app.set('port', process.env.PORT || 3000);
+app.set('views', path.join(__dirname, 'views'));
+app.set('view engine', 'pug');
+app.use(express.favicon());
+app.use(express.logger('dev'));
+app.use(express.methodOverride());
+app.use(express.session({ secret: 'your secret here' }));
+app.use(express.bodyParser());
+app.use(app.router);
+app.use(express.static(path.join(__dirname, 'public')));
+
+// development only
+if (app.get('env') === 'development') {
+ app.use(express.errorHandler());
+}
+
+app.get('/', routes.index);
+app.get('/users', user.list);
+
+http.createServer(app).listen(app.get('port'), () => {
+ console.log('Express server listening on port ' + app.get('port'));
+});
+```
+
+package.json
+
+Die zugehörige `package.json`-Datei der Version 3 sieht in etwa wie folgt aus:
+
+```json
+{
+ "name": "application-name",
+ "version": "0.0.1",
+ "private": true,
+ "scripts": {
+ "start": "node app.js"
+ },
+ "dependencies": {
+ "express": "3.12.0",
+ "pug": "*"
+ }
+}
+```
+
+
+Prozess
+
+
+Beginnen Sie den Migrationsprozess mit der Installation der erforderlichen Middleware für die Express 4-Anwendung und der Aktualisierung von Express und Pug auf die aktuellen Versionen. Verwenden Sie hierzu den folgenden Befehl:
+
+```bash
+$ npm install serve-favicon morgan method-override express-session body-parser multer errorhandler express@latest pug@latest --save
+```
+
+Nehmen Sie an `app.js` die folgenden Änderungen vor:
+
+1. Die integrierten Express-Middlewarefunktionen `express.favicon`,
+ `express.logger`, `express.methodOverride`,
+ `express.session`, `express.bodyParser` und
+ `express.errorHandler` sind im Objekt `express` nicht mehr verfügbar. Sie müssen deren Alternativen manuell installieren und in die Anwendung laden.
+
+2. Sie müssen die Funktion `app.router` nicht mehr laden.
+ Sie ist kein gültiges Express 4-Anwendungsobjekt. Entfernen Sie also den Code `app.use(app.router);`.
+
+3. Stellen Sie sicher, dass die Middlewarefunktionen in der richtigen Reihenfolge geladen werden – laden Sie `errorHandler` nach dem Laden der Anwendungsweiterleitungen.
+
+Anwendung der Version 4
+
+package.json
+
+Durch Ausführung des Befehls `npm` wird `package.json` wie folgt aktualisiert:
+
+```json
+{
+ "name": "application-name",
+ "version": "0.0.1",
+ "private": true,
+ "scripts": {
+ "start": "node app.js"
+ },
+ "dependencies": {
+ "body-parser": "^1.5.2",
+ "errorhandler": "^1.1.1",
+ "express": "^4.8.0",
+ "express-session": "^1.7.2",
+ "pug": "^2.0.0",
+ "method-override": "^2.1.2",
+ "morgan": "^1.2.2",
+ "multer": "^0.1.3",
+ "serve-favicon": "^2.0.1"
+ }
+}
+```
+
+app.js
+
+Entfernen Sie dann ungültigen Code, laden Sie die erforderliche Middleware und nehmen Sie andere Änderungen nach Bedarf vor. Die Datei `app.js` sieht dann wie folgt aus:
+
+```js
+var http = require('http');
+var express = require('express');
+var routes = require('./routes');
+var user = require('./routes/user');
+var path = require('path');
+
+var favicon = require('serve-favicon');
+var logger = require('morgan');
+var methodOverride = require('method-override');
+var session = require('express-session');
+var bodyParser = require('body-parser');
+var multer = require('multer');
+var errorHandler = require('errorhandler');
+
+var app = express();
+
+// all environments
+app.set('port', process.env.PORT || 3000);
+app.set('views', path.join(__dirname, 'views'));
+app.set('view engine', 'pug');
+app.use(favicon(path.join(__dirname, '/public/favicon.ico')));
+app.use(logger('dev'));
+app.use(methodOverride());
+app.use(
+ session({
+ resave: true,
+ saveUninitialized: true,
+ secret: 'uwotm8',
+ })
+);
+app.use(bodyParser.json());
+app.use(bodyParser.urlencoded({ extended: true }));
+app.use(multer());
+app.use(express.static(path.join(__dirname, 'public')));
+
+app.get('/', routes.index);
+app.get('/users', user.list);
+
+// error handling middleware should be loaded after the loading the routes
+if (app.get('env') === 'development') {
+ app.use(errorHandler());
+}
+
+var server = http.createServer(app);
+server.listen(app.get('port'), () => {
+ console.log('Express server listening on port ' + app.get('port'));
+});
+```
+
+Wenn Sie nicht direkt mit dem Modul `http` arbeiten müssen (socket.io/SPDY/HTTPS), ist das Laden des Moduls nicht erforderlich. Die Anwendung kann dann einfach wie folgt gestartet werden:
+
+```js
+app.listen(app.get('port'), () => {
+ console.log('Express server listening on port ' + app.get('port'));
+});
+```
+
+
+
+Anwendung ausführen
+
+Der Migrationsprozess ist abgeschlossen und die Anwendung ist nun eine Express 4-Anwendung. Zum Bestätigen starten Sie die Anwendung mit dem folgenden Befehl:
+
+```bash
+$ node .
+```
+
+Laden Sie [http://localhost:3000](http://localhost:3000) und sehen Sie, wie die Homepage von Express 4 wiedergegeben wird.
+
+Upgrade auf den Express 4 App Generator
+
+Das Befehlszeilentool zum Generieren einer Express-Anwendung ist nach wie vor `express`. Für ein Upgrade auf die neue Version müssen Sie jedoch den Express 3 App Generator deinstallieren und dann den neuen Generator `express-generator` installieren.
+
+Installation
+
+Wenn der Express 3 App Generator bereits auf Ihrem System installiert ist, müssen Sie diesen deinstallieren:
+
+```bash
+$ npm uninstall -g express
+```
+
+Abhängig davon, wie Ihre Datei- und Verzeichnissberechtigungen konfiguriert sind, müssen Sie diesen Befehl möglicherweise mit `sudo` ausführen.
+
+Installieren Sie nun den neuen Generator:
+
+```bash
+$ npm install -g express-generator
+```
+
+Abhängig davon, wie Ihre Datei- und Verzeichnissberechtigungen konfiguriert sind, müssen Sie diesen Befehl möglicherweise mit `sudo` ausführen.
+
+Nun wird der Befehl `express` auf Ihrem System auf den Express 4 App Generator aktualisiert.
+
+Änderungen am App Generator
+
+Befehlsoptionen und -nutzung bleiben größtenteils unverändert. Es gelten jedoch folgende Ausnahmen:
+
+{: .doclist }
+
+- Option `--sessions` wurde entfernt.
+- Option `--jshtml` wurde entfernt.
+- Option `--hogan` wurde hinzugefügt, um [Hogan.js](http://twitter.github.io/hogan.js/) zu unterstützen.
+
+Beispiel
+
+Führen Sie den folgenden Befehl aus, um eine Express 4-Anwendung zu erstellen:
+
+```bash
+$ express app4
+```
+
+Wenn Sie sich den Inhalt der Datei `app4/app.js` ansehen, werden Sie feststellen, dass alle Middlewarefunktionen (außer `express.static`), die für die Anwendung erforderlich sind, als unabhängige Module geladen werden und die Middleware `router` nicht mehr explizit in die Anwendung geladen wird.
+
+Sie werden auch feststellen, dass die Datei `app.js` nun ein Node.js-Modul ist – im Gegensatz zur eigenständigen Anwendung, die vom bisherigen Generator generiert wurde.
+
+Starten Sie nach der Installation der Abhängigkeiten die Anwendung mit dem folgenden Befehl:
+
+```bash
+$ npm start
+```
+
+Wenn Sie sich das npm-Startscript in der Datei `package.json` näher ansehen, werden Sie feststellen, dass der eigentliche Befehl, der die Anwendung startet, `node ./bin/www` heißt. Dieser Befehl lautete in Express 3 `node app.js`.
+
+Da die Datei `app.js`, die vom Express 4 Generator erstellt wurde, nun ein Node.js-Modul ist, kann dieses nicht mehr wie bisher unabhängig als Anwendung gestartet werden (es sei denn, Sie ändern den Code). Das Modul muss in eine Node.js-Datei geladen und über die Node.js-Datei gestartet werden. Die Node.js-Datei ist in diesem Fall `./bin/www`.
+
+Weder das Verzeichnis `bin` noch die erweiterungslose Datei `www` ist für das Erstellen einer Express-Anwendung oder das Starten der Anwendung zwingend erforderlich. Dies sind lediglich Vorschläge des Generators. Sie können diese also je nach Ihren Anforderungen ändern.
+
+Um das Verzeichnis `www` zu löschen und alles im "Express 3-Stil" zu belassen, löschen Sie die Zeile mit dem Eintrag `module.exports = app;` am Ende der Datei `app.js`. Fügen Sie dann stattdessen den folgenden Code an derselben Position ein:
+
+```js
+app.set('port', process.env.PORT || 3000);
+
+var server = app.listen(app.get('port'), () => {
+ debug('Express server listening on port ' + server.address().port);
+});
+```
+
+Stellen Sie sicher, dass Sie das Modul `debug` am Anfang der Datei `app.js` laden. Verwenden Sie dazu den folgenden Code:
+
+```js
+var debug = require('debug')('app4');
+```
+
+Ändern Sie als Nächstes `"start": "node ./bin/www"` in der Datei `package.json` in `"start": "node app.js"`.
+
+Sie haben nun die Funktionalität von `./bin/www` wieder in `app.js` verschoben. Diese Änderung wird nicht empfohlen. Die Übung hat Ihnen jedoch geholfen, zu verstehen, wie die Datei `./bin/www` funktioniert und warum die Datei `app.js` nicht mehr automatisch gestartet wird.
diff --git a/de/guide/migrating-5.md b/astro/src/content/docs/de/4x/guide/migrating-5.md
similarity index 90%
rename from de/guide/migrating-5.md
rename to astro/src/content/docs/de/4x/guide/migrating-5.md
index 2b2e8f031f..1d1d033413 100644
--- a/de/guide/migrating-5.md
+++ b/astro/src/content/docs/de/4x/guide/migrating-5.md
@@ -1,10 +1,6 @@
---
-layout: page
title: Migration auf Express 5
description: A comprehensive guide to migrating your Express.js applications from version 4 to 5, detailing breaking changes, deprecated methods, and new improvements.
-menu: guide
-order: 10
-redirect_from: " "
---
# Wechsel zu Express 5
@@ -99,7 +95,7 @@ Anfänglich wurde `del` statt `delete` verwendet, weil `delete` in JavaScript ei
{% capture codemod-deprecated-signatures %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod v4-deprecated-signatures
```
@@ -110,13 +106,13 @@ npx @expressjs/codemod v4-deprecated-signatures
```js
// v4
app.del('/user/:id', (req, res) => {
- res.send(`DELETE /user/${req.params.id}`)
-})
+ res.send(`DELETE /user/${req.params.id}`);
+});
// v5
app.delete('/user/:id', (req, res) => {
- res.send(`DELETE /user/${req.params.id}`)
-})
+ res.send(`DELETE /user/${req.params.id}`);
+});
```
app.param(fn)
@@ -136,7 +132,7 @@ Die folgenden Methodennamen wurden pluralisiert. In Express 4 wurde bei Verwendu
{% capture codemod-pluralized-methods %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod pluralized-methods
```
@@ -147,28 +143,28 @@ npx @expressjs/codemod pluralized-methods
```js
// v4
app.all('/', (req, res) => {
- req.acceptsCharset('utf-8')
- req.acceptsEncoding('br')
- req.acceptsLanguage('en')
+ req.acceptsCharset('utf-8');
+ req.acceptsEncoding('br');
+ req.acceptsLanguage('en');
// ...
-})
+});
// v5
app.all('/', (req, res) => {
- req.acceptsCharsets('utf-8')
- req.acceptsEncodings('br')
- req.acceptsLanguages('en')
+ req.acceptsCharsets('utf-8');
+ req.acceptsEncodings('br');
+ req.acceptsLanguages('en');
// ...
-})
+});
```
Führender Doppelpunkt (:) im Namen für app.param(name, fn)
Ein führendes Doppelpunktzeichen (:) im Namen für die Funktion `app.param(name, fn)` ist ein Überbleibsel aus Express 3. Aus Gründen der Abwärtskompatibilität wurde dieser Name in Express 4 mit einem Hinweis zu veralteten Versionen weiter unterstützt. In Express 5 wird dieser Name stillschwiegend ignoriert und der Namensparameter ohne einen vorangestellten Doppelpunkt verwendet.
-Dies dürfte keine Auswirkungen auf Ihren Code haben, wenn Sie die Express 4-Dokumentation zu [app.param](/{{ page.lang }}/4x/api.html#app.param) befolgen, da dort der führende Doppelpunkt nicht erwähnt wird.
+Dies dürfte keine Auswirkungen auf Ihren Code haben, wenn Sie die Express 4-Dokumentation zu [app.param](/en/4x/api#app.param) befolgen, da dort der führende Doppelpunkt nicht erwähnt wird.
req.param(name)
@@ -177,7 +173,7 @@ Dieses potenziell verwirrende und durchaus riskante Verfahren des Abrufens von F
{% capture codemod-req-param %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod req-param
```
@@ -188,75 +184,75 @@ npx @expressjs/codemod req-param
```js
// v4
app.post('/user', (req, res) => {
- const id = req.param('id')
- const body = req.param('body')
- const query = req.param('query')
+ const id = req.param('id');
+ const body = req.param('body');
+ const query = req.param('query');
// ...
-})
+});
// v5
app.post('/user', (req, res) => {
- const id = req.params.id
- const body = req.body
- const query = req.query
+ const id = req.params.id;
+ const body = req.body;
+ const query = req.query;
// ...
-})
+});
```
res.json(obj, status)
-Express 5 unterstützt die Signatur `res.json(obj, status)` nicht mehr. Stattdessen müssen Sie den Status festlegen und diesen dann mit `res.json()`-Methoden wie dieser verketten: `res.status(status).json(obj)`.
+Express 5 unterstützt die Signatur `res.json(obj, status)` nicht mehr. Stattdessen müssen Sie den Status festlegen und diesen dann mit `res.json()`-Methoden wie dieser verketten: `res.status(status).json(obj)`.
{% include admonitions/note.html content=codemod-deprecated-signatures %}
```js
// v4
app.post('/user', (req, res) => {
- res.json({ name: 'Ruben' }, 201)
-})
+ res.json({ name: 'Ruben' }, 201);
+});
// v5
app.post('/user', (req, res) => {
- res.status(201).json({ name: 'Ruben' })
-})
+ res.status(201).json({ name: 'Ruben' });
+});
```
res.jsonp(obj, status)
-Express 5 unterstützt die Signatur `res.jsonp(obj, status)` nicht mehr. Stattdessen müssen Sie den Status festlegen und diesen dann mit `res.jsonp()`-Methoden wie dieser verketten: `res.status(status).jsonp(obj)`.
+Express 5 unterstützt die Signatur `res.jsonp(obj, status)` nicht mehr. Stattdessen müssen Sie den Status festlegen und diesen dann mit `res.jsonp()`-Methoden wie dieser verketten: `res.status(status).jsonp(obj)`.
{% include admonitions/note.html content=codemod-deprecated-signatures %}
```js
// v4
app.post('/user', (req, res) => {
- res.jsonp({ name: 'Ruben' }, 201)
-})
+ res.jsonp({ name: 'Ruben' }, 201);
+});
// v5
app.post('/user', (req, res) => {
- res.status(201).jsonp({ name: 'Ruben' })
-})
+ res.status(201).jsonp({ name: 'Ruben' });
+});
```
res.redirect(url, status)
-Express 5 unterstützt die Signatur `res.send(obj, status)` nicht mehr. Stattdessen müssen Sie den Status festlegen und diesen dann mit `res.send()`-Methoden wie dieser verketten: `res.status(status).send(obj)`.
+Express 5 unterstützt die Signatur `res.send(obj, status)` nicht mehr. Stattdessen müssen Sie den Status festlegen und diesen dann mit `res.send()`-Methoden wie dieser verketten: `res.status(status).send(obj)`.
{% include admonitions/note.html content=codemod-deprecated-signatures %}
```js
// v4
app.get('/user', (req, res) => {
- res.redirect('/users', 301)
-})
+ res.redirect('/users', 301);
+});
// v5
app.get('/user', (req, res) => {
- res.redirect(301, '/users')
-})
+ res.redirect(301, '/users');
+});
```
res.redirect('back') and res.location('back')
@@ -266,7 +262,7 @@ Express 5 no longer supports the magic string `back` in the `res.redirect()` and
{% capture codemod-magic-redirect %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod magic-redirect
```
@@ -277,13 +273,13 @@ npx @expressjs/codemod magic-redirect
```js
// v4
app.get('/user', (req, res) => {
- res.redirect('back')
-})
+ res.redirect('back');
+});
// v5
app.get('/user', (req, res) => {
- res.redirect(req.get('Referrer') || '/')
-})
+ res.redirect(req.get('Referrer') || '/');
+});
```
res.send(body, status)
@@ -295,13 +291,13 @@ Express 5 no longer supports the signature `res.send(obj, status)`. Instead, set
```js
// v4
app.get('/user', (req, res) => {
- res.send({ name: 'Ruben' }, 200)
-})
+ res.send({ name: 'Ruben' }, 200);
+});
// v5
app.get('/user', (req, res) => {
- res.status(200).send({ name: 'Ruben' })
-})
+ res.status(200).send({ name: 'Ruben' });
+});
```
res.send(status)
@@ -314,13 +310,13 @@ Wenn Sie eine Zahl senden und hierfür die Funktion `res.send()` verwenden müss
```js
// v4
app.get('/user', (req, res) => {
- res.send(200)
-})
+ res.send(200);
+});
// v5
app.get('/user', (req, res) => {
- res.sendStatus(200)
-})
+ res.sendStatus(200);
+});
```
res.sendfile()
@@ -341,13 +337,13 @@ Die Funktion `res.sendfile()` wurde durch eine Version in Camel-Schreibweise von
```js
// v4
app.get('/user', (req, res) => {
- res.sendfile('/path/to/file')
-})
+ res.sendfile('/path/to/file');
+});
// v5
app.get('/user', (req, res) => {
- res.sendFile('/path/to/file')
-})
+ res.sendFile('/path/to/file');
+});
```
router.param(fn)
@@ -364,17 +360,17 @@ Use the [`mime-types` package](https://github.com/jshttp/mime-types) to work wit
- JavaScript files (.js): now served as "text/javascript" instead of "application/javascript"
- JSON files (.json): now served as "application/json" instead of "text/json"
- CSS files (.css): now served as "text/css" instead of "text/plain"
-- HTML files (.html): now served as "text/html; charset=utf-8" instead of just "text/html"
+- HTML files (): now served as "text/html; charset=utf-8" instead of just "text/html"
- XML files (.xml): now served as "application/xml" instead of "text/xml"
- Font files (.woff): now served as "font/woff" instead of "application/font-woff"
```js
// v4
-express.static.mime.lookup('json')
+express.static.mime.lookup('json');
// v5
-const mime = require('mime-types')
-mime.lookup('json')
+const mime = require('mime-types');
+mime.lookup('json');
```
express:router debug logs
@@ -407,13 +403,13 @@ Path route matching syntax is when a string is supplied as the first parameter t
```js
// v4
app.get('/*', async (req, res) => {
- res.send('ok')
-})
+ res.send('ok');
+});
// v5
app.get('/*splat', async (req, res) => {
- res.send('ok')
-})
+ res.send('ok');
+});
```
{% capture note_wildcard %}
@@ -422,8 +418,8 @@ app.get('/*splat', async (req, res) => {
```js
// v5
app.get('/{*splat}', async (req, res) => {
- res.send('ok')
-})
+ res.send('ok');
+});
```
{% endcapture %}
@@ -434,29 +430,29 @@ app.get('/{*splat}', async (req, res) => {
```js
// v4
app.get('/:file.:ext?', async (req, res) => {
- res.send('ok')
-})
+ res.send('ok');
+});
// v5
app.get('/:file{.:ext}', async (req, res) => {
- res.send('ok')
-})
+ res.send('ok');
+});
```
- Regexp characters are not supported. Beispiel:
```js
app.get('/[discussion|page]/:slug', async (req, res) => {
- res.status(200).send('ok')
-})
+ res.status(200).send('ok');
+});
```
should be changed to:
```js
app.get(['/discussion/:slug', '/page/:slug'], async (req, res) => {
- res.status(200).send('ok')
-})
+ res.status(200).send('ok');
+});
```
- Some characters have been reserved to avoid confusion during upgrade (`()[]?+!`), use `\` to escape them.
@@ -466,7 +462,7 @@ app.get(['/discussion/:slug', '/page/:slug'], async (req, res) => {
Request middleware and handlers that return rejected promises are now handled by forwarding the rejected value as an `Error` to the error handling middleware. This means that using `async` functions as middleware and handlers are easier than ever. When an error is thrown in an `async` function or a rejected promise is `await`ed inside an async function, those errors will be passed to the error handler as if calling `next(err)`.
-Details of how Express handles errors is covered in the [error handling documentation](/en/guide/error-handling.html).
+Details of how Express handles errors is covered in the [error handling documentation](/en/guide/error-handling).
express.urlencoded
@@ -480,7 +476,7 @@ Example of breaking code:
```js
// v4
-app.use(express.static('public'))
+app.use(express.static('public'));
```
After migrating to Express 5, a request to `/.well-known/assetlinks.json` will result in a **404 Not Found**.
@@ -489,8 +485,8 @@ To fix this, serve specific dot-directories explicitly using the `dotfiles: "all
```js
// v5
-app.use('/.well-known', express.static('public/.well-known', { dotfiles: 'allow' }))
-app.use(express.static('public'))
+app.use('/.well-known', express.static('public/.well-known', { dotfiles: 'allow' }));
+app.use(express.static('public'));
```
This approach allows you to safely serve only the intended dot-directories while keeping the default secure behavior for other dotfiles, which remain inaccessible.
@@ -503,10 +499,10 @@ Beispiel:
```js
const server = app.listen(8080, '0.0.0.0', (error) => {
if (error) {
- throw error // e.g. EADDRINUSE
+ throw error; // e.g. EADDRINUSE
}
- console.log(`Listening on ${JSON.stringify(server.address())}`)
-})
+ console.log(`Listening on ${JSON.stringify(server.address())}`);
+});
```
app.router
@@ -532,9 +528,9 @@ Wildcards (e.g., `/*splat`) capture path segments as an array instead of a singl
```js
app.get('/*splat', (req, res) => {
// GET /foo/bar
- console.dir(req.params)
+ console.dir(req.params);
// => [Object: null prototype] { splat: [ 'foo', 'bar' ] }
-})
+});
```
**Unmatched parameters are omitted:**
@@ -545,23 +541,23 @@ In Express 4, unmatched wildcards were empty strings (`''`) and optional `:` par
// v4: unmatched wildcard is empty string
app.get('/*', (req, res) => {
// GET /
- console.dir(req.params)
+ console.dir(req.params);
// => { '0': '' }
-})
+});
// v4: unmatched optional param is undefined
app.get('/:file.:ext?', (req, res) => {
// GET /image
- console.dir(req.params)
+ console.dir(req.params);
// => { file: 'image', ext: undefined }
-})
+});
// v5: unmatched optional param is omitted
app.get('/:file{.:ext}', (req, res) => {
// GET /image
- console.dir(req.params)
+ console.dir(req.params);
// => [Object: null prototype] { file: 'image' }
-})
+});
```
req.query
diff --git a/astro/src/content/docs/de/4x/guide/overriding-express-api.md b/astro/src/content/docs/de/4x/guide/overriding-express-api.md
new file mode 100644
index 0000000000..8f78a06422
--- /dev/null
+++ b/astro/src/content/docs/de/4x/guide/overriding-express-api.md
@@ -0,0 +1,70 @@
+---
+title: Overriding the Express API
+description: Discover how to customize and extend the Express.js API by overriding methods and properties on the request and response objects using prototypes.
+---
+
+# Overriding the Express API
+
+The Express API consists of various methods and properties on the request and response objects. These are inherited by prototype. There are two extension points for the Express API:
+
+1. The global prototypes at `express.request` and `express.response`.
+2. App-specific prototypes at `app.request` and `app.response`.
+
+Altering the global prototypes will affect all loaded Express apps in the same process. If desired, alterations can be made app-specific by only altering the app-specific prototypes after creating a new app.
+
+## Methods
+
+You can override the signature and behavior of existing methods with your own, by assigning a custom function.
+
+Following is an example of overriding the behavior of [res.sendStatus](/en/4x/api#res.sendStatus).
+
+```js
+app.response.sendStatus = function (statusCode, type, message) {
+ // code is intentionally kept simple for demonstration purpose
+ return this.contentType(type).status(statusCode).send(message);
+};
+```
+
+The above implementation completely changes the original signature of `res.sendStatus`. It now accepts a status code, encoding type, and the message to be sent to the client.
+
+The overridden method may now be used this way:
+
+```js
+res.sendStatus(404, 'application/json', '{"error":"resource not found"}');
+```
+
+## Properties
+
+Properties in the Express API are either:
+
+1. Assigned properties (ex: `req.baseUrl`, `req.originalUrl`)
+2. Defined as getters (ex: `req.secure`, `req.ip`)
+
+Since properties under category 1 are dynamically assigned on the `request` and `response` objects in the context of the current request-response cycle, their behavior cannot be overridden.
+
+Properties under category 2 can be overwritten using the Express API extensions API.
+
+The following code rewrites how the value of `req.ip` is to be derived. Now, it simply returns the value of the `Client-IP` request header.
+
+```js
+Object.defineProperty(app.request, 'ip', {
+ configurable: true,
+ enumerable: true,
+ get() {
+ return this.get('Client-IP');
+ },
+});
+```
+
+## Prototype
+
+In order to provide the Express API, the request/response objects passed to Express (via `app(req, res)`, for example) need to inherit from the same prototype chain. By default, this is `http.IncomingRequest.prototype` for the request and `http.ServerResponse.prototype` for the response.
+
+Unless necessary, it is recommended that this be done only at the application level, rather than globally. Also, take care that the prototype that is being used matches the functionality as closely as possible to the default prototypes.
+
+```js
+// Use FakeRequest and FakeResponse in place of http.IncomingRequest and http.ServerResponse
+// for the given app reference
+Object.setPrototypeOf(Object.getPrototypeOf(app.request), FakeRequest.prototype);
+Object.setPrototypeOf(Object.getPrototypeOf(app.response), FakeResponse.prototype);
+```
diff --git a/astro/src/content/docs/de/4x/guide/routing.md b/astro/src/content/docs/de/4x/guide/routing.md
new file mode 100644
index 0000000000..5e5c52fbae
--- /dev/null
+++ b/astro/src/content/docs/de/4x/guide/routing.md
@@ -0,0 +1,417 @@
+---
+title: Weiterleitung in Express
+description: Learn how to define and use routes in Express.js applications, including route methods, route paths, parameters, and using Router for modular routing.
+---
+
+# Weiterleitung (Routing)
+
+Der Begriff _Weiterleitung_ (Routing) bezieht sich auf die Definition von Anwendungsendpunkten (URIs) und deren Antworten auf Clientanforderungen.
+Eine Einführung in dieses Routing siehe [Basisrouting](/en/starter/basic-routing).
+
+You define routing using methods of the Express `app` object that correspond to HTTP methods;
+for example, `app.get()` to handle GET requests and `app.post` to handle POST requests. For a full list,
+see [app.METHOD](/en/5x/api#app.METHOD). You can also use [app.all()](/en/5x/api#app.all) to handle all HTTP methods and [app.use()](/en/5x/api#app.use) to
+specify middleware as the callback function (See [Using middleware](/en/guide/using-middleware) for details).
+
+These routing methods specify a callback function (sometimes called "handler functions") called when the application receives a request to the specified route (endpoint) and HTTP method. In other words, the application "listens" for requests that match the specified route(s) and method(s), and when it detects a match, it calls the specified callback function.
+
+In fact, the routing methods can have more than one callback function as arguments.
+With multiple callback functions, it is important to provide `next` as an argument to the callback function and then call `next()` within the body of the function to hand off control
+to the next callback.
+
+Der folgende Code ist ein Beispiel für ein sehr einfaches Basisrouting.
+
+```js
+const express = require('express');
+const app = express();
+
+// respond with "hello world" when a GET request is made to the homepage
+app.get('/', (req, res) => {
+ res.send('hello world');
+});
+```
+
+Weiterleitungsmethoden
+
+Eine Weiterleitungsmethode wird von einer HTTP-Methode abgeleitet und an eine Instanz der Klasse `express` angehängt.
+
+Der folgende Code ist ein Beispiel für Weiterleitungen, die für die Methoden GET und POST zum Stamm (Root) der Anwendung definiert werden.
+
+```js
+// GET method route
+app.get('/', (req, res) => {
+ res.send('GET request to the homepage');
+});
+
+// POST method route
+app.post('/', (req, res) => {
+ res.send('POST request to the homepage');
+});
+```
+
+Express supports methods that correspond to all HTTP request methods: `get`, `post`, and so on.
+For a full list, see [app.METHOD](/en/5x/api#app.METHOD).
+
+Es gibt eine spezielle Weiterleitungsmethode, `app.all()`, die nicht von einer HTTP-Methode abgeleitet wird. Diese Methode wird zum Laden von Middlewarefunktionen bei einem Pfad für alle Anforderungsmethoden verwendet. Im folgenden Beispiel wird der Handler für Anforderungen zur Weiterleitung "/secret" ausgeführt, um herauszufinden, ob Sie GET-, POST-, PUT-, DELETE- oder andere HTTP-Anforderungsmethoden verwenden, die im [HTTP-Modul](https://nodejs.org/api/http.html#http_http_methods) unterstützt werden.
+
+```js
+app.all('/secret', (req, res, next) => {
+ console.log('Accessing the secret section ...');
+ next(); // pass control to the next handler
+});
+```
+
+Weiterleitungspfade
+
+Über Weiterleitungspfade werden in Kombination mit einer Anforderungsmethode die Endpunkte definiert, bei denen Anforderungen erfolgen können. Weiterleitungspfade können Zeichenfolgen, Zeichenfolgemuster oder reguläre Ausdrücke sein.
+
+{% capture caution-character %} In express 5, the characters `?`, `+`, `*`, `[]`, and `()` are handled differently than in version 4, please review the [migration guide](/en/guide/migrating-5#path-syntax) for more information.{% endcapture %}
+
+{% include admonitions/caution.html content=caution-character %}
+
+{% capture note-dollar-character %}In express 4, regular expression characters such as `$` need to be escaped with a `\`.
+{% endcapture %}
+
+{% include admonitions/caution.html content=note-dollar-character %}
+
+{% capture note-path-to-regexp %}
+
+Express uses [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) for matching the route paths; see the path-to-regexp documentation for all the possibilities in defining route paths. [Express Route Tester](http://forbeslindesay.github.io/express-route-tester/) ist ein handliches Tool zum Testen von Express-Basisweiterleitungen, auch wenn dieses Tool keine Musterabgleiche unterstützt.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=note-path-to-regexp %}
+
+{% capture query-string-note %}
+
+Query strings are not part of the route path.
+
+{% endcapture %}
+
+{% include admonitions/warning.html content=query-string-note %}
+
+### Route paths based on strings
+
+Dieser Weiterleitungspfad gleicht Weiterleitungsanforderungen zum Stammverzeichnis (`/`) ab.
+
+```js
+app.get('/', (req, res) => {
+ res.send('root');
+});
+```
+
+Dieser Weiterleitungspfad gleicht Anforderungen mit `/about` ab.
+
+```js
+app.get('/about', (req, res) => {
+ res.send('about');
+});
+```
+
+Dieser Weiterleitungspfad gleicht Anforderungen mit `/random.text` ab.
+
+```js
+app.get('/random.text', (req, res) => {
+ res.send('random.text');
+});
+```
+
+### Route paths based on string patterns
+
+{% capture caution-string-patterns %} The string patterns in Express 5 no longer work. Please refer to the [migration guide](/en/guide/migrating-5#path-syntax) for more information.{% endcapture %}
+
+{% include admonitions/caution.html content=caution-string-patterns %}
+
+Dieser Weiterleitungspfad gleicht `acd` und `abcd` ab.
+
+```js
+app.get('/ab?cd', (req, res) => {
+ res.send('ab?cd');
+});
+```
+
+Dies sind einige Beispiele für Weiterleitungspfade auf Basis von Zeichenfolgemustern.
+
+```js
+app.get('/ab+cd', (req, res) => {
+ res.send('ab+cd');
+});
+```
+
+Dies sind einige Beispiele für Weiterleitungspfade auf Basis von Zeichenfolgen.
+
+```js
+app.get('/ab*cd', (req, res) => {
+ res.send('ab*cd');
+});
+```
+
+Dieser Weiterleitungspfad gleicht `/abe` und `/abcde` ab.
+
+```js
+app.get('/ab(cd)?e', (req, res) => {
+ res.send('ab(cd)?e');
+});
+```
+
+### Route paths based on regular expressions
+
+Dieser Weiterleitungspfad gleicht alle Weiterleitungsnamen ab, die den Buchstaben "a" enthalten.
+
+```js
+app.get(/a/, (req, res) => {
+ res.send('/a/');
+});
+```
+
+Dieser Weiterleitungspfad gleicht `butterfly` und `dragonfly`, jedoch nicht `butterflyman`, `dragonfly man` usw.
+
+```js
+app.get(/.*fly$/, (req, res) => {
+ res.send('/.*fly$/');
+});
+```
+
+Route parameters
+
+Route parameters are named URL segments that are used to capture the values specified at their position in the URL. The captured values are populated in the `req.params` object, with the name of the route parameter specified in the path as their respective keys.
+
+```
+Route path: /users/:userId/books/:bookId
+Request URL: http://localhost:3000/users/34/books/8989
+req.params: { "userId": "34", "bookId": "8989" }
+```
+
+To define routes with route parameters, simply specify the route parameters in the path of the route as shown below.
+
+```js
+app.get('/users/:userId/books/:bookId', (req, res) => {
+ res.send(req.params);
+});
+```
+
+
+The name of route parameters must be made up of "word characters" ([A-Za-z0-9_]).
+
+
+Since the hyphen (`-`) and the dot (`.`) are interpreted literally, they can be used along with route parameters for useful purposes.
+
+```
+Route path: /flights/:from-:to
+Request URL: http://localhost:3000/flights/LAX-SFO
+req.params: { "from": "LAX", "to": "SFO" }
+```
+
+```
+Route path: /plantae/:genus.:species
+Request URL: http://localhost:3000/plantae/Prunus.persica
+req.params: { "genus": "Prunus", "species": "persica" }
+```
+
+{% capture warning-regexp %}
+In express 5, Regexp characters are not supported in route paths, for more information please refer to the [migration guide](/en/guide/migrating-5#path-syntax).{% endcapture %}
+
+{% include admonitions/caution.html content=warning-regexp %}
+
+To have more control over the exact string that can be matched by a route parameter, you can append a regular expression in parentheses (`()`):
+
+```
+Route path: /user/:userId(\d+)
+Request URL: http://localhost:3000/user/42
+req.params: {"userId": "42"}
+```
+
+{% capture escape-advisory %}
+
+Because the regular expression is usually part of a literal string, be sure to escape any `\` characters with an additional backslash, for example `\\d+`.
+
+{% endcapture %}
+
+{% include admonitions/warning.html content=escape-advisory %}
+
+{% capture warning-version %}
+
+In Express 4.x, the `*` character in regular expressions is not interpreted in the usual way . As a workaround, use `{0,}` instead of `*`. This will likely be fixed in Express 5.
+
+{% endcapture %}
+
+{% include admonitions/warning.html content=warning-version %}
+
+Routenhandler (Weiterleitungsroutinen)
+
+Sie können mehrere Callback-Funktionen angeben, die sich wie [Middleware](/en/guide/using-middleware) verhalten, um eine Anforderung zu verarbeiten. Die einzige Ausnahme hierbei ist, dass diese Callbacks möglicherweise `next('route')` aufrufen, um die verbleibenden Weiterleitungs-Callbacks zu umgehen. Mit diesem Verfahren können Sie Vorabbedingungen für eine Weiterleitung festlegen und dann die Steuerung an nachfolgende Weiterleitungen übergeben, wenn kein Grund vorliegt, mit der aktuellen Weiterleitung fortzufahren.
+
+```js
+app.get('/user/:id', (req, res, next) => {
+ if (req.params.id === '0') {
+ return next('route');
+ }
+ res.send(`User ${req.params.id}`);
+});
+
+app.get('/user/:id', (req, res) => {
+ res.send('Special handler for user ID 0');
+});
+```
+
+In this example:
+
+- `GET /user/5` → handled by first route → sends "User 5"
+- `GET /user/0` → first route calls `next('route')`, skipping to the next matching `/user/:id` route
+
+Routenhandler können eine Funktion und/oder ein Funktionsarray sein, wie in den folgenden Beispielen zu sehen ist.
+
+Eine einzelne Callback-Funktion kann eine Weiterleitung verarbeiten. Beispiel:
+
+```js
+app.get('/example/a', (req, res) => {
+ res.send('Hello from A!');
+});
+```
+
+Mehrere Callback-Funktionen können eine Weiterleitung verarbeiten (achten Sie darauf, dass Sie das Objekt `next` angeben). Beispiel:
+
+```js
+app.get(
+ '/example/b',
+ (req, res, next) => {
+ console.log('the response will be sent by the next function ...');
+ next();
+ },
+ (req, res) => {
+ res.send('Hello from B!');
+ }
+);
+```
+
+Ein Array von Callback-Funktionen kann eine Weiterleitung verarbeiten. Beispiel:
+
+```js
+const cb0 = function (req, res, next) {
+ console.log('CB0');
+ next();
+};
+
+const cb1 = function (req, res, next) {
+ console.log('CB1');
+ next();
+};
+
+const cb2 = function (req, res) {
+ res.send('Hello from C!');
+};
+
+app.get('/example/c', [cb0, cb1, cb2]);
+```
+
+Eine Kombination aus unabhängigen Funktionen und Funktionsarrays kann eine Weiterleitung verarbeiten. Beispiel:
+
+```js
+const cb0 = function (req, res, next) {
+ console.log('CB0');
+ next();
+};
+
+const cb1 = function (req, res, next) {
+ console.log('CB1');
+ next();
+};
+
+app.get(
+ '/example/d',
+ [cb0, cb1],
+ (req, res, next) => {
+ console.log('the response will be sent by the next function ...');
+ next();
+ },
+ (req, res) => {
+ res.send('Hello from D!');
+ }
+);
+```
+
+Antwortmethoden
+
+Über die Methoden für das Antwortobjekt (`res`) in der folgenden Tabelle kann eine Antwort an den Client gesendet und der Anforderung/Antwort-Zyklus beendet werden. Wenn keine dieser Methoden über einen Routenhandler aufgerufen wird, bleibt die Clientanforderung im Status "blockiert".
+
+| Methode | Beschreibung |
+| --------------------------------------------- | ----------------------------------------------------------------------------------------------- |
+| [res.download()](/en/4x/api#res.download) | Gibt eine Eingabeaufforderung zum Herunterladen einer Datei aus. |
+| [res.end()](/en/4x/api#res.end) | End the response process. |
+| [res.json()](/en/4x/api#res.json) | Sendet eine JSON-Antwort. |
+| [res.jsonp()](/en/4x/api#res.jsonp) | Sendet eine JSON-Antwort mit JSONP-Unterstützung. |
+| [res.redirect()](/en/4x/api#res.redirect) | Leitet eine Anforderung um. |
+| [res.render()](/en/4x/api#res.render) | Render a view template. |
+| [res.send()](/en/4x/api#res.send) | Sendet eine Antwort mit unterschiedlichen Typen. |
+| [res.sendFile](/en/4x/api#res.sendFile) | Sendet eine Datei als Oktett-Stream. |
+| [res.sendStatus()](/en/4x/api#res.sendStatus) | Legt den Antwortstatuscode fest und sendet dessen Zeichenfolgedarstellung als Antworthauptteil. |
+
+app.route()
+
+Sie können mithilfe von `app.route()` verkettbare Routenhandler für einen Weiterleitungspfad erstellen.
+Da der Pfad an einer einzelnen Position angegeben wird, ist das Erstellen modularer Weiterleitungen hilfreich, da Redundanzen und Schreibfehler reduziert werden. Weitere Informationen zu Weiterleitungen finden Sie in der Dokumentation zu [Router()](/en/4x/api#router).
+
+Dies ist ein Beispiel für verkettete Routenhandler, die mit der Funktion `app.route()` definiert werden.
+
+```js
+app
+ .route('/book')
+ .get((req, res) => {
+ res.send('Get a random book');
+ })
+ .post((req, res) => {
+ res.send('Add a book');
+ })
+ .put((req, res) => {
+ res.send('Update the book');
+ });
+```
+
+express.Router
+
+Mit der Klasse `express.Router` lassen sich modular einbindbare Routenhandler erstellen. Eine `Router`-Instanz ist ein vollständiges Middleware- und Routingsystem. Aus diesem Grund wird diese Instanz oft auch als "Mini-App" bezeichnet.
+
+Im folgenden Beispiel wird ein Router als Modul erstellt, eine Middlewarefunktion in das Modul geladen, es werden Weiterleitungen definiert und das Modul letztendlich in einen Pfad in der Hauptanwendung eingebunden.
+
+Erstellen Sie eine Routerdatei namens `birds.js` mit dem folgenden Inhalt im Anwendungsverzeichnis:
+
+```js
+const express = require('express');
+const router = express.Router();
+
+// middleware that is specific to this router
+const timeLog = (req, res, next) => {
+ console.log('Time: ', Date.now());
+ next();
+};
+router.use(timeLog);
+
+// define the home page route
+router.get('/', (req, res) => {
+ res.send('Birds home page');
+});
+// define the about route
+router.get('/about', (req, res) => {
+ res.send('About birds');
+});
+
+module.exports = router;
+```
+
+Laden Sie dann das Routermodul in die Anwendung:
+
+```js
+const birds = require('./birds');
+
+// ...
+
+app.use('/birds', birds);
+```
+
+Die Anwendung kann nun Anforderungen an die Pfade `/birds` und `/birds/about` bearbeiten und ruft die Middlewarefunktion `timeLog` auf, die speziell für diese Weiterleitung bestimmt ist.
+
+But if the parent route `/birds` has path parameters, it will not be accessible by default from the sub-routes. To make it accessible, you will need to pass the `mergeParams` option to the Router constructor [reference](/en/5x/api#app.use).
+
+```js
+const router = express.Router({ mergeParams: true });
+```
diff --git a/astro/src/content/docs/de/4x/guide/using-middleware.md b/astro/src/content/docs/de/4x/guide/using-middleware.md
new file mode 100644
index 0000000000..f5987bc806
--- /dev/null
+++ b/astro/src/content/docs/de/4x/guide/using-middleware.md
@@ -0,0 +1,293 @@
+---
+title: Express-Middleware verwenden
+description: Learn how to use middleware in Express.js applications, including application-level and router-level middleware, error handling, and integrating third-party middleware.
+---
+
+# Middleware verwenden
+
+Express ist ein Weiterleitungs- und Middleware-Web-Framework, das selbst nur minimale Funktionalität aufweist: Eine Express-Anwendung besteht im Wesentlichen aus einer Reihe von Middlewarefunktionsaufrufen.
+
+_Middleware_ functions are functions that have access to the [request object](/en/5x/api#req) (`req`), the [response object](/en/5x/api#res) (`res`), and the next middleware function in the application's request-response cycle. Die nächste Middlewarefunktion wird im Allgemeinen durch die Variable `next` bezeichnet.
+
+Über Middlewarefunktionen lassen sich die folgenden Tasks ausführen:
+
+- Ausführen von Code
+- Vornehmen von Änderungen an der Anforderung und an Antwortobjekten
+- End the request-response cycle.
+- Aufrufen der nächsten Middlewarefunktion im Stack
+
+Wenn über die aktuelle Middlewarefunktion der Anforderung/Antwort-Zyklus nicht beendet werden kann, muss `next()` aufgerufen werden, um die Steuerung an die nächste Middlewarefunktion zu übergeben. Andernfalls geht die Anforderung in den Status "Blockiert" über.
+
+Eine Express-Anwendung kann die folgenden Middlewaretypen verwenden:
+
+- [Middleware auf Anwendungsebene](#middleware.application)
+- [Middleware auf Routerebene](#middleware.router)
+- [Middleware für die Fehlerbehandlung](#middleware.error-handling)
+- [Integrierte Middleware](#middleware.built-in)
+- [Middleware anderer Anbieter](#middleware.third-party)
+
+Sie können Middleware auf Anwendungsebene und Routerebene mit einem optionalen Mountpfad laden.
+Sie können auch eine Reihe von Middlewarefunktionen zusammen laden. Dadurch wird ein Sub-Stack des Middlewaresystems am Mountpunkt erstellt.
+
+Middleware auf Anwendungsebene
+
+Bind application-level middleware to an instance of the [app object](/en/5x/api#app) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the HTTP method of the request that the middleware function handles (such as GET, PUT, or POST) in lowercase.
+
+Dieses Beispiel zeigt eine Middlewarefunktion ohne Mountpfad. Die Funktion wird immer dann ausgeführt, wenn die Anwendung eine Anforderung erhält.
+
+```js
+const express = require('express');
+const app = express();
+
+app.use((req, res, next) => {
+ console.log('Time:', Date.now());
+ next();
+});
+```
+
+Dieses Beispiel zeigt eine Middlewarefunktion mit dem Mountpfad `/user/:id`. Die Funktion wird für jede Art von HTTP-Anforderung auf dem Pfad `/user/:id` ausgeführt.
+
+```js
+app.use('/user/:id', (req, res, next) => {
+ console.log('Request Type:', req.method);
+ next();
+});
+```
+
+Dieses Beispiel zeigt eine Weiterleitung und deren Handlerfunktion (Middlewaresystem). Die Funktion verarbeitet GET-Anforderungen zum Pfad `/user/:id`.
+
+```js
+app.get('/user/:id', (req, res, next) => {
+ res.send('USER');
+});
+```
+
+Dies ist ein Beispiel zum Laden einer Reihe von Middlewarefunktionen an einem Mountpunkt mit einem Mountpfad.
+Das Beispiel veranschaulicht einen Middleware-Stack, über den Anforderungsinformationen zu einer HTTP-Anforderung zum Pfad `/user/:id` ausgegeben werden.
+
+```js
+app.use(
+ '/user/:id',
+ (req, res, next) => {
+ console.log('Request URL:', req.originalUrl);
+ next();
+ },
+ (req, res, next) => {
+ console.log('Request Type:', req.method);
+ next();
+ }
+);
+```
+
+Mit einem Routenhandler können Sie mehrere Weiterleitungen für einen Pfad definieren. Im folgenden Beispiel werden zwei Weiterleitungen für GET-Anforderungen zum Pfad `/user/:id` definiert. Die zweite Weiterleitung verursacht zwar keine Probleme, wird jedoch nie aufgerufen, da durch die erste Weiterleitung der Anforderung/Antwort-Zyklus beendet wird.
+
+Dieses Beispiel zeigt einen Middleware-Sub-Stack, über den GET-Anforderungen zum Pfad `/user/:id` verarbeitet werden.
+
+```js
+app.get(
+ '/user/:id',
+ (req, res, next) => {
+ console.log('ID:', req.params.id);
+ next();
+ },
+ (req, res, next) => {
+ res.send('User Info');
+ }
+);
+
+// handler for the /user/:id path, which prints the user ID
+app.get('/user/:id', (req, res, next) => {
+ res.send(req.params.id);
+});
+```
+
+Wenn Sie den Rest der Middlewarefunktionen eines Weiterleitungs-Middleware-Stack überspringen wollen, rufen Sie `next('route')` auf, um die Steuerung an die nächste Weiterleitung zu übergeben.
+
+{% capture next-function %}
+
+`next('route')` will work only in middleware functions that were loaded by using the `app.METHOD()` or `router.METHOD()` functions.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=next-function %}
+
+Dieses Beispiel zeigt einen Middleware-Sub-Stack, über den GET-Anforderungen zum Pfad `/user/:id` verarbeitet werden.
+
+```js
+app.get(
+ '/user/:id',
+ (req, res, next) => {
+ // if the user ID is 0, skip to the next route
+ if (req.params.id === '0') next('route');
+ // otherwise pass the control to the next middleware function in this stack
+ else next();
+ },
+ (req, res, next) => {
+ // send a regular response
+ res.send('regular');
+ }
+);
+
+// handler for the /user/:id path, which sends a special response
+app.get('/user/:id', (req, res, next) => {
+ res.send('special');
+});
+```
+
+Middleware can also be declared in an array for reusability.
+
+Dies ist ein Beispiel zur Verwendung der Middlewarefunktion `express.static` mit einem ausführlich dargestellten Optionsobjekt:
+
+```js
+function logOriginalUrl(req, res, next) {
+ console.log('Request URL:', req.originalUrl);
+ next();
+}
+
+function logMethod(req, res, next) {
+ console.log('Request Type:', req.method);
+ next();
+}
+
+const logStuff = [logOriginalUrl, logMethod];
+app.get('/user/:id', logStuff, (req, res, next) => {
+ res.send('User Info');
+});
+```
+
+Middleware auf Routerebene
+
+Middleware auf Routerebene funktioniert in der gleichen Weise wie Middleware auf Anwendungsebene, mit dem einzigen Unterschied, dass sie an eine Instanz von `express.Router()` gebunden ist.
+
+```js
+const router = express.Router();
+```
+
+Laden Sie Middleware auf Routerebene über die Funktionen `router.use()` und `router.METHOD()`.
+
+Der folgende Beispielcode repliziert das Middlewaresystem, das oben für die Middleware auf Anwendungsebene gezeigt wird, durch Verwendung von Middleware auf Routerebene.
+
+```js
+const express = require('express');
+const app = express();
+const router = express.Router();
+
+// a middleware function with no mount path. This code is executed for every request to the router
+router.use((req, res, next) => {
+ console.log('Time:', Date.now());
+ next();
+});
+
+// a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path
+router.use(
+ '/user/:id',
+ (req, res, next) => {
+ console.log('Request URL:', req.originalUrl);
+ next();
+ },
+ (req, res, next) => {
+ console.log('Request Type:', req.method);
+ next();
+ }
+);
+
+// a middleware sub-stack that handles GET requests to the /user/:id path
+router.get(
+ '/user/:id',
+ (req, res, next) => {
+ // if the user ID is 0, skip to the next router
+ if (req.params.id === '0') next('route');
+ // otherwise pass control to the next middleware function in this stack
+ else next();
+ },
+ (req, res, next) => {
+ // render a regular page
+ res.render('regular');
+ }
+);
+
+// handler for the /user/:id path, which renders a special page
+router.get('/user/:id', (req, res, next) => {
+ console.log(req.params.id);
+ res.render('special');
+});
+
+// mount the router on the app
+app.use('/', router);
+```
+
+To skip the rest of the router's middleware functions, call `next('router')`
+to pass control back out of the router instance.
+
+Dieses Beispiel zeigt einen Middleware-Sub-Stack, über den GET-Anforderungen zum Pfad `/user/:id` verarbeitet werden.
+
+```js
+const express = require('express');
+const app = express();
+const router = express.Router();
+
+// predicate the router with a check and bail out when needed
+router.use((req, res, next) => {
+ if (!req.headers['x-auth']) return next('router');
+ next();
+});
+
+router.get('/user/:id', (req, res) => {
+ res.send('hello, user!');
+});
+
+// use the router and 401 anything falling through
+app.use('/admin', router, (req, res) => {
+ res.sendStatus(401);
+});
+```
+
+Middleware für die Fehlerbehandlung
+
+
+Middleware für die Fehlerbehandlung benötigt immer *vier* Argumente. Sie müssen vier Argumente angeben, um die Erkennung als Middlewarefunktion für die Fehlerbehandlung zu ermöglichen. Selbst wenn das Objekt `next` nicht verwenden müssen, müssen Sie dies angeben, um die Signatur beizubehalten. Andernfalls wird das Objekt `next` als reguläre Middleware interpretiert, sodass keine Fehlerbehandlung möglich ist.
+
+
+Middlewarefunktionen für die Fehlerbehandlung werden in derselben Weise definiert wie andere Middlewarefunktionen, außer dass Fehlerbehandlungsfunktionen speziell bei Signaturen vier anstatt drei Argumente aufweisen `(err, req, res, next)`:
+
+```js
+app.use((err, req, res, next) => {
+ console.error(err.stack);
+ res.status(500).send('Something broke!');
+});
+```
+
+Details zu Middleware für die Fehlerbehandlung siehe [Fehlerbehandlung](/en/guide/error-handling).
+
+Integrierte Middleware
+
+Seit Version 4.x bestehen bei Express keine Abhängigkeiten zu [Connect](https://github.com/senchalabs/connect) mehr. Mit Ausnahme von `express.static` befinden sich nun alle Middlewarefunktionen, die bisher in Express enthalten waren, in separaten Modulen. Sehen Sie sich hierzu auch die [Liste der Middlewarefunktionen](https://github.com/senchalabs/connect#middleware) an.
+
+Die einzige integrierte Middlewarefunktion in Express ist `express.static`.
+
+- [express.static](/en/5x/api#express.static) serves static assets such as HTML files, images, and so on.
+- [express.json](/en/5x/api#express.json) parses incoming requests with JSON payloads. **NOTE: Available with Express 4.16.0+**
+- [express.urlencoded](/en/5x/api#express.urlencoded) parses incoming requests with URL-encoded payloads. **NOTE: Available with Express 4.16.0+**
+
+Middleware anderer Anbieter
+
+Mit Middleware anderer Anbieter können Sie Express-Anwendungen um neue Funktionalität erweitern.
+
+Installieren Sie das Modul Node.js für die erforderliche Funktionalität. Laden Sie das Modul dann in Ihre Anwendung auf Anwendungsebene oder auf Routerebene.
+
+Das folgende Beispiel veranschaulicht das Installieren und Laden der Middlewarefunktion `cookie-parser` für das Cookie-Parsing.
+
+```bash
+$ npm install cookie-parser
+```
+
+```js
+const express = require('express');
+const app = express();
+const cookieParser = require('cookie-parser');
+
+// load the cookie-parsing middleware
+app.use(cookieParser());
+```
+
+Eine nicht vollständige Liste zu den Middlewarefunktionen anderer Anbieter, die im Allgemeinen mit Express verwendet werden, finden Sie unter [Middleware anderer Anbieter](../resources/middleware).
diff --git a/astro/src/content/docs/de/4x/guide/using-template-engines.md b/astro/src/content/docs/de/4x/guide/using-template-engines.md
new file mode 100644
index 0000000000..0e99b8b839
--- /dev/null
+++ b/astro/src/content/docs/de/4x/guide/using-template-engines.md
@@ -0,0 +1,58 @@
+---
+title: Template-Engines in Express verwenden
+description: Discover how to integrate and use template engines like Pug, Handlebars, and EJS with Express.js to render dynamic HTML pages efficiently.
+---
+
+# Template-Engines in Express verwenden
+
+A _template engine_ enables you to use static template files in your application. At runtime, the template engine replaces
+variables in a template file with actual values, and transforms the template into an HTML file sent to the client.
+This approach makes it easier to design an HTML page.
+
+The [Express application generator](/en/starter/generator) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it also supports [Handlebars](https://www.npmjs.com/package/handlebars), and [EJS](https://www.npmjs.com/package/ejs), among others.
+
+To render template files, set the following [application setting properties](/en/4x/api#app.set), in the default `app.js` created by the generator:
+
+- `views`, das Verzeichnis, in dem sich die Vorlagendateien befinden. Beispiel: `app.set('views', './views')`
+ This defaults to the `views` directory in the application root directory.
+- `view engine`, die zu verwendende Template-Engine. Beispiel: `app.set('view engine', 'pug')`
+
+Installieren Sie dann das entsprechende npm-Paket für die Template-Engine:
+
+```bash
+$ npm install pug --save
+```
+
+Express-konforme Template-Engines wie Pug exportieren eine Funktion namens `__express(filePath, options, callback)`, die über die Funktion `res.render()` aufgerufen wird, um den Vorlagencode ausgeben zu können.
+
+Einige Template-Engines folgen dieser Konvention nicht. Die Bibliothek [Consolidate.js](https://www.npmjs.org/package/consolidate) folgt dieser Konvention, indem alle gängigen Node.js-Template-Engines zugeordnet werden. Daher ist eine reibungslose Funktion in Express gewährleistet.
+
+
+
+Nach der Festlegung der View-Engine muss die Engine nicht angegeben oder das Template-Engine-Modul nicht in Ihre Anwendung geladen werden. Express lädt das Modul intern (wie unten für das obige Beispiel gezeigt).
+
+```js
+app.set('view engine', 'pug');
+```
+
+Erstellen Sie eine Pug-Vorlagendatei namens `index.pug` im Verzeichnis `views` mit dem folgenden Inhalt:
+
+```pug
+html
+ head
+ title= title
+ body
+ h1= message
+```
+
+Dann erstellen Sie eine Weiterleitung, um die Datei `index.pug` auszugeben. Wenn die Eigenschaft `view engine` nicht festgelegt wurde, müssen Sie die Erweiterung der Datei `view` angeben. Andernfalls müssen Sie diese Erweiterung nicht angeben.
+
+```js
+app.get('/', (req, res) => {
+ res.render('index', { title: 'Hey', message: 'Hello there!' });
+});
+```
+
+Wenn Sie eine Anforderung zur Homepage ausführen, wird die Datei `index.pug` im HTML-Format ausgegeben.
+
+The view engine cache does not cache the contents of the template's output, only the underlying template itself. The view is still re-rendered with every request even when the cache is on.
diff --git a/astro/src/content/docs/de/4x/guide/writing-middleware.md b/astro/src/content/docs/de/4x/guide/writing-middleware.md
new file mode 100644
index 0000000000..3bc5fbb2fb
--- /dev/null
+++ b/astro/src/content/docs/de/4x/guide/writing-middleware.md
@@ -0,0 +1,217 @@
+---
+title: Middleware für die Verwendung in Express-Anwendungen schreiben
+description: Learn how to write custom middleware functions for Express.js applications, including examples and best practices for enhancing request and response handling.
+---
+
+# Middleware für die Verwendung in Express-Anwendungen schreiben
+
+Überblick
+
+_Middleware_ functions are functions that have access to the [request object](/en/5x/api#req) (`req`), the [response object](/en/5x/api#res) (`res`), and the `next` function in the application's request-response cycle. Die nächste Middlewarefunktion wird im Allgemeinen durch die Variable `next` bezeichnet.
+
+Über Middlewarefunktionen lassen sich die folgenden Tasks ausführen:
+
+- Ausführen von Code
+- Vornehmen von Änderungen an der Anforderung und an Antwortobjekten
+- End the request-response cycle.
+- Aufrufen der nächsten Middleware im Stack
+
+Wenn über die aktuelle Middlewarefunktion der Anforderung/Antwort-Zyklus nicht beendet werden kann, muss `next()` aufgerufen werden, um die Steuerung an die nächste Middlewarefunktion zu übergeben. Andernfalls geht die Anforderung in den Status "Blockiert" über.
+
+Das folgende Beispiel zeigt die Elemente eines Middlewarefunktionsaufrufs:
+
+
+
+Starting with Express 5, middleware functions that return a Promise will call `next(value)` when they reject or throw an error. `next` will be called with either the rejected value or the thrown Error.
+
+Beispiel
+
+Here is an example of a simple "Hello World" Express application.
+The remainder of this article will define and add three middleware functions to the application:
+one called `myLogger` that prints a simple log message, one called `requestTime` that
+displays the timestamp of the HTTP request, and one called `validateCookies` that validates incoming cookies.
+
+```js
+const express = require('express');
+const app = express();
+
+app.get('/', (req, res) => {
+ res.send('Hello World!');
+});
+
+app.listen(3000);
+```
+
+Dies ist ein Beispiel einer einfachen Express-Anwendung namens "Hello World", für die Sie zwei Middlewarefunktionen definieren:
+Dies ist ein einfaches Beispiel einer Middlewarefunktion namens "myLogger". Diese Funktion gibt lediglich "LOGGED" aus, wenn eine Anforderung zur Anwendung über diese Funktion läuft. Die Middlewarefunktion ist der Variablen `myLogger` zugeordnet.
+
+```js
+const myLogger = function (req, res, next) {
+ console.log('LOGGED');
+ next();
+};
+```
+
+
+Beachten Sie den Aufruf oben zu `next()`. Durch den Aufruf dieser Funktion wird die nächste Middlewarefunktion in der Anwendung aufgerufen.
+Die Funktion `next()` ist nicht Teil der Node.js- oder Express-API, sondern das dritte Argument, das an die Middlewarefunktion übergeben wird. Die Funktion `next()` kann jeden beliebigen Namen haben, per Konvention erhält sie jedoch immer den Namen "next".
+Um Unklarheiten zu vermeiden, sollten Sie immer diese Konvention verwenden.
+
+
+Zum Laden der Middlewarefunktion rufen Sie `app.use()` auf und geben die Middlewarefunktion an.
+Beispiel: Durch den folgenden Code wird die Middlewarefunktion `myLogger` vor der Weiterleitung zum Stammverzeichnispfad (/) geladen.
+
+```js
+const express = require('express');
+const app = express();
+
+const myLogger = function (req, res, next) {
+ console.log('LOGGED');
+ next();
+};
+
+app.use(myLogger);
+
+app.get('/', (req, res) => {
+ res.send('Hello World!');
+});
+
+app.listen(3000);
+```
+
+Sobald die Anwendung eine Anforderung erhält, gibt sie die Nachricht "LOGGED" an das Terminal aus.
+
+Die Reihenfolge beim Laden der Middleware ist wichtig: Middlewarefunktionen, die zuerst geladen werden, werden auch zuerst ausgeführt.
+
+Wenn `myLogger` nach der Weiterleitung zum Stammverzeichnispfad geladen wird, erreicht die Weiterleitung die Middlewarefunktion nicht. Die Anwendung gibt "LOGGED" nicht aus, weil der Routenhandler für den Stammverzeichnispfad den Anforderung/Antwort-Zyklus beendet.
+
+Die Middlewarefunktion `myLogger` gibt einfach eine Nachricht aus und übergibt dann die Anforderung zur nächsten Middlewarefunktion im Stack durch Aufruf der Funktion `next()`.
+
+Middleware function requestTime
+
+Im nächsten Beispiel wird die Eigenschaft `requestTime` zum Anforderungsobjekt hinzugefügt. Diese Middlewarefunktion erhält den Namen "requestTime".
+
+```js
+const requestTime = function (req, res, next) {
+ req.requestTime = Date.now();
+ next();
+};
+```
+
+Die Anwendung verwendet nun die Middlewarefunktion `requestTime`. Außerdem verwendet die Callback-Funktion der Weiterleitung zum Stammverzeichnispfad die Eigenschaft, die die Middlewarefunktion zu `req` (dem Anforderungsobjekt) hinzufügt.
+
+```js
+const express = require('express');
+const app = express();
+
+const requestTime = function (req, res, next) {
+ req.requestTime = Date.now();
+ next();
+};
+
+app.use(requestTime);
+
+app.get('/', (req, res) => {
+ let responseText = 'Hello World! ';
+ responseText += `Requested at: ${req.requestTime} `;
+ res.send(responseText);
+});
+
+app.listen(3000);
+```
+
+Wenn Sie eine Anforderung zum Stammverzeichnis der Anwendung einleiten, zeigt die Anwendung nun die Zeitmarke Ihrer Anforderung im Browser an.
+
+Middleware function validateCookies
+
+Finally, we'll create a middleware function that validates incoming cookies and sends a 400 response if cookies are invalid.
+
+Here's an example function that validates cookies with an external async service.
+
+```js
+async function cookieValidator(cookies) {
+ try {
+ await externallyValidateCookie(cookies.testCookie);
+ } catch {
+ throw new Error('Invalid cookies');
+ }
+}
+```
+
+Here, we use the [`cookie-parser`](/en/resources/middleware/cookie-parser) middleware to parse incoming cookies off the `req` object and pass them to our `cookieValidator` function. The `validateCookies` middleware returns a Promise that upon rejection will automatically trigger our error handler.
+
+```js
+const express = require('express');
+const cookieParser = require('cookie-parser');
+const cookieValidator = require('./cookieValidator');
+
+const app = express();
+
+async function validateCookies(req, res, next) {
+ await cookieValidator(req.cookies);
+ next();
+}
+
+app.use(cookieParser());
+
+app.use(validateCookies);
+
+// error handler
+app.use((err, req, res, next) => {
+ res.status(400).send(err.message);
+});
+
+app.listen(3000);
+```
+
+
+Note how `next()` is called after `await cookieValidator(req.cookies)`. This ensures that if `cookieValidator` resolves, the next middleware in the stack will get called. If you pass anything to the `next()` function (except the string `'route'` or `'router'`), Express regards the current request as being an error and will skip any remaining non-error handling routing and middleware functions.
+
+
+Da Sie Zugriff auf das Anforderungsobjekt, das Antwortobjekt, die nächste Middlewarefunktion im Stack und die gesamte Node.js-API haben, sind die Möglichkeiten, die Sie mit Middlewarefunktionen haben, nahezu unendlich.
+
+Weitere Informationen zur Verwendung von Middleware in Express siehe [ Express-Middleware verwenden](/en/guide/using-middleware).
+
+Configurable middleware
+
+If you need your middleware to be configurable, export a function which accepts an options object or other parameters, which, then returns the middleware implementation based on the input parameters.
+
+File: `my-middleware.js`
+
+```js
+module.exports = function (options) {
+ return function (req, res, next) {
+ // Implement the middleware function based on the options object
+ next();
+ };
+};
+```
+
+The middleware can now be used as shown below.
+
+```js
+const mw = require('./my-middleware.js');
+
+app.use(mw({ option1: '1', option2: '2' }));
+```
+
+Refer to [cookie-session](https://github.com/expressjs/cookie-session) and [compression](https://github.com/expressjs/compression) for examples of configurable middleware.
diff --git a/astro/src/content/docs/de/4x/starter/basic-routing.md b/astro/src/content/docs/de/4x/starter/basic-routing.md
new file mode 100644
index 0000000000..633da3f660
--- /dev/null
+++ b/astro/src/content/docs/de/4x/starter/basic-routing.md
@@ -0,0 +1,63 @@
+---
+title: Basisrouting in Express
+description: Learn the fundamentals of routing in Express.js applications, including how to define routes, handle HTTP methods, and create route handlers for your web server.
+---
+
+# Basisrouting
+
+Per _Routing_ wird bestimmt, wie eine Antwort auf eine Clientanforderung an einem bestimmten Endpunkt antwortet. Dies ist eine URI (oder ein Pfad) und eine bestimmte HTTP-Anforderungsmethode (GET, POST usw.).
+
+Jede Weiterleitung (Route) kann eine oder mehrere Handlerfunktionen haben, die ausgeführt werden, wenn die Weiterleitung abgeglichen wird.
+
+Weiterleitungsdefinitionen haben die folgende Struktur:
+
+```js
+app.METHOD(PATH, HANDLER);
+```
+
+Where:
+
+- `app` ist eine Instanz von `express`.
+- `METHOD` is an [HTTP request method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods), in lowercase.
+- `PATH` ist ein Pfad auf dem Server.
+- `HANDLER` ist die Funktion, die ausgeführt wird, wenn die Weiterleitung abgeglichen wird.
+
+
+In diesem Lernprogramm wird vorausgesetzt, dass eine Instanz von `express` namens `app` erstellt und der Server ausgeführt wird. Wenn Sie mit dem Erstellen und Starten von Anwendungen nicht vertraut sind, spielen Sie das [Beispiel "Hello World"](/en/starter/hello-world) durch.
+
+
+Die folgenden Beispiele veranschaulichen das Definieren einfacher Weiterleitungen.
+
+Antworten Sie mit `Hello World!` auf der Homepage:
+
+```js
+app.get('/', (req, res) => {
+ res.send('Hello World!');
+});
+```
+
+Respond to a POST request on the root route (`/`), the application's home page:
+
+```js
+app.post('/', (req, res) => {
+ res.send('Got a POST request');
+});
+```
+
+Antworten Sie auf eine PUT-Anforderung zur Weiterleitung `/user`:
+
+```js
+app.put('/user', (req, res) => {
+ res.send('Got a PUT request at /user');
+});
+```
+
+Antworten Sie auf eine DELETE-Anforderung zur Weiterleitung `/user`:
+
+```js
+app.delete('/user', (req, res) => {
+ res.send('Got a DELETE request at /user');
+});
+```
+
+Details zum Thema Routing finden Sie in der entsprechenden [Routinganleitung](/en/guide/routing).
diff --git a/astro/src/content/docs/de/4x/starter/examples.md b/astro/src/content/docs/de/4x/starter/examples.md
new file mode 100644
index 0000000000..a25a6d9834
--- /dev/null
+++ b/astro/src/content/docs/de/4x/starter/examples.md
@@ -0,0 +1,16 @@
+---
+title: Express examples
+description: Explore a collection of Express.js application examples covering various use cases, integrations, and advanced configurations to help you learn and build your projects.
+---
+
+{% capture examples %}{% include readmes/express-master/examples.md %}{% endcapture %}
+{{ examples | replace: "](.", "](https://github.com/expressjs/express/tree/master/examples" }}
+
+## Additional examples
+
+These are some additional examples with more extensive integrations.
+
+{% include community-caveat.html %}
+
+- [prisma-fullstack](https://github.com/prisma/prisma-examples/tree/latest/pulse/fullstack-simple-chat) - Fullstack app with Express and Next.js using [Prisma](https://www.npmjs.com/package/prisma) as an ORM
+- [prisma-rest-api-ts](https://github.com/prisma/prisma-examples/tree/latest/orm/express) - REST API with Express in TypeScript using [Prisma](https://www.npmjs.com/package/prisma) as an ORM
diff --git a/astro/src/content/docs/de/4x/starter/faq.md b/astro/src/content/docs/de/4x/starter/faq.md
new file mode 100644
index 0000000000..1ab5b58628
--- /dev/null
+++ b/astro/src/content/docs/de/4x/starter/faq.md
@@ -0,0 +1,75 @@
+---
+title: Häufig gestellte Fragen zu Express
+description: Finden Sie Antworten auf häufig gestellte Fragen zu Express.js, darunter Themen wie Anwendungsstruktur, Models, Authentifizierung, Template-Engines, Fehlerbehandlung und mehr.
+---
+
+# Häufig gestellte Fragen
+
+## Wie muss ich meine Anwendung strukturieren?
+
+Auf diese Frage gibt es keine verbindliche Antwort. Die Antwort hängt vom Umfang Ihrer Anwendung und dem eingebundenen Team ab. Um so flexibel wie möglich zu sein, gibt es bei Express keine Voraussetzungen hinsichtlich der Struktur.
+
+Weiterleitungen und andere anwendungsspezifische Logik können in einer beliebigen Anzahl von Dateien und in jeder von Ihnen bevorzugten Verzeichnisstruktur vorkommen. Die folgenden Beispiele sollen als Entscheidungshilfe dienen:
+
+- [Weiterleitungslisten](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-47)
+- [Weiterleitungszuordnung](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66)
+- [Controller im MVC-Stil](https://github.com/expressjs/express/tree/master/examples/mvc)
+
+Darüber hinaus gibt es Erweiterungen anderer Anbieter für Express, die zur Vereinfachung einiger dieser Muster beitragen:
+
+- [Weiterleitung mit "express-resource"](https://github.com/expressjs/express-resource)
+
+## Wie definiere ich Modelle?
+
+Express hat keine Vorstellungen von einer Datenbank. Dieses Konzept bleibt Node-Modulen anderer Anbieter überlassen, wodurch Schnittstellen zu allen Datenbank möglich sind.
+
+[LoopBack](http://loopback.io) zeigt ein Express-basiertes Framework, um das Modelle angeordnet sind.
+
+## Wie kann ich Benutzer authentifizieren?
+
+Die Authentifizierung ist ein weiterer meinungsstarker Bereich, in den Express nicht eingreift. Sie können ein Authentifizierungsschema nach Ihren Vorstellungen verwenden.
+Ein einfaches Benutzername/Kennwort-Schema können Sie in [diesem Beispiel](https://github.com/expressjs/express/tree/master/examples/auth) sehen.
+
+## Welche Template-Engines unterstützt Express?
+
+Express unterstützt jede Template-Engine, die der `(path, locals, callback)`-Signatur entspricht.
+Informationen zur Normalisierung von Template-Engine-Schnittstellen und -Caching siehe das Projekt [consolidate.js](https://github.com/visionmedia/consolidate.js). Nicht aufgelistete Template-Engines können trotzdem die Express-Signatur unterstützen.
+
+For more information, see [Using template engines with Express](/en/guide/using-template-engines).
+
+## Wie handhabe ich 404-Antworten?
+
+In Express sind 404-Antworten nicht das Ergebnis eines Fehlers, sodass diese Antworten von der Fehlerbehandlungsroutine nicht erfasst werden. Dieses Verhalten ist damit zu erklären, dass eine 404-Antwort einfach angibt, dass keine weiteren Arbeiten auszuführen sind. In anderen Worten: Express hat alle Middlewarefunktionen und Weiterleitungen ausgeführt und festgestellt, dass keine Funktion eine Antwort zurückgegeben hat. Sie müssen also bei der Handhabung der 404-Antwort nur eine Middlewarefunktion am Ende des Stacks (unterhalb von allen anderen Funktionen) hinzufügen:
+
+```js
+app.use((req, res, next) => {
+ res.status(404).send("Sorry can't find that!");
+});
+```
+
+Add routes dynamically at runtime on an instance of `express.Router()`
+so the routes are not superseded by a middleware function.
+
+## Wie richte ich eine Fehlerbehandlungsroutine ein?
+
+Middleware für die Fehlerbehandlung wird in derselben Weise definiert wie andere Middleware; außer dass sie vier anstatt drei Argumente aufweist. Dies gilt speziell bei der Signatur `(err, req, res, next)`:
+
+```js
+app.use((err, req, res, next) => {
+ console.error(err.stack);
+ res.status(500).send('Something broke!');
+});
+```
+
+Weitere Informationen siehe [Fehlerbehandlung](/en/guide/error-handling).
+
+## Wie gebe ich normales HTML-Format aus?
+
+Das ist nicht Ihre Aufgabe! Sie müssen kein HTML-Format mit der Funktion `res.render()` ausgeben.
+Verwenden Sie die Funktion `res.sendFile()`, wenn Sie es mit einer bestimmten Datei zu tun haben.
+Wenn Sie viele Assets aus einem Verzeichnis bedienen müssen, verwenden Sie die Middlewarefunktion `express.static()`.
+
+## Welche Version von Node.js benötigt Express?
+
+- [Express 4.x](/en/4x/api) requires Node.js 0.10 or higher.
+- [Express 5.x](/en/5x/api) requires Node.js 18 or higher.
diff --git a/astro/src/content/docs/de/4x/starter/generator.md b/astro/src/content/docs/de/4x/starter/generator.md
new file mode 100644
index 0000000000..cf23c63154
--- /dev/null
+++ b/astro/src/content/docs/de/4x/starter/generator.md
@@ -0,0 +1,122 @@
+---
+title: Express-Anwendungsgenerator
+description: Learn how to use the Express application generator tool to quickly create a skeleton for your Express.js applications, streamlining setup and configuration.
+---
+
+# Express-Anwendungsgenerator
+
+Mit dem Application Generator Tool `express` können Sie innerhalb kürzester Zeit ein Anwendungsgerüst erstellen.
+
+You can run the application generator with the `npx` command (available in Node.js 8.2.0).
+
+```bash
+$ npx express-generator
+```
+
+For earlier Node versions, install the application generator as a global npm package and then launch it:
+
+```bash
+$ npm install -g express-generator
+$ express
+```
+
+Zeigen Sie die Befehlsoptionen mit der Option `-h` an:
+
+```bash
+$ express -h
+
+ Usage: express [options] [dir]
+
+ Options:
+
+ -h, --help output usage information
+ --version output the version number
+ -e, --ejs add ejs engine support
+ --hbs add handlebars engine support
+ --pug add pug engine support
+ -H, --hogan add hogan.js engine support
+ --no-view generate without view engine
+ -v, --view add view support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
+ -c, --css add stylesheet support (less|stylus|compass|sass) (defaults to plain css)
+ --git add .gitignore
+ -f, --force force on non-empty directory
+```
+
+Im folgenden Beispiel wird eine Express-Anwendung mit dem Namen _myapp_ im aktuellen Arbeitsverzeichnis erstellt: The app will be created in a folder named _myapp_ in the current working directory and the view engine will be set to Pug :
+
+```bash
+$ express --view=pug myapp
+
+ create : myapp
+ create : myapp/package.json
+ create : myapp/app.js
+ create : myapp/public
+ create : myapp/public/javascripts
+ create : myapp/public/images
+ create : myapp/routes
+ create : myapp/routes/index.js
+ create : myapp/routes/users.js
+ create : myapp/public/stylesheets
+ create : myapp/public/stylesheets/style.css
+ create : myapp/views
+ create : myapp/views/index.pug
+ create : myapp/views/layout.pug
+ create : myapp/views/error.pug
+ create : myapp/bin
+ create : myapp/bin/www
+```
+
+Installieren Sie dann Abhängigkeiten:
+
+```bash
+$ cd myapp
+$ npm install
+```
+
+Verwenden Sie unter Windows diesen Befehl:
+
+```bash
+$ DEBUG=myapp:* npm start
+```
+
+Führen Sie unter MacOS oder Linux die Anwendung mit diesem Befehl aus:
+
+```bash
+> set DEBUG=myapp:* & npm start
+```
+
+On Windows PowerShell, use this command:
+
+```bash
+PS> $env:DEBUG='myapp:*'; npm start
+```
+
+Laden Sie dann `http://localhost:3000/` in Ihren Browser, um auf die Anwendung zuzugreifen.
+
+Die erstellte Anwendung hat die folgende Verzeichnisstruktur:
+
+```bash
+.
+├── app.js
+├── bin
+│ └── www
+├── package.json
+├── public
+│ ├── images
+│ ├── javascripts
+│ └── stylesheets
+│ └── style.css
+├── routes
+│ ├── index.js
+│ └── users.js
+└── views
+ ├── error.pug
+ ├── index.pug
+ └── layout.pug
+
+7 directories, 9 files
+```
+
+
+Die vom Generator erstellte Anwendungsstruktur ist nur eine der vielen Möglichkeiten, Express-Anwendungen zu strukturieren. Sie können diese Struktur verwenden oder sie an Ihre Anforderungen anpassen.
+
diff --git a/astro/src/content/docs/de/4x/starter/hello-world.md b/astro/src/content/docs/de/4x/starter/hello-world.md
new file mode 100644
index 0000000000..d6e9f141a6
--- /dev/null
+++ b/astro/src/content/docs/de/4x/starter/hello-world.md
@@ -0,0 +1,42 @@
+---
+title: Beispiel "Hello World" in Express
+description: Get started with Express.js by building a simple 'Hello World' application, demonstrating the basic setup and server creation for beginners.
+---
+
+# Beispiel "Hello World"
+
+
+Dies ist wohl die einfachste Express-Anwendung, die Sie erstellen können. Es handelt sich um eine Anwendung mit nur einer Datei und — *nicht* das, was Sie mit dem [Express Generator](/en/starter/generator) erhalten würden. Mit dem Generator würde das Gerüst für eine vollständige Anwendung mit zahlreichen JavaScript-Dateien, Jade-Vorlagen und Unterverzeichnissen für verschiedene Zwecke erstellt werden.
+
+
+```js
+const express = require('express');
+const app = express();
+const port = 3000;
+
+app.get('/', (req, res) => {
+ res.send('Hello World!');
+});
+
+app.listen(port, () => {
+ console.log(`Example app listening on port ${port}`);
+});
+```
+
+Die Anwendung startet einen Server und ist an Port 3000 empfangsbereit für Verbindungen. Die Anwendung antwortet mit "Hello World!" auf Anforderungen zur Stamm-URL (`/`) oder zu _route_. Bei jedem anderen Pfad lautet die Antwort **404 Not Found**.
+
+### Running Locally
+
+Erstellen Sie zunächst ein Verzeichnis namens `myapp`, wechseln Sie in das Verzeichnis und führen Sie `npm init` aus. Installieren Sie dann `express` als Abhängigkeit, wie im [Installationshandbuch](/en/starter/installing) beschrieben.
+
+Erstellen Sie im Verzeichnis `myapp` eine Datei namens `app.js` und fügen Sie den folgenden Code hinzu:
+
+`req` (Anforderung) und `res` (Antwort) sind genau dieselben Objekte, die Node bereitstellt. Sie können also `req.pipe()`, `req.on('data', callback)` und alle anderen Tasks, die Sie ausführen wollen, ohne Express ausführen.
+
+Führen Sie die Anwendung mit dem folgenden Befehl aus:
+
+```bash
+$ node app.js
+```
+
+Laden Sie dann [http://localhost:3000/](http://localhost:3000/) in einen Browser, um die Ausgabe zu sehen.
diff --git a/astro/src/content/docs/de/4x/starter/installing.md b/astro/src/content/docs/de/4x/starter/installing.md
new file mode 100644
index 0000000000..371e979f5f
--- /dev/null
+++ b/astro/src/content/docs/de/4x/starter/installing.md
@@ -0,0 +1,48 @@
+---
+title: Express installieren
+description: Erfahren Sie, wie Sie Express.js in Ihrer Node.js-Umgebung installieren, wie Sie Ihr Projektverzeichnis aufsetzen und Abhängigkeiten mit npm verwalten.
+---
+
+# Installation
+
+Angenommen, Sie haben [Node.js](https://nodejs.org/) bereits installiert. Erstellen Sie ein Verzeichnis für Ihre Anwendung und definieren Sie dieses Verzeichnis als Ihr Arbeitsverzeichnis.
+
+- [Express 4.x](/en/4x/api) requires Node.js 0.10 or higher.
+- [Express 5.x](/en/5x/api) requires Node.js 18 or higher.
+
+```bash
+$ mkdir myapp
+$ cd myapp
+```
+
+Erstellen Sie mit dem Befehl `npm init` eine Datei namens `package.json` für Ihre Anwendung.
+Weitere Informationen zur Funktionsweise von `package.json` finden Sie in den [Angaben zur Handhabung der npm-Datei package.json](https://docs.npmjs.com/files/package.json).
+
+```bash
+$ npm init
+```
+
+Dieser Befehl fordert Sie zur Eingabe verschiedener Angaben wie Name und Version Ihrer Anwendung auf.
+For now, you can simply hit RETURN to accept the defaults for most of them, with the following exception:
+
+```
+entry point: (index.js)
+```
+
+Geben Sie `app.js` oder einen Namen Ihrer Vorstellung als Namen für die Hauptdatei ein. Wenn dieser Name `index.js` lauten soll, drücken Sie die Eingabetaste, um den vorgeschlagenen Standarddateinamen zu akzeptieren.
+
+Installieren Sie jetzt Express im Verzeichnis `myapp` und speichern Sie es in der Abhängigkeitsliste. Beispiel:
+
+```bash
+$ npm install express
+```
+
+Wenn Sie Express vorübergehend installieren und nicht zur Abhängigkeitsliste hinzufügen wollen, geben Sie die Option `--save` nicht an:
+
+```bash
+$ npm install express --no-save
+```
+
+
+Node-Module, die mit der Option `--save` installiert werden, werden zur `Abhängigkeitsliste` in der Datei `package.json` hinzugefügt. Danach werden bei der Ausführung von `npm install` im Verzeichnis `app` automatisch alle Module in der Abhängigkeitsliste installiert.
+
diff --git a/astro/src/content/docs/de/4x/starter/static-files.md b/astro/src/content/docs/de/4x/starter/static-files.md
new file mode 100644
index 0000000000..fb36f85ca5
--- /dev/null
+++ b/astro/src/content/docs/de/4x/starter/static-files.md
@@ -0,0 +1,74 @@
+---
+title: Statische Dateien in Express bereitstellen
+description: Understand how to serve static files like images, CSS, and JavaScript in Express.js applications using the built-in 'static' middleware.
+---
+
+# Statische Dateien in Express bereitstellen
+
+Wenn Sie statische Dateien wie Bilder, CSS-Dateien und JavaScript-Dateien bereitstellen wollen, verwenden Sie die in Express integrierte Middlewarefunktion `express.static`.
+
+The function signature is:
+
+```js
+express.static(root, [options]);
+```
+
+The `root` argument specifies the root directory from which to serve static assets.
+For more information on the `options` argument, see [express.static](/en/5x/api#express.static).
+
+Beispiel: Verwenden Sie den folgenden Code, um Bilder, CSS-Dateien und JavaScript-Dateien in einem Verzeichnis namens `public` bereitzustellen:
+
+```js
+app.use(express.static('public'));
+```
+
+Jetzt können Sie die Dateien laden, die sich im Verzeichnis `public` befinden:
+
+```text
+http://localhost:3000/images/kitten.jpg
+http://localhost:3000/css/style.css
+http://localhost:3000/js/app.js
+http://localhost:3000/images/bg.png
+http://localhost:3000/hello.html
+```
+
+Express sucht nach den Dateien, die sich auf das Verzeichnis mit den statischen Assets beziehen. Der Name dieses Verzeichnisses ist also nicht Teil der URL.
+
+Wenn Sie mehrere Verzeichnisse mit statischen Assets verwenden wollen, rufen Sie die Middlewarefunktion `express.static` mehrmals auf:
+
+```js
+app.use(express.static('public'));
+app.use(express.static('files'));
+```
+
+Express sucht in der Reihenfolge nach den Dateien, in der sie die Verzeichnisse mit den statischen Assets über die Middlewarefunktion `express.static` festgelegt haben.
+
+{% capture alert_content %}
+For best results, [use a reverse proxy](/en/advanced/best-practice-performance#use-a-reverse-proxy) cache to improve performance of serving static assets.
+{% endcapture %}
+{% include admonitions/note.html content=alert_content %}
+
+To create a virtual path prefix (where the path does not actually exist in the file system) for files that are served by the `express.static` function, [specify a mount path](/en/5x/api#app.use) for the static directory, as shown below:
+
+```js
+app.use('/static', express.static('public'));
+```
+
+Jetzt können Sie die Dateien, die sich im Verzeichnis `public` befinden, aus dem Pfadpräfix `/static` laden.
+
+```text
+http://localhost:3000/static/images/kitten.jpg
+http://localhost:3000/static/css/style.css
+http://localhost:3000/static/js/app.js
+http://localhost:3000/static/images/bg.png
+http://localhost:3000/static/hello.html
+```
+
+Der Pfad, den Sie für die Funktion `express.static` angeben, ist jedoch relativ zum Verzeichnis, aus dem Sie Ihren Prozess `node` starten. Wenn Sie die Express-Anwendung aus einem anderen Verzeichnis ausführen, ist es sicherer, den absoluten Pfad des Verzeichnisses zu verwenden, das Sie bereitstellen wollen:
+
+```js
+const path = require('path');
+app.use('/static', express.static(path.join(__dirname, 'public')));
+```
+
+For more details about the `serve-static` function and its options, see [serve-static](/en/resources/middleware/serve-static).
diff --git a/astro/src/content/docs/de/5x/advanced/best-practice-performance.md b/astro/src/content/docs/de/5x/advanced/best-practice-performance.md
new file mode 100644
index 0000000000..cf631586a0
--- /dev/null
+++ b/astro/src/content/docs/de/5x/advanced/best-practice-performance.md
@@ -0,0 +1,307 @@
+---
+title: Leistungsspezifische Best Practices für Express-Anwendungen in Produktionsumgebungen
+description: Discover performance and reliability best practices for Express apps in production, covering code optimizations and environment setups for optimal performance.
+---
+
+# Best Practices in Produktionsumgebungen: Leistung und Zuverlässigkeit
+
+In diesem Beitrag werden Best Practices in Bezug auf Leistung und Zuverlässigkeit für Express-Anwendungen behandelt, die in der Produktionsumgebung bereitgestellt werden.
+
+Dieses Thema gehört sicherlich zur "DevOps"-Welt und deckt traditionelle Entwicklungs- und Betriebsprozesse ab. Entsprechend sind die Informationen hier in zwei Teile unterteilt:
+
+- Things to do in your code (the dev part):
+ - Für statische Dateien Middleware verwenden
+ - Keine synchronen Funktionen verwenden
+ - [Do logging correctly](#do-logging-correctly)
+ - [Handle exceptions properly](#handle-exceptions-properly)
+- Things to do in your environment / setup (the ops part):
+ - NODE_ENV auf "production" festlegen
+ - Automatischen Neustart Ihrer Anwendung sicherstellen
+ - Anwendung in einem Cluster ausführen
+ - Anforderungsergebnisse im Cache speichern
+ - Load Balancer verwenden
+ - Reverse Proxy verwenden
+
+## Things to do in your code {#in-code}
+
+Dies sind einige Beispiele für Maßnahmen, die Sie an Ihrem Code vornehmen können, um die Anwendungsleistung zu verbessern:
+
+- Für statische Dateien Middleware verwenden
+- Keine synchronen Funktionen verwenden
+- [Do logging correctly](#do-logging-correctly)
+- [Handle exceptions properly](#handle-exceptions-properly)
+
+### GZIP-Komprimierung verwenden
+
+Mit der GZIP-Komprimierung lässt sich die Größe des Antworthauptteils deutlich verringern und somit die Geschwindigkeit der Webanwendung erhöhen. Verwenden Sie die Middleware [compression](https://www.npmjs.com/package/compression) für die GZIP-Komprimierung in Ihrer Express-Anwendung. Beispiel:
+
+```js
+const compression = require('compression');
+const express = require('express');
+const app = express();
+
+app.use(compression());
+```
+
+Bei Websites mit hohem Datenverkehr in Produktionsumgebungen lässt sich die Komprimierung am besten installieren, indem sie auf Reverse Proxy-Ebene implementiert wird (siehe [Reverse Proxy verwenden](#proxy)). In diesem Fall wird die Middleware "compression" nicht benötigt. Details zur Aktivierung der GZIP-Komprimierung in Nginx siehe [Modul ngx_http_gzip_module](http://nginx.org/en/docs/http/ngx_http_gzip_module) in der Nginx-Dokumentation.
+
+### Keine synchronen Funktionen verwenden
+
+Synchrone Funktionen und Methoden belasten den Ausführungsprozess, bis sie zurückgegeben werden. Ein einzelner Aufruf für eine synchrone Funktion kann in wenigen Mikrosekunden oder Millisekunden zurückgegeben werden. Bei Websites mit hohem Datenverkehr hingegen summieren sich diese Aufrufe und verringern die Leistung der Anwendung. Sie sollten also deren Verwendung in Produktionsumgebungen vermeiden.
+
+Auch wenn Node und viele andere Module synchrone und asynchrone Versionen ihrer Funktionen bieten, sollten Sie in Produktionsumgebungen immer die asynchrone Version verwenden. Nur beim ersten Systemstart ist die Verwendung einer synchronen Funktion begründet.
+
+You can use the `--trace-sync-io` command-line flag to print a warning and a stack trace whenever your application uses a synchronous API. Auch wenn Sie diese natürlich nicht in der Produktionsumgebung verwenden werden, soll dadurch trotzdem sichergestellt werden, dass Ihr Code in der Produktionsumgebung eingesetzt werden kann. Weitere Informationen hierzu siehe [Wöchentliches Update für io.js 2.1.0](https://nodejs.org/en/blog/weekly-updates/weekly-update.2015-05-22/#2-1-0).
+
+### Do logging correctly
+
+Im Allgemeinen gibt es für die Protokollierung Ihrer Anwendung zwei Gründe: 1) Debugging und 2) Protokollierung von Anwendungsaktivitäten (im Wesentlichen alles andere, außer Debugging). Die Verwendung von`console.log()` oder `console.err()` zur Ausgabe von Protokollnachrichten an das Terminal ist in der Entwicklung gängige Praxis. But [these functions are synchronous](https://nodejs.org/api/console#console) when the destination is a terminal or a file, so they are not suitable for production, unless you pipe the output to another program.
+
+#### Für Debuggingzwecke
+
+Wenn Sie die Protokollierung für Debuggingzwecke nutzen, sollten Sie statt `console.log()` besser ein spezielles Debuggingmodul wie [debug](https://www.npmjs.com/package/debug) verwenden. Mit einem solchen Modul können Sie über die Umgebungsvariable DEBUG steuern, welche Debugnachrichten an `console.err()` gesendet werden (falls vorhanden). Um Ihre Anwendung rein asynchron zu halten, können Sie trotzdem `console.err()` per Pipe zu einem anderen Programm umleiten. Sie nehmen dann aber kein Debugging in der Produktionsumgebung vor, richtig?
+
+#### Für Anwendungsaktivitäten
+
+If you're logging app activity (for example, tracking traffic or API calls), instead of using `console.log()`, use a logging library like [Pino](https://www.npmjs.com/package/pino), which is the fastest and most efficient option available.
+
+### Ausnahmebedingungen ordnungsgemäß handhaben
+
+Node-Anwendungen stürzen ab, wenn eine nicht abgefangene Ausnahmebedingung vorkommt. Wenn diese Ausnahmebedingungen nicht behandelt und entsprechende Maßnahmen eingeleitet werden, stürzt Ihre Express-Anwendung ab und geht offline. Wenn Sie dem nachfolgenden Rat in [Sicherstellen, dass Ihre Anwendung automatisch neu gestartet wird](#restart) folgen, wird Ihre Anwendung nach einem Absturz wiederhergestellt. Glücklicherweise haben Express-Anwendungen nur eine kurze Initialisierungszeit. Nevertheless, you want to avoid crashing in the first place, and to do that, you need to handle exceptions properly.
+
+Mit folgenden Verfahren stellen Sie sicher, dass alle Ausnahmebedingungen gehandhabt werden:
+
+- ["try-catch" verwenden](#try-catch)
+- ["Promises" verwenden](#promises)
+
+Um näher auf diese Themen eingehen zu können, müssen Sie sich ein grundlegendes Verständnis der Fehlerbehandlung in Node und Express aneignen: Verwendung von Error-first-Callbacks und Propagieren von Fehlern in Middleware. Node verwendet die Konvention "Error-first-Callback" für die Rückgabe von Fehlern von asynchronen Funktionen, bei denen der erste Parameter zur Callback-Funktion das Fehlerobjekt ist, gefolgt von Ergebnisdaten in den nachfolgenden Parametern. Um anzugeben, dass kein Fehler vorliegt, müssen Sie "null" als ersten Parameter übergeben. Die Callback-Funktion muss der Konvention "Error-first-Callback" folgen, um den Fehler sinnvoll bearbeiten zu können. In Express hat sich bewährt, die Funktion "next()" zu verwenden, um Fehler über die Middleware-Chain zu propagieren.
+
+Weitere Informationen zu den Grundlagen der Fehlerbehandlung siehe:
+
+- [Fehlerbehandlung in Node.js](https://www.tritondatacenter.com/node-js/production/design/errors)
+
+#### "try-catch" verwenden
+
+"try-catch" ist ein JavaScript-Sprachkonstrukt, mit dem Sie Ausnahmebedingungen in synchronem Code abfangen können. Verwenden Sie "try-catch" beispielsweise, um JSON-Parsing-Fehler wie unten gezeigt zu bearbeiten.
+
+Dies ist ein Beispiel zur Verwendung von "try-catch", um eine potenzielle "process-crashing"-Ausnahmebedingung zu handhaben.
+Diese Middlewarefunktion akzeptiert einen Abfragefeldparameter mit dem Namen "params", der ein JSON-Objekt ist.
+
+```js
+app.get('/search', (req, res) => {
+ // Simulating async operation
+ setImmediate(() => {
+ const jsonStr = req.query.params;
+ try {
+ const jsonObj = JSON.parse(jsonStr);
+ res.send('Success');
+ } catch (e) {
+ res.status(400).send('Invalid JSON string');
+ }
+ });
+});
+```
+
+"try-catch" funktioniert jedoch nur in synchronem Code. Da die Node-Plattform primär asynchron ist (insbesondere in einer Produktionsumgebung), lassen sich mit "try-catch" nicht besonders viele Ausnahmebedingungen abfangen.
+
+#### "Promises" verwenden
+
+When an error is thrown in an `async` function or a rejected promise is awaited inside an `async` function, those errors will be passed to the error handler as if calling `next(err)`
+
+```js
+app.get('/', async (req, res, next) => {
+ const data = await userData(); // If this promise fails, it will automatically call `next(err)` to handle the error.
+
+ res.send(data);
+});
+
+app.use((err, req, res, next) => {
+ res.status(err.status ?? 500).send({ error: err.message });
+});
+```
+
+Also, you can use asynchronous functions for your middleware, and the router will handle errors if the promise fails, for example:
+
+```js
+app.use(async (req, res, next) => {
+ req.locals.user = await getUser(req);
+
+ next(); // This will be called if the promise does not throw an error.
+});
+```
+
+Best practice is to handle errors as close to the site as possible. So while this is now handled in the router, it’s best to catch the error in the middleware and handle it without relying on separate error-handling middleware.
+
+#### What not to do
+
+Sie sollten _auf keinen_ Fall per Listener das Ereignis `uncaughtException` überwachen, das ausgegeben wird, wenn eine Ausnahmebedingung bis zurück zur Ereignisschleife bestehen bleibt. Durch das Hinzufügen eines Ereignislisteners für `uncaughtException` verändert sich das Standardverhalten des Prozesses, über das eine Ausnahmebedingung festgestellt wird. Das Ausführen einer Anwendung nach einer nicht abgefangenen Ausnahmebedingung ist aber eine durchaus riskante Vorgehensweise und wird nicht empfohlen, da der Prozessstatus störanfällig und unvorhersehbar wird.
+
+Außerdem wird die Verwendung von `uncaughtException` offiziell als [grobes Vorgehen](https://nodejs.org/api/process#process_event_uncaughtexception) angesehen, sodass es den [Vorschlag](https://github.com/nodejs/node-v0.x-archive/issues/2582) gibt, die Funktion aus dem Kern zu entfernen. Das Überwachen von `uncaughtException` per Listener ist also keine gute Idee. Daher empfehlen wir Dinge wie Mehrfachprozesse und Supervisoren: Ein Absturz und anschließender Neustart ist häufig die zuverlässigste Art der Fehlerbehebung.
+
+Zudem empfehlen wir, [domains](https://nodejs.org/api/domain) nicht zu verwenden. Mit diesem Modul, das zudem veraltet ist, lässt sich das Problem in der Regel nicht lösen.
+
+## Things to do in your environment / setup {#in-environment}
+
+Dies sind einige Beispiele für Maßnahmen, die Sie an Ihrer Systemumgebung vornehmen können, um die Anwendungsleistung zu verbessern:
+
+- NODE_ENV auf "production" festlegen
+- Automatischen Neustart Ihrer Anwendung sicherstellen
+- Anwendung in einem Cluster ausführen
+- Anforderungsergebnisse im Cache speichern
+- Load Balancer verwenden
+- Reverse Proxy verwenden
+
+### NODE_ENV auf "production" festlegen
+
+In der Umgebungsvariablen NODE_ENV wird die Umgebung angegeben, in der eine Anwendung ausgeführt wird (in der Regel ist dies die Entwicklungs- oder Produktionsumgebung). One of the simplest things you can do to improve performance is to set NODE_ENV to `production`.
+
+Durch das Festlegen von NODE_ENV auf "production" führt Express Folgendes aus:
+
+- Speichern von Anzeigevorlagen im Cache.
+- Speichern von CSS-Dateien, die aus CSS-Erweiterungen generiert wurden, im Cache.
+- Generieren von weniger ausführlichen Fehlernachrichten.
+
+[Tests indicate](https://www.dynatrace.com/news/blog/the-drastic-effects-of-omitting-node-env-in-your-express-js-applications/) that just doing this can improve app performance by a factor of three!
+
+Wenn Sie umgebungsspezifischen Code schreiben müssen, können Sie den Wert von NODE_ENV mit `process.env.NODE_ENV` überprüfen. Beachten Sie, dass die Überprüfung des Werts seiner Umgebungsvariablen eine leistungsbezogene Penalisierung nach sich zieht.
+
+In einer Entwicklungsumgebung wird die Umgebungsvariable in der Regel in Ihrer interaktiven Shell festgelegt, indem Sie beispielsweise `export` oder Ihre Datei `.bash_profile` verwenden. But in general, you shouldn't do that on a production server; instead, use your OS's init system (systemd). Der nächste Abschnitt enthält weitere Details zur Verwendung des Init-Systems im Allgemeinen. Die Festlegung von NODE_ENV ist jedoch für das Leistungsverhalten so wichtig (und so einfach durchzuführen), dass hier besonders darauf eingegangen wird.
+
+Verwenden Sie bei systemd die Anweisung `Environment` in Ihrer Einheitendatei. Beispiel:
+
+```sh
+# /etc/systemd/system/myservice.service
+Environment=NODE_ENV=production
+```
+
+For more information, see [Using Environment Variables In systemd Units](https://www.flatcar.org/docs/latest/setup/systemd/environment-variables/).
+
+### Automatischen Neustart Ihrer Anwendung sicherstellen
+
+In der Produktionsumgebung sollte die Anwendung nie offline sein. Das bedeutet, dass Sie sicherstellen müssen, dass die Anwendung bei einem Absturz der Anwendung oder des Servers immer wieder neu gestartet wird. Auch wenn man hofft, das keines dieser Ereignisse jemals eintritt, muss man doch mit beiden Möglichkeiten rechnen und:
+
+- einen Prozessmanager verwenden, um die Anwendung (und Node) bei einem Absturz neu zu starten.
+- das Init-System Ihres Betriebssystems verwenden, um den Prozessmanager bei einem Absturz des Betriebssystems neu zu starten. Außerdem kann das Init-System auch ohne einen Prozessmanager verwendet werden.
+
+Node-Anwendungen stürzen ab, wenn eine nicht abgefangene Ausnahmebedingung auftritt. Als Erstes müssen Sie in einem solchen Fall sicherstellen, dass Ihre Anwendung ausreichend getestet wurde und in der Lage ist, alle Ausnahmebedingungen zu handhaben (weitere Informationen siehe [Ausnahmebedingungen ordnungsgemäß handhaben](#exceptions)). Die sicherste Maßnahme ist jedoch, einen Mechanismus zu implementieren, über den bei einem Absturz der Anwendung ein automatischer Neustart der Anwendung ausgeführt wird.
+
+#### Prozessmanager verwenden
+
+In Entwicklungumgebungen wird die Anwendung einfach über die Befehlszeile mit `node server.js` oder einer vergleichbaren Datei gestartet. In der Produktionsumgebung hingegen ist durch diese Vorgehensweise die Katastrophe bereits vorprogrammiert. Wenn die Anwendung abstürzt, ist sie solange offline, bis Sie sie erneut starten. Um sicherzustellen, dass Ihre Anwendung nach einem Absturz neu gestartet wird, sollten Sie einen Prozessmanager verwenden. Ein Prozessmanager ist ein "Container" für Anwendungen, der die Bereitstellung erleichtert, eine hohe Verfügbarkeit sicherstellt und die Verwaltung der Anwendung zur Laufzeit ermöglicht.
+
+Neben einem Neustart der Anwendung nach einem Absturz bietet ein Prozessmanager noch weitere Möglichkeiten:
+
+- Einblicke in die Laufzeitleistung und die Ressourcennutzung
+- Dynamische Änderung der Einstellungen zur Verbesserung des Leistungsverhaltens
+- Control clustering (pm2).
+
+Historically, it was popular to use a Node.js process manager like [PM2](https://github.com/Unitech/pm2). See their documentation if you wish to do this. However, we recommend using your init system for process management.
+
+#### Init-System verwenden
+
+Als nächste Ebene der Zuverlässigkeit müssen Sie sicherstellen, dass Ihre Anwendung bei einem Serverneustart neu gestartet wird. Systeme können immer wieder aus verschiedenen Gründen abstürzen. Um sicherzustellen, dass Ihre Anwendung bei einem Serverabsturz neu gestartet wird, können Sie das in Ihr Betriebssystem integrierte Init-System verwenden. The main init system in use today is [systemd](https://wiki.debian.org/systemd).
+
+Es gibt zwei Möglichkeiten, Init-Systeme mit Ihrer Express-Anwendung zu verwenden:
+
+- Ausführung Ihrer Anwendung in einem Prozessmanager und Installation des Prozessmanagers als Service mit dem Init-System. Der Prozessmanager wird neu gestartet, wenn Ihre Anwendung abstürzt. Dies ist die empfohlene Vorgehensweise.
+- Ausführung Ihrer Anwendung (und von Node) direkt mit dem Init-System. Diese Vorgehensweise ist zwar etwas einfacher, Sie profitieren jedoch nicht von den zusätzlichen Vorteilen des Einsatzes eines Prozessmanagers.
+
+##### systemd
+
+"systemd" ist ein Linux-System und Service-Manager. Die meisten wichtigen Linux-Distributionen haben "systemd" als Init-Standardsystem übernommen.
+
+Eine "systemd"-Servicekonfigurationsdatei wird als _Einheitendatei_ bezeichnet, die die Endung ".service" hat. Dies ist ein Beispiel für eine Einheitendatei zur direkten Verwaltung einer Node-Anwendung (ersetzen Sie den Text in Fettdruck durch Werte für Ihr System und Ihre Anwendung): Replace the values enclosed in `` for your system and app:
+
+```sh
+[Unit]
+Description=
+
+[Service]
+Type=simple
+ExecStart=/usr/local/bin/node
+WorkingDirectory=
+
+User=nobody
+Group=nogroup
+
+# Environment variables:
+Environment=NODE_ENV=production
+
+# Allow many incoming connections
+LimitNOFILE=infinity
+
+# Allow core dumps for debugging
+LimitCORE=infinity
+
+StandardInput=null
+StandardOutput=syslog
+StandardError=syslog
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
+```
+
+Weitere Informationen zu "systemd" siehe [systemd-Referenz (Man-Page)](http://www.freedesktop.org/software/systemd/man/systemd.unit).
+
+### Anwendung in einem Cluster ausführen
+
+In einem Multi-Core-System können Sie die Leistung einer Node-Anwendung mehrmals erhöhen, indem Sie einen Cluster von Prozessen starten. Ein Cluster führt mehrere Instanzen der Anwendung aus, idealerweise eine Instanz auf jedem CPU-Core.
+
+
+
+Wichtig. Da die Anwendungsinstanzen als separate Prozesse ausgeführt werden, nutzen sie nicht dieselbe Hauptspeicherkapazität gemeinsam. Das heißt, Objekte befinden sich für jede Instanz der Anwendung auf lokaler Ebene. Daher kann der Status im Anwendungscode nicht beibehalten werden. Sie können jedoch einen speicherinternen Datenspeicher wie [Redis](http://redis.io/) verwenden, um sitzungsrelevante Daten und Statusinformationen zu speichern. Diese Einschränkung trifft im Wesentlichen auf alle Formen der horizontalen Skalierung zu, unabhängig davon, ob es sich um Clustering mit mehreren Prozessen oder mehreren physischen Servern handelt.
+
+Bei in Gruppen zusammengefassten Anwendungen (geclusterte Anwendungen) können Verarbeitungsprozesse einzeln ausfallen, ohne dass sich dies auf die restlichen Prozesse auswirkt. Neben den Leistungsvorteilen ist die Fehlerisolierung ein weiterer Grund, einen Cluster von Anwendungsprozessen auszuführen. Wenn ein Verarbeitungsprozess abstürzt, müssen Sie sicherstellen, dass das Ereignis protokolliert und ein neuer Prozess mithilfe von "cluster.fork()" gestartet wird.
+
+#### Clustermodule von Node verwenden
+
+Clustering is made possible with Node's [cluster module](https://nodejs.org/api/cluster). Dadurch wird ein Masterprozess eingeleitet, um Verarbeitungsprozesse zu starten und eingehende Verbindungen auf die Verarbeitungsprozesse zu verteilen.
+
+#### Using PM2
+
+If you deploy your application with PM2, then you can take advantage of clustering _without_ modifying your application code. You should ensure your [application is stateless](https://pm2.keymetrics.io/docs/usage/specifics/#stateless-apps) first, meaning no local data is stored in the process (such as sessions, websocket connections and the like).
+
+When running an application with PM2, you can enable **cluster mode** to run it in a cluster with a number of instances of your choosing, such as the matching the number of available CPUs on the machine. You can manually change the number of processes in the cluster using the `pm2` command line tool without stopping the app.
+
+To enable cluster mode, start your application like so:
+
+```bash
+# Start 4 worker processes
+$ pm2 start npm --name my-app -i 4 -- start
+# Auto-detect number of available CPUs and start that many worker processes
+$ pm2 start npm --name my-app -i max -- start
+```
+
+This can also be configured within a PM2 process file (`ecosystem.config.js` or similar) by setting `exec_mode` to `cluster` and `instances` to the number of workers to start.
+
+Once running, the application can be scaled like so:
+
+```bash
+# Add 3 more workers
+$ pm2 scale my-app +3
+# Scale to a specific number of workers
+$ pm2 scale my-app 2
+```
+
+For more information on clustering with PM2, see [Cluster Mode](https://pm2.keymetrics.io/docs/usage/cluster-mode/) in the PM2 documentation.
+
+### Anforderungsergebnisse im Cache speichern
+
+Eine weitere Strategie zur Verbesserung des Leistungsverhaltens in Produktionsumgebungen ist das Speichern von Anforderungergebnissen im Cache. Ihre Anwendung muss also diese Operation nicht wiederholt ausführen, um dieselbe Anforderung wiederholt zu bedienen.
+
+Use a caching server like [Varnish](https://www.varnish-cache.org/) or [Nginx](https://blog.nginx.org/blog/nginx-caching-guide) (see also [Nginx Caching](https://serversforhackers.com/nginx-caching/)) to greatly improve the speed and performance of your app.
+
+### Load Balancer verwenden
+
+Unabhängig davon, wie gut eine Anwendung optimiert wurde, kann eine Einzelinstanz nur eine begrenzte Arbeitslast oder einen begrenzten Datenverkehr handhaben. Eine Möglichkeit, eine Anwendung zu skalieren, ist die Ausführung mehrerer Instanzen dieser Anwendung und die Verteilung des Datenverkehrs über eine Lastausgleichsfunktion (Load Balancer) vorzunehmen. Die Einrichtung eines solchen Load Balancer kann helfen, Leistung und Geschwindigkeit Ihrer Anwendung zu verbessern.
+
+Ein Load Balancer ist in der Regel ein Reverse Proxy, der den Datenverkehr zu und von mehreren Anwendungsinstanzen und Servern koordiniert. You can easily set up a load balancer for your app by using [Nginx](https://nginx.org/en/docs/http/load_balancing) or [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts).
+
+Bei einer solchen Lastverteilung müssen Sie sicherstellen, dass Anforderungen, die einer bestimmten Sitzungs-ID zugeordnet sind, mit dem Prozess verbunden sind, von dem sie ursprünglich stammen. Dies wird auch als _Sitzungsaffinität_ oder _Affine Sitzungen_ bezeichnet und kann durch den obigen Vorschlag, einen Datenspeicher wie Redis für Sitzungsdaten zu verwenden (je nach Anwendung), umgesetzt werden. Eine Beschreibung hierzu siehe [Mehrere Knoten verwenden](https://socket.io/docs/v4/using-multiple-nodes/).
+
+### Reverse Proxy verwenden
+
+Ein Reverse Proxy befindet sich vor einer Webanwendung und führt Unterstützungsoperationen für die Anforderungen aus (außer das Weiterleiten von Anforderungen an die Anwendung). Fehlerseiten, Komprimierungen und Caching bearbeiten, Dateien bereitstellen und Lastverteilungen vornehmen.
+
+Durch die Übergabe von Tasks, die keine Kenntnis des Anwendungsstatus erfordern, an einen Reverse Proxy muss Express keine speziellen Anwendungstasks mehr ausführen. For this reason, it is recommended to run Express behind a reverse proxy like [Nginx](https://www.nginx.org/) or [HAProxy](https://www.haproxy.org/) in production.
diff --git a/astro/src/content/docs/de/5x/advanced/best-practice-security.md b/astro/src/content/docs/de/5x/advanced/best-practice-security.md
new file mode 100644
index 0000000000..32fdb44395
--- /dev/null
+++ b/astro/src/content/docs/de/5x/advanced/best-practice-security.md
@@ -0,0 +1,282 @@
+---
+title: Sicherheitsspezifische Best Practices für Express-Anwendungen in Produktionsumgebungen
+description: Discover crucial security best practices for Express apps in production, including using TLS, input validation, secure cookies, and preventing vulnerabilities.
+---
+
+# Best Practices in Produktionsumgebungen: Sicherheit
+
+## Überblick
+
+Der Begriff _"Produktion"_ bezieht sich auf die Phase im Softwarelebenszyklus, in der eine Anwendung oder API für Endbenutzer oder Verbraucher allgemein verfügbar ist. Im Gegensatz dazu wird in der Phase _"Entwicklung"_ noch aktiv Code geschrieben und getestet. Die Anwendung ist in dieser Phase noch nicht für externen Zugriff verfügbar. Die entsprechenden Systemumgebungen werden als _Produktionsumgebungen_ und _Entwicklungsumgebungen_ bezeichnet.
+
+Entwicklungs- und Produktionsumgebungen werden in der Regel unterschiedlich konfiguriert und weisen deutliche Unterschiede bei den Anforderungen auf. Was in der Entwicklung funktioniert, muss in der Produktion nicht unbedingt akzeptabel sein. Beispiel: In einer Entwicklungsumgebung ist eine ausführliche Protokollierung von Fehlern für Debuggingzwecke sinnvoll. Dieselbe Vorgehensweise kann in einer Produktionsumgebung jedoch zu einem Sicherheitsproblem führen. In einer Entwicklungsumgebung müssen Sie sich keine Gedanken zu Themen wie Skalierbarkeit, Zuverlässigkeit und Leistung machen, während dies in einer Produktionsumgebung kritische Faktoren sind.
+
+{% capture security-note %}
+
+If you believe you have discovered a security vulnerability in Express, please see
+[Security Policies and Procedures](/en/resources/contributing#security-policies-and-procedures).
+
+{% endcapture %}
+
+{% include admonitions/note.html content=security-note %}
+
+In diesem Beitrag werden einige der Best Practices in Bezug auf das Thema Sicherheit für Express-Anwendungen behandelt, die in der Produktionsumgebung bereitgestellt werden.
+
+- [Best Practices in Produktionsumgebungen: Sicherheit](#best-practices-in-produktionsumgebungen-sicherheit)
+ - [Überblick](#überblick)
+ - [Verwenden Sie keine veralteten oder anfälligen Versionen von Express](#verwenden-sie-keine-veralteten-oder-anfälligen-versionen-von-express)
+ - [TLS verwenden](#tls-verwenden)
+ - [Do not trust user input](#do-not-trust-user-input)
+ - [Prevent open redirects](#prevent-open-redirects)
+ - ["Helmet" verwenden](#helmet-verwenden)
+ - [Reduce fingerprinting](#reduce-fingerprinting)
+ - [Cookies sicher verwenden](#cookies-sicher-verwenden)
+ - [Verwenden Sie nicht den standardmäßigen Namen des Sitzungscookies](#verwenden-sie-nicht-den-standardmäßigen-namen-des-sitzungscookies)
+ - [Cookie-Sicherheitsoptionen festlegen](#cookie-sicherheitsoptionen-festlegen)
+ - [Prevent brute-force attacks against authorization](#prevent-brute-force-attacks-against-authorization)
+ - [Ensure your dependencies are secure](#ensure-your-dependencies-are-secure)
+ - [Vermeiden Sie andere Schwachstellen](#vermeiden-sie-andere-schwachstellen)
+ - [Weitere Überlegungen](#weitere-überlegungen)
+
+## Verwenden Sie keine veralteten oder anfälligen Versionen von Express
+
+Express 2.x und 3.x werden nicht mehr gepflegt. Sicherheits- und Leistungsprobleme in diesen Versionen werden nicht mehr behoben. Verwenden Sie diese Versionen nicht! Wenn Sie noch nicht auf Version 4 umgestellt haben, befolgen Sie die Anweisungen im [Migrationshandbuch](/en/guide/migrating-4).
+
+Stellen Sie außerdem sicher, dass Sie keine anfälligen Express-Versionen verwenden, die auf der [Seite mit den Sicherheitsupdates](/en/advanced/security-updates) aufgelistet sind. Falls doch, führen Sie ein Update auf eines der stabileren Releases durch, bevorzugt das aktuelle Release.
+
+## TLS verwenden
+
+Wenn über Ihre Anwendung vertrauliche Daten bearbeitet oder übertragen werden, sollten Sie [Transport Layer Security](https://en.wikipedia.org/wiki/Transport_Layer_Security) (TLS) verwenden, um die Verbindung und die Daten zu schützen. Diese Technologie verschlüsselt Daten, bevor sie vom Client zum Server gesendet werden. Dadurch lassen sich einige gängige (und einfache) Hackerattacken vermeiden. Auch wenn Ajax- und POST-Anforderungen nicht sofort offensichtlich und in Browsern "versteckt" zu sein scheinen, ist deren Netzverkehr anfällig für das [Ausspionieren von Paketen](https://en.wikipedia.org/wiki/Packet_analyzer) und [Man-in-the-Middle-Attacken](https://en.wikipedia.org/wiki/Man-in-the-middle_attack).
+
+Möglicherweise sind Sie mit SSL-Verschlüsselung (Secure Socket Layer) bereits vertraut. [TLS ist einfach der nächste Entwicklungsschritt bei SSL](). In anderen Worten: Wenn Sie bisher SSL verwendet haben, sollten Sie ein Upgrade auf TLS in Erwägung ziehen. Generell empfehlen wir für TLS den Nginx-Server. Eine gute Referenz zum Konfigurieren von TLS auf Nginx (und anderen Servern) ist [Empfohlene Serverkonfigurationen (Mozilla Wiki)](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations).
+
+Ein handliches Tool zum Abrufen eines kostenloses TLS-Zertifikats ist außerdem [Let's Encrypt](https://letsencrypt.org/about/), eine kostenlose, automatisierte und offene Zertifizierungsstelle der [Internet Security Research Group (ISRG)](https://www.abetterinternet.org/).
+
+## Do not trust user input
+
+For web applications, one of the most critical security requirements is proper user input validation and handling. This comes in many forms and we will not cover all of them here.
+Ultimately, the responsibility for validating and correctly handling the types of user input your application accepts is yours.
+
+### Prevent open redirects
+
+An example of potentially dangerous user input is an _open redirect_, where an application accepts a URL as user input (often in the URL query, for example `?url=https://example.com`) and uses `res.redirect` to set the `location` header and
+return a 3xx status.
+
+An application must validate that it supports redirecting to the incoming URL to avoid sending users to malicious links such as phishing websites, among other risks.
+
+Here is an example of checking URLs before using `res.redirect` or `res.location`:
+
+```js
+app.use((req, res) => {
+ try {
+ if (new Url(req.query.url).host !== 'example.com') {
+ return res.status(400).end(`Unsupported redirect to host: ${req.query.url}`);
+ }
+ } catch (e) {
+ return res.status(400).end(`Invalid url: ${req.query.url}`);
+ }
+ res.redirect(req.query.url);
+});
+```
+
+## "Helmet" verwenden
+
+[Helmet](https://www.npmjs.com/package/helmet) kann beim Schutz Ihrer Anwendung gegen einige gängige Schwachstellen hilfreiche Dienste leisten, indem die HTTP-Header entsprechend konfiguriert werden.
+
+Helmet is a middleware function that sets security-related HTTP response headers. Helmet sets the following headers by default:
+
+- `Content-Security-Policy`: A powerful allow-list of what can happen on your page which mitigates many attacks
+- `Cross-Origin-Opener-Policy`: Helps process-isolate your page
+- `Cross-Origin-Resource-Policy`: Blocks others from loading your resources cross-origin
+- `Origin-Agent-Cluster`: Changes process isolation to be origin-based
+- `Referrer-Policy`: Controls the [`Referer`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) header
+- `Strict-Transport-Security`: Tells browsers to prefer HTTPS
+- `X-Content-Type-Options`: Avoids [MIME sniffing](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing)
+- `X-DNS-Prefetch-Control`: Controls DNS prefetching
+- `X-Download-Options`: Forces downloads to be saved (Internet Explorer only)
+- `X-Frame-Options`: Legacy header that mitigates [Clickjacking](https://en.wikipedia.org/wiki/Clickjacking) attacks
+- `X-Permitted-Cross-Domain-Policies`: Controls cross-domain behavior for Adobe products, like Acrobat
+- `X-Powered-By`: Info about the web server. Removed because it could be used in simple attacks
+- `X-XSS-Protection`: Legacy header that tries to mitigate [XSS attacks](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting), but makes things worse, so Helmet disables it
+
+Each header can be configured or disabled. To read more about it please go to [its documentation website][helmet].
+
+Installieren Sie "Helmet" wie alle anderen Module:
+
+```bash
+$ npm install helmet
+```
+
+So verwenden Sie "Helmet" in Ihrem Code:
+
+```js
+// ...
+
+const helmet = require('helmet');
+app.use(helmet());
+
+// ...
+```
+
+## Reduce fingerprinting
+
+It can help to provide an extra layer of security to reduce the ability of attackers to determine
+the software that a server uses, known as "fingerprinting." Though not a security issue itself,
+reducing the ability to fingerprint an application improves its overall security posture.
+Server software can be fingerprinted by quirks in how it responds to specific requests, for example in
+the HTTP response headers.
+
+Ein bewährtes Verfahren ist also, diesen Header mit der Methode `app.disable()` zu deaktivieren:
+
+```js
+app.disable('x-powered-by');
+```
+
+{% capture powered-advisory %}
+
+Disabling the `X-Powered-By header` does not prevent
+a sophisticated attacker from determining that an app is running Express. It may
+discourage a casual exploit, but there are other ways to determine an app is running
+Express.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=powered-advisory %}
+
+Express also sends its own formatted "404 Not Found" messages and formatter error
+response messages. These can be changed by
+[adding your own not found handler](/en/starter/faq#how-do-i-handle-404-responses)
+and
+[writing your own error handler](/en/guide/error-handling#writing-error-handlers):
+
+```js
+// last app.use calls right before app.listen():
+
+// custom 404
+app.use((req, res, next) => {
+ res.status(404).send("Sorry can't find that!");
+});
+
+// custom error handler
+app.use((err, req, res, next) => {
+ console.error(err.stack);
+ res.status(500).send('Something broke!');
+});
+```
+
+## Cookies sicher verwenden
+
+Um sicherzustellen, dass Cookies Ihre Anwendung nicht für Angriffsmöglichkeiten öffnen, sollten Sie den standardmäßigen Namen des Sitzungscookies nicht verwenden und die Cookie-Sicherheitsoptionen entsprechend festlegen.
+
+Es gibt zwei wesentliche Middleware-Cookie-Sitzungsmodule:
+
+- [express-session](https://www.npmjs.com/package/express-session), das in Express 3.x integrierte `express.session`-Middleware ersetzt.
+- [cookie-session](https://www.npmjs.com/package/cookie-session), das in Express 3.x integrierte `express.cookieSession`-Middleware ersetzt.
+
+Der Hauptunterschied zwischen diesen beiden Modulen liegt darin, wie die Cookie-Sitzungsdaten gespeichert werden. Die [express-session](https://www.npmjs.com/package/express-session)-Middleware speichert Sitzungsdaten auf dem Server. Sie speichert nur die Sitzungs-ID im Cookie und nicht die Sitzungsdaten. Standardmäßig wird dabei der speicherinterne Speicher verwendet. Eine Verwendung der Middleware in der Produktionsumgebung ist nicht vorgesehen. In der Produktionsumgebung müssen Sie einen skalierbaren "Session-Store" einrichten. Siehe hierzu die Liste der [kompatiblen Session-Stores](https://github.com/expressjs/session#compatible-session-stores).
+
+Im Gegensatz dazu implementiert die [cookie-session](https://www.npmjs.com/package/cookie-session)-Middleware cookiegestützten Speicher: Sie serialisiert die gesamte Sitzung zum Cookie und nicht nur einen Sitzungsschlüssel. Diese Middleware sollten Sie nur verwenden, wenn Sitzungsdaten relativ klein sind und einfach als primitive Werte (und nicht als Objekte) codiert sind. Auch wenn Browser mindestens 4096 Byte pro Cookie unterstützen sollten, müssen Sie sicherstellen, dass dieses Limit nicht überschritten wird. Überschreiten Sie auf keinen Fall die Größe von 4093 Byte pro Domäne. Achten Sie zudem darauf, dass die Cookiedaten für den Client sichtbar sind. Wenn also ein Grund vorliegt, die Daten sicher oder unkenntlich zu machen, ist "express-session" möglicherweise die bessere Wahl.
+
+### Verwenden Sie nicht den standardmäßigen Namen des Sitzungscookies
+
+Die Verwendung des standardmäßigen Namens des Sitzungscookies kann Ihre Anwendung anfällig für Attacken machen. Das mögliche Sicherheitsproblem ist vergleichbar mit `X-Powered-By`: ein potenzieller Angreifer kann diesen Header verwenden, um einen elektronischen Fingerabdruck des Servers zu erstellen und Attacken entsprechend zu platzieren.
+
+Über [noSniff](https://github.com/helmetjs/dont-sniff-mimetype) werden `X-Content-Type-Options`-Header festgelegt, um bei Browsern MIME-Sniffing von Antworten weg vom deklarierten Inhaltstyp (declared content-type) vorzubeugen.
+
+```js
+const session = require('express-session');
+app.set('trust proxy', 1); // trust first proxy
+app.use(
+ session({
+ secret: 's3Cur3',
+ name: 'sessionId',
+ })
+);
+```
+
+### Cookie-Sicherheitsoptionen festlegen
+
+Legen Sie die folgenden Cookieoptionen fest, um die Sicherheit zu erhöhen:
+
+- `secure` - Stellt sicher, dass der Browser das Cookie nur über HTTPS sendet.
+- `httpOnly` - Stellt sicher, dass das Cookie nur über HTTP(S) und nicht über das Client-JavaScript gesendet wird und dadurch Schutz gegen Cross-Site Scripting-Attacken besteht.
+- `domain` - Gibt die Domäne des Cookies an, die für den Vergleich mit der Domäne des Servers verwendet wird, in der die URL angefordert wird. Stimmen diese beiden überein, müssen Sie das Pfadattribut überprüfen.
+- `path` - Gibt den Pfad des Cookies an, der für den Vergleich mit dem Anforderungspfad verwendet wird. Wenn dieser Pfad und die Domäne übereinstimmen, können Sie das Cookie in der Anforderung senden.
+- `expires` - Wird verwendet, um das Ablaufdatum für persistente Cookies festzulegen.
+
+Dies ist ein Beispiel zur Verwendung der [cookie-session](https://www.npmjs.com/package/cookie-session)-Middleware:
+
+```js
+const session = require('cookie-session');
+const express = require('express');
+const app = express();
+
+const expiryDate = new Date(Date.now() + 60 * 60 * 1000); // 1 hour
+app.use(
+ session({
+ name: 'session',
+ keys: ['key1', 'key2'],
+ cookie: {
+ secure: true,
+ httpOnly: true,
+ domain: 'example.com',
+ path: 'foo/bar',
+ expires: expiryDate,
+ },
+ })
+);
+```
+
+## Prevent brute-force attacks against authorization
+
+Make sure login endpoints are protected to make private data more secure.
+
+A simple and powerful technique is to block authorization attempts using two metrics:
+
+1. The number of consecutive failed attempts by the same user name and IP address.
+2. The number of failed attempts from an IP address over some long period of time. For example, block an IP address if it makes 100 failed attempts in one day.
+
+[rate-limiter-flexible](https://github.com/animir/node-rate-limiter-flexible) package provides tools to make this technique easy and fast. You can find [an example of brute-force protection in the documentation](https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#login-endpoint-protection)
+
+## Ensure your dependencies are secure
+
+Using npm to manage your application's dependencies is powerful and convenient. But the packages that you use may contain critical security vulnerabilities that could also affect your application. The security of your app is only as strong as the "weakest link" in your dependencies.
+
+Since npm@6, npm automatically reviews every install request. Also, you can use `npm audit` to analyze your dependency tree.
+
+```bash
+$ npm audit
+```
+
+If you want to stay more secure, consider [Snyk](https://snyk.io/).
+
+Snyk offers both a [command-line tool](https://www.npmjs.com/package/snyk) and a [Github integration](https://snyk.io/docs/github) that checks your application against [Snyk's open source vulnerability database](https://snyk.io/vuln/) for any known vulnerabilities in your dependencies. Install the CLI as follows:
+
+```bash
+$ npm install -g snyk
+$ cd your-app
+```
+
+Use this command to test your application for vulnerabilities:
+
+```bash
+$ snyk test
+```
+
+### Vermeiden Sie andere Schwachstellen
+
+Achten Sie auf [Node Security Project](https://npmjs.com/advisories)-Empfehlungen, die Express oder andere Module, die Ihre Anwendung nutzt, beeinträchtigen können. Im Allgemeinen ist Node Security Project aber eine exzellente Ressource mit Wissen und Tools zur Sicherheit von Node.
+
+Letztendlich können Express-Anwendungen – wie viele andere Webanwendungen auch – anfällig für eine Vielzahl webbasierter Attacken sein. Machen Sie sich deshalb mit bekannten [webspezifischen Schwachstellen](https://www.owasp.org/www-project-top-ten/) vertraut und treffen Sie die geeigneten Vorkehrungen, um diese zu vermeiden.
+
+## Weitere Überlegungen
+
+Dies sind einige weitere Empfehlungen aus der hervorragenden [Node.js Security Checklist](https://blog.risingstack.com/node-js-security-checklist/). In diesem Blogbeitrag finden Sie alle Details zu diesen Empfehlungen:
+
+- Filtern und bereinigen Sie immer Benutzereingaben, um sich gegen XS-Angriffe (Cross-Site Scripting) und Befehlsinjektionsattacken zu schützen.
+- Implementieren Sie Verteidungsmaßnahmen gegen SQL-Injection-Attacken, indem sie parametrisierte Abfragen oder vorbereitete Anweisungen einsetzen.
+- Nutzen Sie das Open-Source-Tool [sqlmap](http://sqlmap.org/), um SQL-Injection-Schwachstellen in Ihrer Anwendung zu erkennen.
+- Verwenden Sie die Tools [nmap](https://nmap.org/) und [sslyze](https://github.com/nabla-c0d3/sslyze), um die Konfiguration Ihrer SSL-Verschlüsselungen, -Schlüssel und Neuvereinbarungen sowie die Gültigkeit Ihres Zertifikats zu testen.
+- Verwenden Sie [safe-regex](https://www.npmjs.com/package/safe-regex), um sicherzustellen, dass Ihre regulären Ausdrücke nicht für [Denial-of-Service-Attacken](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS) anfällig sind.
+
+[helmet]:
diff --git a/astro/src/content/docs/de/5x/advanced/developing-template-engines.md b/astro/src/content/docs/de/5x/advanced/developing-template-engines.md
new file mode 100644
index 0000000000..354927776d
--- /dev/null
+++ b/astro/src/content/docs/de/5x/advanced/developing-template-engines.md
@@ -0,0 +1,45 @@
+---
+title: Template-Engines für Express entwickeln
+description: Learn how to develop custom template engines for Express.js using app.engine(), with examples on creating and integrating your own template rendering logic.
+---
+
+# Template-Engines für Express entwickeln
+
+Verwenden Sie die Methode `app.engine(ext, callback)`, um Ihre eigene Template-Engine zu erstellen. `ext` bezieht sich auf die Dateierweiterung, `callback` ist die Template-Engine-Funktion, die die folgenden Elemente als Parameter akzeptiert: die Position der Datei, das Optionsobjekt und die Callback-Funktion.
+
+Der folgende Code ist ein Beispiel für die Implementierung einer sehr einfachen Template-Engine für die Ausgabe von `.ntl`-Dateien.
+
+```js
+const fs = require('fs'); // this engine requires the fs module
+app.engine('ntl', (filePath, options, callback) => {
+ // define the template engine
+ fs.readFile(filePath, (err, content) => {
+ if (err) return callback(err);
+ // this is an extremely simple template engine
+ const rendered = content
+ .toString()
+ .replace('#title#', `${options.title} `)
+ .replace('#message#', `${options.message} `);
+ return callback(null, rendered);
+ });
+});
+app.set('views', './views'); // specify the views directory
+app.set('view engine', 'ntl'); // register the template engine
+```
+
+Ihre Anwendung ist jetzt in der Lage, `.ntl`-Dateien auszugeben. Erstellen Sie im Verzeichnis `views` eine Datei namens `index.ntl` mit dem folgenden Inhalt.
+
+```pug
+#title#
+#message#
+```
+
+Erstellen Sie dann in Ihrer Anwendung die folgende Route.
+
+```js
+app.get('/', (req, res) => {
+ res.render('index', { title: 'Hey', message: 'Hello there!' });
+});
+```
+
+Wenn Sie eine Anforderung zur Homepage einleiten, wird `index.ntl` im HTML-Format ausgegeben.
diff --git a/astro/src/content/docs/de/5x/advanced/healthcheck-graceful-shutdown.md b/astro/src/content/docs/de/5x/advanced/healthcheck-graceful-shutdown.md
new file mode 100644
index 0000000000..545baf7174
--- /dev/null
+++ b/astro/src/content/docs/de/5x/advanced/healthcheck-graceful-shutdown.md
@@ -0,0 +1,30 @@
+---
+title: Health Checks and Graceful Shutdown
+description: Learn how to implement health checks and graceful shutdown in Express apps to enhance reliability, manage deployments, and integrate with load balancers like Kubernetes.
+---
+
+# Health Checks and Graceful Shutdown
+
+## Graceful shutdown
+
+When you deploy a new version of your application, you must replace the previous version. The process manager you're using will first send a SIGTERM signal to the application to notify it that it will be killed. Once the application gets this signal, it should stop accepting new requests, finish all the ongoing requests, clean up the resources it used, including database connections and file locks then exit.
+
+### Beispiel
+
+```js
+const server = app.listen(port);
+
+process.on('SIGTERM', () => {
+ debug('SIGTERM signal received: closing HTTP server');
+ server.close(() => {
+ debug('HTTP server closed');
+ });
+});
+```
+
+## Health checks
+
+A load balancer uses health checks to determine if an application instance is healthy and can accept requests. For example, [Kubernetes has two health checks](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/):
+
+- `liveness`, that determines when to restart a container.
+- `readiness`, that determines when a container is ready to start accepting traffic. When a pod is not ready, it is removed from the service load balancers.
diff --git a/astro/src/content/docs/de/5x/advanced/security-updates.md b/astro/src/content/docs/de/5x/advanced/security-updates.md
new file mode 100644
index 0000000000..850aacf852
--- /dev/null
+++ b/astro/src/content/docs/de/5x/advanced/security-updates.md
@@ -0,0 +1,84 @@
+---
+title: Express-Sicherheitsupdates
+description: Review the latest security updates and patches for Express.js, including detailed vulnerability lists for different versions to help maintain a secure application.
+---
+
+# Sicherheitsupdates
+
+
+Schwachstellen bei Node.js wirken sich direkt auf Express aus. Daher sollten Sie [ein Auge auf Schwachstellen bei Node.js haben](https://nodejs.org
+/en/blog/vulnerability/) und sicherstellen, dass Sie die aktuelle stabile Version von Node.js haben.
+
+
+Die folgende Liste enthält die Express-Schwachstellen, die im angegebenen Versionsupdate behoben wurden.
+
+{% capture security-policy %}
+If you believe you have discovered a security vulnerability in Express, please see
+[Security Policies and Procedures](/en/resources/contributing#security-policies-and-procedures).
+{% endcapture %}
+
+{% include admonitions/note.html content=security-policy %}
+
+## 4.x
+
+- 4.21.2
+ - The dependency `path-to-regexp` has been updated to address a [vulnerability](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-rhx6-c78j-4q9w).
+- 4.21.1
+ - The dependency `cookie` has been updated to address a [vulnerability](https://github.com/jshttp/cookie/security/advisories/GHSA-pxg6-pf52-xh8x), This may affect your application if you use `res.cookie`.
+- 4.20.0
+ - Fixed XSS vulnerability in `res.redirect` ([advisory](https://github.com/expressjs/express/security/advisories/GHSA-qw6h-vgh9-j6wx), [CVE-2024-43796](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-43796)).
+ - The dependency `serve-static` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-cm22-4g7w-348p).
+ - The dependency `send` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-m6fv-jmcg-4jfg).
+ - The dependency `path-to-regexp` has been updated to address a [vulnerability](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-9wv6-86v2-598j).
+ - The dependency `body-parser` has been updated to addres a [vulnerability](https://github.com/advisories/GHSA-qwcr-r2fm-qrc7), This may affect your application if you had url enconding activated.
+- 4.19.0, 4.19.1
+ - Fixed open redirect vulnerability in `res.location` and `res.redirect` ([advisory](https://github.com/expressjs/express/security/advisories/GHSA-rv95-896h-c2vc), [CVE-2024-29041](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-29041)).
+- 4.17.3
+ - The dependency `qs` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-hrpp-h998-j3pp). This may affect your application if the following APIs are used: `req.query`, `req.body`, `req.param`.
+- 4.16.0
+ - The dependency `forwarded` has been updated to address a [vulnerability](https://npmjs.com/advisories/527). This may affect your application if the following APIs are used: `req.host`, `req.hostname`, `req.ip`, `req.ips`, `req.protocol`.
+ - The dependency `mime` has been updated to address a [vulnerability](https://npmjs.com/advisories/535), but this issue does not impact Express.
+ - The dependency `send` has been updated to provide a protection against a [Node.js 8.5.0 vulnerability](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/). This only impacts running Express on the specific Node.js version 8.5.0.
+- 4.15.5
+ - The dependency `debug` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:debug:20170905), but this issue does not impact Express.
+ - The dependency `fresh` has been updated to address a [vulnerability](https://npmjs.com/advisories/526). This will affect your application if the following APIs are used: `express.static`, `req.fresh`, `res.json`, `res.jsonp`, `res.send`, `res.sendfile` `res.sendFile`, `res.sendStatus`.
+- 4.15.3
+ - The dependency `ms` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:ms:20170412). This may affect your application if untrusted string input is passed to the `maxAge` option in the following APIs: `express.static`, `res.sendfile`, and `res.sendFile`.
+- 4.15.2
+ - The dependency `qs` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:qs:20170213), but this issue does not impact Express. Updating to 4.15.2 is a good practice, but not required to address the vulnerability.
+- 4.11.1
+ - Offenlegungsgefahr beim Rootpfad in `express.static`, `res.sendfile` und `res.sendFile` behoben.
+- 4.10.7
+ - Offene Umadressierungsschwachstelle in `express.static` ([Empfehlung](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)) behoben.
+- 4.8.8
+ - Schwachstellen durch Directory-Traversal-Technik in `express.static` ([Empfehlung](http://npmjs.com/advisories/32) , [CVE-2014-6394](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6394)) behoben.
+- 4.8.4
+ - Node.js 0.10 kann in bestimmten Situationen Lecks bei `fd` aufweisen, die sich auf `express.static` und `res.sendfile` auswirken. Böswillige Anforderungen können zu Lecks bei `fd` führen und letztendlich `EMFILE`-Fehler nach sich ziehen und bewirken, dass Server nicht antworten.
+- 4.8.0
+ - Sparse-Arrays mit extrem hohen Indizes in der Abfragezeichenfolge können bewirken, dass für die Prozessausführung nicht genügend Arbeitsspeicher zur Verfügung steht und es zu einem Serverabsturz kommt.
+ - Extrem verschachtelte Abfragezeichenfolgenobjekte können bewirken, dass der Prozess blockiert und der Server dadurch vorübergehend nicht antwortet.
+
+## 3.x
+
+
+ **Express 3.x WIRD NICHT MEHR GEWARTET**
+
+Bekannte und unbekannte Probleme bei Sicherheit und Leistung in 3.x wurden seit dem letzten Update (1. August 2015) noch nicht behoben. Es wird dringend empfohlen, die aktuelle Version von Express zu verwenden.
+
+If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/en/support#commercial-support-options).
+
+
+
+- 3.19.1
+ - Offenlegungsgefahr beim Rootpfad in `express.static`, `res.sendfile` und `res.sendFile` behoben.
+- 3.19.0
+ - Offene Umadressierungsschwachstelle in `express.static` ([Empfehlung](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)) behoben.
+- 3.16.10
+ - Schwachstellen durch Directory-Traversal-Technik in `express.static` behoben.
+- 3.16.6
+ - Node.js 0.10 kann in bestimmten Situationen Lecks bei `fd` aufweisen, die sich auf `express.static` und `res.sendfile` auswirken. Böswillige Anforderungen können zu Lecks bei `fd` führen und letztendlich `EMFILE`-Fehler nach sich ziehen und bewirken, dass Server nicht antworten.
+- 3.16.0
+ - Sparse-Arrays mit extrem hohen Indizes in der Abfragezeichenfolge können bewirken, dass für die Prozessausführung nicht genügend Arbeitsspeicher zur Verfügung steht und es zu einem Serverabsturz kommt.
+ - Extrem verschachtelte Abfragezeichenfolgenobjekte können bewirken, dass der Prozess blockiert und der Server dadurch vorübergehend nicht antwortet.
+- 3.3.0
+ - Die Antwort 404 bei einem nicht unterstützten Überschreibungsversuch war anfällig gegen Cross-Site Scripting-Attacken.
diff --git a/astro/src/content/docs/de/5x/api.md b/astro/src/content/docs/de/5x/api.md
new file mode 100644
index 0000000000..47f8327c8e
--- /dev/null
+++ b/astro/src/content/docs/de/5x/api.md
@@ -0,0 +1,26 @@
+---
+version: 5x
+title: Express 5.x - API-Referenz
+description: Access the API reference for Express.js 5.x, detailing all modules, methods, and properties for building web applications with this latest version.
+---
+
+
+
+
5.x API
+
+{% capture node-version %}
+
+Express 5.0 requires Node.js 18 or higher.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=node-version %}
+
+
+{% include api/en/5x/express.md %}
+{% include api/en/5x/app.md %}
+{% include api/en/5x/req.md %}
+{% include api/en/5x/res.md %}
+{% include api/en/5x/router.md %}
+
+
diff --git a/astro/src/content/docs/de/5x/guide/behind-proxies.md b/astro/src/content/docs/de/5x/guide/behind-proxies.md
new file mode 100644
index 0000000000..34def6bfcb
--- /dev/null
+++ b/astro/src/content/docs/de/5x/guide/behind-proxies.md
@@ -0,0 +1,90 @@
+---
+title: Express hinter Proxys
+description: Learn how to configure Express.js applications to work correctly behind reverse proxies, including using the trust proxy setting to handle client IP addresses.
+---
+
+# Express hinter Proxys
+
+When running an Express app behind a reverse proxy, some of the Express APIs may return different values than expected. In order to adjust for this, the `trust proxy` application setting may be used to expose information provided by the reverse proxy in the Express APIs. The most common issue is express APIs that expose the client's IP address may instead show an internal IP address of the reverse proxy.
+
+
+When configuring the `trust proxy` setting, it is important to understand the exact setup of the reverse proxy. Since this setting will trust values provided in the request, it is important that the combination of the setting in Express matches how the reverse proxy operates.
+
+
+Bei der Ausführung einer Express-Anwendung hinter einem Proxy legen Sie die Anwendungsvariable `trust proxy` (mithilfe von [app.set()](/en/4x/api#app.set)) auf einen der in der folgenden Tabelle enthaltenen Werte fest:
+
+
+ Typ Wert
+
+
+ Boolesch
+Wenn `true` angegeben wird, wird die IP-Adresse des Clients als der äußerst rechte Eintrag im Header `X-Forwarded-*` interpretiert.
+
+Wenn `false` angegeben wird, wird die Anwendung als direkte Verbindung zum Internet gesehen. Die IP-Adresse des Clients wird dann von `req.connection.remoteAddress` abgeleitet. Dies ist die Standardeinstellung.
+
+
+When setting to `true`, it is important to ensure that the last reverse proxy trusted is removing/overwriting all of the following HTTP headers: `X-Forwarded-For`, `X-Forwarded-Host`, and `X-Forwarded-Proto`, otherwise it may be possible for the client to provide any value.
+
+
+
+
+ IP addresses
+
+An IP address, subnet, or an array of IP addresses and subnets to trust as being a reverse proxy. The following list shows the pre-configured subnet names:
+
+- loopback - `127.0.0.1/8`, `::1/128`
+- linklocal - `169.254.0.0/16`, `fe80::/10`
+- uniquelocal - `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7`
+
+Sie können IP-Adressen wie folgt festlegen:
+
+```js
+app.set('trust proxy', 'loopback'); // specify a single subnet
+app.set('trust proxy', 'loopback, 123.123.123.123'); // specify a subnet and an address
+app.set('trust proxy', 'loopback, linklocal, uniquelocal'); // specify multiple subnets as CSV
+app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']); // specify multiple subnets as an array
+```
+
+Sobald die Werte angegeben wurden, werden die betreffenden IP-Adressen und Teilnetze aus dem Adressfeststellungsprozess ausgeschlossen. Die nicht vertrauenswürdige IP-Adresse, die am nächsten zum Anwendungsserver liegt, wird als IP-Adresse des Clients festgelegt. This works by checking if `req.socket.remoteAddress` is trusted. If so, then each address in `X-Forwarded-For` is checked from right to left until the first non-trusted address.
+
+
+
+
+ Zahl
+
+Use the address that is at most `n` number of hops away from the Express application. `req.socket.remoteAddress` is the first hop, and the rest are looked for in the `X-Forwarded-For` header from right to left. A value of `0` means that the first untrusted address would be `req.socket.remoteAddress`, i.e. there is no reverse proxy.
+
+
+When using this setting, it is important to ensure there are not multiple, different-length paths to the Express application such that the client can be less than the configured number of hops away, otherwise it may be possible for the client to provide any value.
+
+
+
+
+ Function
+
+Custom trust implementation.
+
+```js
+app.set('trust proxy', (ip) => {
+ if (ip === '127.0.0.1' || ip === '123.123.123.123')
+ return true; // trusted IPs
+ else return false;
+});
+```
+
+
+
+
+
+
+Enabling `trust proxy` will have the following impact:
+
+
+ Der Wert für [req.hostname](/en/api#req.hostname) wird vom Wert abgeleitet, der im Header `X-Forwarded-Host` festgelegt wurde. Dieser Wert kann vom Client oder Proxy festgelegt werden.
+ `X-Forwarded-Proto` kann vom Reverse Proxy festgelegt werden, um der Anwendung mitzuteilen, ob es sich um `https` oder `http` oder sogar um einen ungültigen Namen handelt. Dieser Wert wird durch [req.protocol](/en/api#req.protocol) abgebildet.
+
+ Als Werte für [req.ip](/en/api#req.ip) und [req.ips](/en/api#req.ips) wird die Liste der Adressen aus `X-Forwarded-For` herangezogen.
+
+
+
+Die Einstellung für `trust proxy` wird mithilfe des [proxy-addr](https://www.npmjs.com/package/proxy-addr)-Pakets implementiert. Weitere Informationen finden Sie in der zugehörigen Dokumentation.
diff --git a/astro/src/content/docs/de/5x/guide/database-integration.md b/astro/src/content/docs/de/5x/guide/database-integration.md
new file mode 100644
index 0000000000..fcd6291fc1
--- /dev/null
+++ b/astro/src/content/docs/de/5x/guide/database-integration.md
@@ -0,0 +1,509 @@
+---
+title: Datenbankintegration in Express
+description: Discover how to integrate various databases with Express.js applications, including setup examples for MongoDB, MySQL, PostgreSQL, and more.
+---
+
+# Datenbankintegration
+
+Die Herstellung einer Verbindung zwischen Datenbanken und Express-Anwendungen erfolgt einfach durch Laden eines geeigneten Node.js-Treibers für die Datenbank in Ihre Anwendung. In diesem Dokument wird in Kurzform beschrieben, wie einige der gängigsten Node.js-Module für Datenbanksysteme Ihrer Express-Anwendung hinzugefügt und verwendet werden:
+
+- [Cassandra](#cassandra)
+- [Couchbase](#couchbase)
+- [CouchDB](#couchdb)
+- [LevelDB](#leveldb)
+- [MySQL](#mysql)
+- [MongoDB](#mongo)
+- [Neo4j](#neo4j)
+- [Oracle](#oracle)
+- [PostgreSQL](#postgres)
+- [Redis](#redis)
+-
+- [SQLite](#sqlite)
+- [ElasticSearch](#elasticsearch)
+
+
+Diese Datenbanktreiber sind neben zahlreichen anderen Treibern verfügbar. Weitere Optionen finden Sie auf der [npm](https://www.npmjs.com/)-Site.
+
+
+## Cassandra
+
+**Modul**: [cassandra-driver](https://github.com/datastax/nodejs-driver)
+**Installation**
+
+### Installation
+
+```bash
+$ npm install cassandra-driver
+```
+
+### Beispiel
+
+```js
+const cassandra = require('cassandra-driver');
+const client = new cassandra.Client({ contactPoints: ['localhost'] });
+
+client.execute('select key from system.local', (err, result) => {
+ if (err) throw err;
+ console.log(result.rows[0]);
+});
+```
+
+## Couchbase
+
+**Module**: [couchnode](https://github.com/couchbase/couchnode)
+
+### Installation
+
+```bash
+$ npm install couchbase
+```
+
+### Beispiel
+
+```js
+const couchbase = require('couchbase');
+const bucket = new couchbase.Cluster('http://localhost:8091').openBucket('bucketName');
+
+// add a document to a bucket
+bucket.insert('document-key', { name: 'Matt', shoeSize: 13 }, (err, result) => {
+ if (err) {
+ console.log(err);
+ } else {
+ console.log(result);
+ }
+});
+
+// get all documents with shoe size 13
+const n1ql = 'SELECT d.* FROM `bucketName` d WHERE shoeSize = $1';
+const query = N1qlQuery.fromString(n1ql);
+bucket.query(query, [13], (err, result) => {
+ if (err) {
+ console.log(err);
+ } else {
+ console.log(result);
+ }
+});
+```
+
+## CouchDB
+
+**Modul**: [nano](https://github.com/dscape/nano)
+**Installation**
+
+### Installation
+
+```bash
+$ npm install nano
+```
+
+### Beispiel
+
+```js
+const nano = require('nano')('http://localhost:5984');
+nano.db.create('books');
+const books = nano.db.use('books');
+
+// Insert a book document in the books database
+books.insert({ name: 'The Art of war' }, null, (err, body) => {
+ if (err) {
+ console.log(err);
+ } else {
+ console.log(body);
+ }
+});
+
+// Get a list of all books
+books.list((err, body) => {
+ if (err) {
+ console.log(err);
+ } else {
+ console.log(body.rows);
+ }
+});
+```
+
+## LevelDB
+
+**Modul**: [levelup](https://github.com/rvagg/node-levelup)
+**Installation**
+
+### Installation
+
+```bash
+$ npm install level levelup leveldown
+```
+
+### Beispiel
+
+```js
+const levelup = require('levelup');
+const db = levelup('./mydb');
+
+db.put('name', 'LevelUP', (err) => {
+ if (err) return console.log('Ooops!', err);
+
+ db.get('name', (err, value) => {
+ if (err) return console.log('Ooops!', err);
+
+ console.log(`name=${value}`);
+ });
+});
+```
+
+## MySQL
+
+**Modul**: [mysql](https://github.com/felixge/node-mysql/)
+**Installation**
+
+### Installation
+
+```bash
+$ npm install mysql
+```
+
+### Beispiel
+
+```js
+const mysql = require('mysql');
+const connection = mysql.createConnection({
+ host: 'localhost',
+ user: 'dbuser',
+ password: 's3kreee7',
+ database: 'my_db',
+});
+
+connection.connect();
+
+connection.query('SELECT 1 + 1 AS solution', (err, rows, fields) => {
+ if (err) throw err;
+
+ console.log('The solution is: ', rows[0].solution);
+});
+
+connection.end();
+```
+
+## MongoDB
+
+**Modul**: [mongodb](https://github.com/mongodb/node-mongodb-native)
+**Installation**
+
+### Installation
+
+```bash
+$ npm install mongodb
+```
+
+### Example (v2.\*)
+
+```js
+const MongoClient = require('mongodb').MongoClient;
+
+MongoClient.connect('mongodb://localhost:27017/animals', (err, db) => {
+ if (err) throw err;
+
+ db.collection('mammals')
+ .find()
+ .toArray((err, result) => {
+ if (err) throw err;
+
+ console.log(result);
+ });
+});
+```
+
+### Example (v3.\*)
+
+```js
+const MongoClient = require('mongodb').MongoClient;
+
+MongoClient.connect('mongodb://localhost:27017/animals', (err, client) => {
+ if (err) throw err;
+
+ const db = client.db('animals');
+
+ db.collection('mammals')
+ .find()
+ .toArray((err, result) => {
+ if (err) throw err;
+
+ console.log(result);
+ });
+});
+```
+
+Wenn Sie nach einem Objektmodelltreiber für MongoDB suchen, schauen Sie unter [Mongoose](https://github.com/LearnBoost/mongoose) nach.
+
+## Neo4j
+
+**Module**: [neo4j-driver](https://github.com/neo4j/neo4j-javascript-driver)
+
+### Installation
+
+```bash
+$ npm install neo4j-driver
+```
+
+### Beispiel
+
+```js
+const neo4j = require('neo4j-driver');
+const driver = neo4j.driver('neo4j://localhost:7687', neo4j.auth.basic('neo4j', 'letmein'));
+
+const session = driver.session();
+
+session.readTransaction((tx) => {
+ return tx
+ .run('MATCH (n) RETURN count(n) AS count')
+ .then((res) => {
+ console.log(res.records[0].get('count'));
+ })
+ .catch((error) => {
+ console.log(error);
+ });
+});
+```
+
+## Oracle
+
+**Modul**: [oracledb](https://github.com/oracle/node-oracledb)
+
+### Installation
+
+Anmerkung: [Siehe Installations-Voraussetzungen](https://github.com/oracle/node-oracledb#-installation).
+
+```bash
+$ npm install oracledb
+```
+
+### Beispiel
+
+```js
+const oracledb = require('oracledb');
+const config = {
+ user: '',
+ password: '',
+ connectString: 'localhost:1521/orcl',
+};
+
+async function getEmployee(empId) {
+ let conn;
+
+ try {
+ conn = await oracledb.getConnection(config);
+
+ const result = await conn.execute('select * from employees where employee_id = :id', [empId]);
+
+ console.log(result.rows[0]);
+ } catch (err) {
+ console.log('Ouch!', err);
+ } finally {
+ if (conn) {
+ // conn assignment worked, need to close
+ await conn.close();
+ }
+ }
+}
+
+getEmployee(101);
+```
+
+## PostgreSQL
+
+**Modul**: [pg-promise](https://github.com/vitaly-t/pg-promise)
+**Installation**
+
+### Installation
+
+```bash
+$ npm install pg-promise
+```
+
+### Beispiel
+
+```js
+const pgp = require('pg-promise')(/* options */);
+const db = pgp('postgres://username:password@host:port/database');
+
+db.one('SELECT $1 AS value', 123)
+ .then((data) => {
+ console.log('DATA:', data.value);
+ })
+ .catch((error) => {
+ console.log('ERROR:', error);
+ });
+```
+
+## Redis
+
+**Modul**: [redis](https://github.com/mranney/node_redis)
+**Installation**
+
+### Installation
+
+```bash
+$ npm install redis
+```
+
+### Beispiel
+
+```js
+const redis = require('redis');
+const client = redis.createClient();
+
+client.on('error', (err) => {
+ console.log(`Error ${err}`);
+});
+
+client.set('string key', 'string val', redis.print);
+client.hset('hash key', 'hashtest 1', 'some value', redis.print);
+client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print);
+
+client.hkeys('hash key', (err, replies) => {
+ console.log(`${replies.length} replies:`);
+
+ replies.forEach((reply, i) => {
+ console.log(` ${i}: ${reply}`);
+ });
+
+ client.quit();
+});
+```
+
+## SQL Server
+
+**Module**: [tedious](https://github.com/tediousjs/tedious)
+
+### Installation
+
+```bash
+$ npm install tedious
+```
+
+### Beispiel
+
+```js
+const Connection = require('tedious').Connection;
+const Request = require('tedious').Request;
+
+const config = {
+ server: 'localhost',
+ authentication: {
+ type: 'default',
+ options: {
+ userName: 'your_username', // update me
+ password: 'your_password', // update me
+ },
+ },
+};
+
+const connection = new Connection(config);
+
+connection.on('connect', (err) => {
+ if (err) {
+ console.log(err);
+ } else {
+ executeStatement();
+ }
+});
+
+function executeStatement() {
+ request = new Request("select 123, 'hello world'", (err, rowCount) => {
+ if (err) {
+ console.log(err);
+ } else {
+ console.log(`${rowCount} rows`);
+ }
+ connection.close();
+ });
+
+ request.on('row', (columns) => {
+ columns.forEach((column) => {
+ if (column.value === null) {
+ console.log('NULL');
+ } else {
+ console.log(column.value);
+ }
+ });
+ });
+
+ connection.execSql(request);
+}
+```
+
+## SQLite
+
+**Modul**: [sqlite3](https://github.com/mapbox/node-sqlite3)
+**Installation**
+
+### Installation
+
+```bash
+$ npm install sqlite3
+```
+
+### Beispiel
+
+```js
+const sqlite3 = require('sqlite3').verbose();
+const db = new sqlite3.Database(':memory:');
+
+db.serialize(() => {
+ db.run('CREATE TABLE lorem (info TEXT)');
+ const stmt = db.prepare('INSERT INTO lorem VALUES (?)');
+
+ for (let i = 0; i < 10; i++) {
+ stmt.run(`Ipsum ${i}`);
+ }
+
+ stmt.finalize();
+
+ db.each('SELECT rowid AS id, info FROM lorem', (err, row) => {
+ console.log(`${row.id}: ${row.info}`);
+ });
+});
+
+db.close();
+```
+
+## ElasticSearch
+
+**Modul**: [elasticsearch](https://github.com/elastic/elasticsearch-js)
+**Installation**
+
+### Installation
+
+```bash
+$ npm install elasticsearch
+```
+
+### Beispiel
+
+```js
+const elasticsearch = require('elasticsearch');
+const client = elasticsearch.Client({
+ host: 'localhost:9200',
+});
+
+client
+ .search({
+ index: 'books',
+ type: 'book',
+ body: {
+ query: {
+ multi_match: {
+ query: 'express js',
+ fields: ['title', 'description'],
+ },
+ },
+ },
+ })
+ .then(
+ (response) => {
+ const hits = response.hits.hits;
+ },
+ (error) => {
+ console.trace(error.message);
+ }
+ );
+```
diff --git a/astro/src/content/docs/de/5x/guide/debugging.md b/astro/src/content/docs/de/5x/guide/debugging.md
new file mode 100644
index 0000000000..1d69c7bda7
--- /dev/null
+++ b/astro/src/content/docs/de/5x/guide/debugging.md
@@ -0,0 +1,126 @@
+---
+title: Debugging bei Express
+description: Learn how to enable and use debugging logs in Express.js applications by setting the DEBUG environment variable for enhanced troubleshooting.
+---
+
+# Debugging bei Express
+
+Wenn Sie alle in Express verwendeten internen Protokolle anzeigen wollen, legen Sie beim Starten Ihrer Anwendung die Umgebungsvariable `DEBUG` auf `express:*` fest.
+
+```bash
+$ DEBUG=express:* node index.js
+```
+
+Verwenden Sie unter Windows den entsprechenden Befehl.
+
+```bash
+> $env:DEBUG = "express:*"; node index.js
+```
+
+Die Ausführung dieses Befehls für die durch [express generator](/en/starter/generator) generierte Standardanwendung resultiert in folgender Ausgabe:
+
+```bash
+$ DEBUG=express:* node ./bin/www
+ express:router:route new / +0ms
+ express:router:layer new / +1ms
+ express:router:route get / +1ms
+ express:router:layer new / +0ms
+ express:router:route new / +1ms
+ express:router:layer new / +0ms
+ express:router:route get / +0ms
+ express:router:layer new / +0ms
+ express:application compile etag weak +1ms
+ express:application compile query parser extended +0ms
+ express:application compile trust proxy false +0ms
+ express:application booting in development mode +1ms
+ express:router use / query +0ms
+ express:router:layer new / +0ms
+ express:router use / expressInit +0ms
+ express:router:layer new / +0ms
+ express:router use / favicon +1ms
+ express:router:layer new / +0ms
+ express:router use / logger +0ms
+ express:router:layer new / +0ms
+ express:router use / jsonParser +0ms
+ express:router:layer new / +1ms
+ express:router use / urlencodedParser +0ms
+ express:router:layer new / +0ms
+ express:router use / cookieParser +0ms
+ express:router:layer new / +0ms
+ express:router use / stylus +90ms
+ express:router:layer new / +0ms
+ express:router use / serveStatic +0ms
+ express:router:layer new / +0ms
+ express:router use / router +0ms
+ express:router:layer new / +1ms
+ express:router use /users router +0ms
+ express:router:layer new /users +0ms
+ express:router use / <anonymous> +0ms
+ express:router:layer new / +0ms
+ express:router use / <anonymous> +0ms
+ express:router:layer new / +0ms
+ express:router use / <anonymous> +0ms
+ express:router:layer new / +0ms
+```
+
+Bei einer Anforderung an die Anwendung sind die Protokolle im Express-Code angegeben:
+
+```bash
+ express:router dispatching GET / +4h
+ express:router query : / +2ms
+ express:router expressInit : / +0ms
+ express:router favicon : / +0ms
+ express:router logger : / +1ms
+ express:router jsonParser : / +0ms
+ express:router urlencodedParser : / +1ms
+ express:router cookieParser : / +0ms
+ express:router stylus : / +0ms
+ express:router serveStatic : / +2ms
+ express:router router : / +2ms
+ express:router dispatching GET / +1ms
+ express:view lookup "index.pug" +338ms
+ express:view stat "/projects/example/views/index.pug" +0ms
+ express:view render "/projects/example/views/index.pug" +1ms
+```
+
+Wenn Sie nur die Protokolle von der Routerimplementierung sehen wollen, legen Sie den Wert für `DEBUG` auf `express:router` fest. Gleichermaßen gilt: Wenn Sie nur die Protokolle von der Anwendungsimplementierung sehen wollen, legen Sie den Wert für `DEBUG` auf `express:application` fest, usw.
+
+## Von `express` generierte Anwendungen
+
+An application generated by the `express` command uses the `debug` module and its debug namespace is scoped to the name of the application.
+
+Beispiel: Wenn Sie die Anwendung mit `$ express sample-app` generiert haben, können Sie die Debuganweisungen mit dem folgenden Befehl aktivieren:
+
+```bash
+$ DEBUG=sample-app:* node ./bin/www
+```
+
+Sie können mehrere Debug-Namespaces in einer durch Kommas getrennten Namensliste angeben:
+
+```bash
+$ DEBUG=http,mail,express:* node index.js
+```
+
+## Advanced options
+
+When running through Node.js, you can set a few environment variables that will change the behavior of the debug logging:
+
+| Name | Purpose |
+| ------------------- | ------------------------------------------------- |
+| `DEBUG` | Enables/disables specific debugging namespaces. |
+| `DEBUG_COLORS` | Whether or not to use colors in the debug output. |
+| `DEBUG_DEPTH` | Object inspection depth. |
+| `DEBUG_FD` | File descriptor to write debug output to. |
+| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. |
+
+{% capture debug-text %}
+
+The environment variables beginning with `DEBUG_` end up being
+converted into an Options object that gets used with `%o`/`%O` formatters.
+See the Node.js documentation for
+[`util.inspect()`](https://nodejs.org/api/util#util_util_inspect_object_options)
+for the complete list.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=debug-text %}
diff --git a/astro/src/content/docs/de/5x/guide/error-handling.md b/astro/src/content/docs/de/5x/guide/error-handling.md
new file mode 100644
index 0000000000..6431405f27
--- /dev/null
+++ b/astro/src/content/docs/de/5x/guide/error-handling.md
@@ -0,0 +1,289 @@
+---
+title: Fehlerbehandlung in Express
+description: Understand how Express.js handles errors in synchronous and asynchronous code, and learn to implement custom error handling middleware for your applications.
+---
+
+# Fehlerbehandlung
+
+_Error Handling_ refers to how Express catches and processes errors that
+occur both synchronously and asynchronously. Express comes with a default error
+handler so you don't need to write your own to get started.
+
+## Catching Errors
+
+It's important to ensure that Express catches all errors that occur while
+running route handlers and middleware.
+
+Errors that occur in synchronous code inside route handlers and middleware
+require no extra work. If synchronous code throws an error, then Express will
+catch and process it. Beispiel:
+
+```js
+app.get('/', (req, res) => {
+ throw new Error('BROKEN'); // Express will catch this on its own.
+});
+```
+
+Middlewarefunktionen für die Fehlerbehandlung werden in derselben Weise definiert wie andere Middlewarefunktionen, nur, dass Fehlerbehandlungsfunktionen vier anstatt drei Argumente aufweisen:
+`(err, req, res, next)`. Beispiel:
+
+```js
+app.get('/', (req, res, next) => {
+ fs.readFile('/file-does-not-exist', (err, data) => {
+ if (err) {
+ next(err); // Pass errors to Express.
+ } else {
+ res.send(data);
+ }
+ });
+});
+```
+
+Middleware für die Fehlerbehandlung wird ganz zuletzt nach allen anderen `app.use()`- und Weiterleitungsaufrufen definiert.
+Beispiel:
+
+```js
+app.get('/user/:id', async (req, res, next) => {
+ const user = await getUserById(req.params.id);
+ res.send(user);
+});
+```
+
+If `getUserById` throws an error or rejects, `next` will be called with either
+the thrown error or the rejected value. If no rejected value is provided, `next`
+will be called with a default Error object provided by the Express router.
+
+Wenn Sie Übergaben an die Funktion `next()` vornehmen (außer die Zeichenfolge `'route'`), sieht Express die aktuelle Anforderung als Fehler an und überspringt alle verbleibenden fehlerfreien Behandlungsroutinen und Middlewarefunktionen.
+
+If the callback in a sequence provides no data, only errors, you can simplify
+this code as follows:
+
+```js
+app.get('/', [
+ function (req, res, next) {
+ fs.writeFile('/inaccessible-path', 'data', next);
+ },
+ function (req, res) {
+ res.send('OK');
+ },
+]);
+```
+
+In the above example, `next` is provided as the callback for `fs.writeFile`,
+which is called with or without errors. If there is no error, the second
+handler is executed, otherwise Express catches and processes the error.
+
+Bei einem Routenhandler mit mehreren Callback-Funktionen können Sie den Parameter `route` verwenden, um den nächsten Routenhandler zu überspringen. Beispiel:
+
+```js
+app.get('/', (req, res, next) => {
+ setTimeout(() => {
+ try {
+ throw new Error('BROKEN');
+ } catch (err) {
+ next(err);
+ }
+ }, 100);
+});
+```
+
+The above example uses a `try...catch` block to catch errors in the
+asynchronous code and pass them to Express. If the `try...catch`
+block were omitted, Express would not catch the error since it is not part of the synchronous
+handler code.
+
+Use promises to avoid the overhead of the `try...catch` block or when using functions
+that return promises. Beispiel:
+
+```js
+app.get('/', (req, res, next) => {
+ Promise.resolve()
+ .then(() => {
+ throw new Error('BROKEN');
+ })
+ .catch(next); // Errors will be passed to Express.
+});
+```
+
+Since promises automatically catch both synchronous errors and rejected promises,
+you can simply provide `next` as the final catch handler and Express will catch errors,
+because the catch handler is given the error as the first argument.
+
+You could also use a chain of handlers to rely on synchronous error
+catching, by reducing the asynchronous code to something trivial. Beispiel:
+
+```js
+app.get('/', [
+ function (req, res, next) {
+ fs.readFile('/maybe-valid-file', 'utf-8', (err, data) => {
+ res.locals.data = data;
+ next(err);
+ });
+ },
+ function (req, res) {
+ res.locals.data = res.locals.data.split(',')[1];
+ res.send(res.locals.data);
+ },
+]);
+```
+
+The above example has a couple of trivial statements from the `readFile`
+call. If `readFile` causes an error, then it passes the error to Express, otherwise you
+quickly return to the world of synchronous error handling in the next handler
+in the chain. Then, the example above tries to process the data. If this fails, then the
+synchronous error handler will catch it. If you had done this processing inside
+the `readFile` callback, then the application might exit and the Express error
+handlers would not run.
+
+Whichever method you use, if you want Express error handlers to be called in and the
+application to survive, you must ensure that Express receives the error.
+
+## Die Standardfehlerbehandlungsroutine (Default Error Handler)
+
+Express ist bereits mit einer integrierten Fehlerbehandlungsroutine ausgestattet, mit der alle in der Anwendung festgestellten Fehler gehandhabt werden können. Diese Middleware für die Fehlerbehandlung wird am Ende des Middleware-Funktionsstack hinzugefügt.
+
+Wenn Sie einen Fehler an `next()` übergeben und diesen nicht mit einem Error-Handler bearbeiten, wird dieser über den integrierten Error-Handler bearbeitet. Der Fehler wird mit dem Stack-Trace zum Client geschrieben. Der Stack-Trace ist in der Produktionsumgebung nicht verfügbar.
+
+
+Legen Sie die Umgebungsvariable `NODE_ENV` auf `production` fest, um die Anwendung im Produktionsmodus auszuführen.
+
+
+When an error is written, the following information is added to the
+response:
+
+- The `res.statusCode` is set from `err.status` (or `err.statusCode`). If
+ this value is outside the 4xx or 5xx range, it will be set to 500.
+- The `res.statusMessage` is set according to the status code.
+- The body will be the HTML of the status code message when in production
+ environment, otherwise will be `err.stack`.
+- Any headers specified in an `err.headers` object.
+
+Wenn `next()` mit einem Fehler aufgerufen wird, nachdem Sie mit dem Schreiben der Antwort begonnen haben (z. B., wenn Sie beim Streamen der Antwort zum Client einen Fehler feststellen), schließt die Standardfehlerbehandlungsroutine in Express die Verbindung, und die Anforderung schlägt fehl.
+
+Wenn Sie also einen angepassten Error-Handler hinzufügen, empfiehlt es sich, eine Delegierung zur Standardfehlerbehandlungsroutine in Express vorzunehmen, wenn die Header bereits an den Client gesendet wurden:
+
+```js
+function errorHandler(err, req, res, next) {
+ if (res.headersSent) {
+ return next(err);
+ }
+ res.status(500);
+ res.render('error', { error: err });
+}
+```
+
+Note that the default error handler can get triggered if you call `next()` with an error
+in your code more than once, even if custom error handling middleware is in place.
+
+Other error handling middleware can be found at [Express middleware](/en/resources/middleware).
+
+## Writing error handlers
+
+Define error-handling middleware functions in the same way as other middleware functions,
+except error-handling functions have four arguments instead of three:
+`(err, req, res, next)`. Beispiel:
+
+```js
+app.use((err, req, res, next) => {
+ console.error(err.stack);
+ res.status(500).send('Something broke!');
+});
+```
+
+You define error-handling middleware last, after other `app.use()` and routes calls; for example:
+
+```js
+const bodyParser = require('body-parser');
+const methodOverride = require('method-override');
+
+app.use(
+ bodyParser.urlencoded({
+ extended: true,
+ })
+);
+app.use(bodyParser.json());
+app.use(methodOverride());
+app.use((err, req, res, next) => {
+ // logic
+});
+```
+
+Antworten von der Middlewarefunktion können das von Ihnen gewünschte Format aufweisen wie beispielsweise eine Fehlerseite im HTML-Format, eine einfache Nachricht oder eine JSON-Zeichenfolge.
+
+Für organisatorische Zwecke (und Frameworks der höheren Ebene) können Sie mehrere Middlewarefunktionen für die Fehlerbehandlung definieren, wie Sie dies bei regulären Middlewarefunktionen auch tun würden. Wenn Sie beispielsweise eine Fehlerbehandlungsroutine (Error-Handler) für Anforderungen über `XHR` und andere Anforderungen definieren wollen, können Sie die folgenden Befehle verwenden:
+
+```js
+const bodyParser = require('body-parser');
+const methodOverride = require('method-override');
+
+app.use(
+ bodyParser.urlencoded({
+ extended: true,
+ })
+);
+app.use(bodyParser.json());
+app.use(methodOverride());
+app.use(logErrors);
+app.use(clientErrorHandler);
+app.use(errorHandler);
+```
+
+In diesem Beispiel kann die generische `logErrors`-Funktion Anforderungs- und Fehlerinformationen in `stderr` schreiben:
+
+```js
+function logErrors(err, req, res, next) {
+ console.error(err.stack);
+ next(err);
+}
+```
+
+In diesem Beispiel wird `clientErrorHandler` wie folgt definiert. In diesem Fall wird der Fehler explizit an den nächsten Error-Handler übergeben:
+
+Notice that when _not_ calling "next" in an error-handling function, you are responsible for writing (and ending) the response. Otherwise, those requests will "hang" and will not be eligible for garbage collection.
+
+```js
+function clientErrorHandler(err, req, res, next) {
+ if (req.xhr) {
+ res.status(500).send({ error: 'Something failed!' });
+ } else {
+ next(err);
+ }
+}
+```
+
+Die `errorHandler`-Funktion "catch-all" kann wie folgt implementiert werden:
+
+```js
+function errorHandler(err, req, res, next) {
+ res.status(500);
+ res.render('error', { error: err });
+}
+```
+
+If you have a route handler with multiple callback functions, you can use the `route` parameter to skip to the next route handler. Beispiel:
+
+```js
+app.get(
+ '/a_route_behind_paywall',
+ (req, res, next) => {
+ if (!req.user.hasPaid) {
+ // continue handling this request
+ next('route');
+ } else {
+ next();
+ }
+ },
+ (req, res, next) => {
+ PaidContent.find((err, doc) => {
+ if (err) return next(err);
+ res.json(doc);
+ });
+ }
+);
+```
+
+In diesem Beispiel wird der Handler `getPaidContent` übersprungen. Alle verbleibenden Handler in `app` für `/a_route_behind_paywall` werden jedoch weiter ausgeführt.
+
+
+Aufrufe zu `next()` und `next(err)` geben an, dass der aktuelle Handler abgeschlossen ist und welchen Status er aufweist. Durch `next(err)` werden alle verbleibenden Handler in der Kette übersprungen. Ausgenommen hiervor sind die Handler, die konfiguriert sind, um Fehler wie oben beschrieben zu behandeln.
+
diff --git a/astro/src/content/docs/de/5x/guide/migrating-4.md b/astro/src/content/docs/de/5x/guide/migrating-4.md
new file mode 100644
index 0000000000..47fad43b6f
--- /dev/null
+++ b/astro/src/content/docs/de/5x/guide/migrating-4.md
@@ -0,0 +1,554 @@
+---
+title: Migration auf Express 4
+description: A guide to migrating your Express.js applications from version 3 to 4, covering changes in middleware, routing, and how to update your codebase effectively.
+---
+
+# Wechsel zu Express 4
+
+Überblick
+
+Express 4 bietet grundlegende Veränderungen im Vergleich zu Express 3. Das bedeutet, dass eine Express 3-Anwendung nicht funktioniert, wenn Sie die Express-Version in ihren Abhängigkeiten aktualisieren.
+
+In diesem Beitrag werden folgende Themen behandelt:
+
+
+
+Änderungen in Express 4
+
+In Express 4 wurden einige signifikante Änderungen vorgenommen:
+
+
+
+Siehe hierzu auch:
+
+- [Neue Features/Funktionen in 4.x.](https://github.com/expressjs/express/wiki/New-features-in-4.x)
+- [Migration von 3.x auf 4.x.](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x)
+
+
+Änderungen am Express-Core- und Middlewaresystem
+
+In Express 4 bestehen keine Abhängigkeiten mehr zu Connect. Alle integrierten Middlewarefunktionen werden aus dem Core entfernt. Ausgenommen hiervon ist die Funktion `express.static`. Das bedeutet, dass Express nun ein unabhängiges Routing- und Middleware-Web-Framework ist und Express-Versionierung und -Releases von Middleware-Updates nicht betroffen sind.
+
+Ohne integrierte Middleware müssen Sie explizit alle Middlewarefunktionen hinzufügen, die für die Ausführung Ihrer Anwendung erforderlich sind. Befolgen Sie einfach diese Schritte:
+
+1. Installieren des Moduls: `npm install --save `
+2. Anfordern des Moduls in Ihrer Anwendung: `require('modulname')`
+3. Verwendung des Moduls gemäß Dokumentation: `app.use( ... )`
+
+In der folgenden Tabelle sind Express 3-Middlewarefunktionen und deren Entsprechungen in Express 4 aufgelistet.
+
+
+
+Hier finden Sie die [komplette Liste](https://github.com/senchalabs/connect#middleware) der Express 4-Middleware.
+
+In den meisten Fällen können Sie einfach nur die Middleware der alten Version 3 durch deren Entsprechung in Express 4 ersetzen. Details hierzu finden Sie in der modulspezifischen Dokumentation in GitHub.
+
+app.use akzeptiert Parameter.
+
+In Version 4 können Sie über einen Variablenparameter den Pfad definieren, in den Middlewarefunktionen geladen werden. Dann können Sie den Wert des Parameters aus dem Routenhandler laden.
+Beispiel:
+
+```js
+app.use('/book/:id', (req, res, next) => {
+ console.log('ID:', req.params.id);
+ next();
+});
+```
+
+
+Das Routingsystem
+
+
+Anwendungen laden nun implizit Routing-Middleware. Sie müssen sich also keine Gedanken mehr über die Reihenfolge machen, in der die Middleware in Bezug auf die `router`-Middleware geladen wird.
+
+Das Routingsystem verfügt jedoch über zwei neue Funktionen, die beim Organisieren Ihrer Weiterleitungen helfen:
+
+{: .doclist }
+
+- Die neue Methode `app.route()` zum Erstellen verkettbarer Routenhandler für einen Weiterleitungspfad
+- Die neue Klasse `express.Router` zum Erstellen modular einbindbarer Routenhandler
+
+Die Methode app.route()
+
+Die neue Methode `app.route()` hilft beim Erstellen verkettbarer Routenhandler für einen Weiterleitungspfad. Da der Pfad an einer einzelnen Position angegeben wird, ist das Erstellen modularer Weiterleitungen hilfreich, da Redundanzen und Schreibfehler reduziert werden. Weitere Informationen zu Weiterleitungen finden Sie in der Dokumentation zu [`Router()`](/en/4x/api#router).
+
+Dies ist ein Beispiel für verkettete Routenhandler, die mit der Funktion `app.route()` definiert werden.
+
+```js
+app
+ .route('/book')
+ .get((req, res) => {
+ res.send('Get a random book');
+ })
+ .post((req, res) => {
+ res.send('Add a book');
+ })
+ .put((req, res) => {
+ res.send('Update the book');
+ });
+```
+
+Die Klasse express.Router
+
+Eine weitere Funktion, die beim Organisieren von Weiterleitungen hilft, ist die neue Klasse `express.Router`. Über diese Klasse können Sie modular einbindbare Routenhandler erstellen. Eine `Router`-Instanz ist ein vollständiges Middleware- und Routingsystem. Aus diesem Grund wird diese Instanz oft auch als "Mini-App" bezeichnet.
+
+Im folgenden Beispiel wird ein Router als Modul erstellt, Middleware in das Modul geladen, es werden Weiterleitungen definiert und das Modul letztendlich in einen Pfad in der Hauptanwendung eingebunden.
+
+Beispiel: Erstellen Sie eine Routerdatei namens `birds.js` mit dem folgenden Inhalt im Anwendungsverzeichnis:
+
+```js
+var express = require('express');
+var router = express.Router();
+
+// middleware specific to this router
+router.use((req, res, next) => {
+ console.log('Time: ', Date.now());
+ next();
+});
+// define the home page route
+router.get('/', (req, res) => {
+ res.send('Birds home page');
+});
+// define the about route
+router.get('/about', (req, res) => {
+ res.send('About birds');
+});
+
+module.exports = router;
+```
+
+Laden Sie dann das Routermodul in die Anwendung:
+
+```js
+var birds = require('./birds');
+
+// ...
+
+app.use('/birds', birds);
+```
+
+Die Anwendung kann nun Anforderungen an die Pfade `/birds` und `/birds/about` bearbeiten und ruft die Middleware `timeLog` auf, die speziell für diese Weiterleitung bestimmt ist.
+
+
+Weitere Änderungen
+
+In der folgenden Tabelle sind andere kleinere, aber trotzdem wichtige Änderungen in Express 4 aufgeführt:
+
+
+
+Objekt
+Beschreibung
+
+
+Node.js
+
+Express 4 erfordert Node.js 0.10.x oder höher und unterstützt nicht mehr Node.js 0.8.x.
+
+
+
+
+`http.createServer()`
+
+
+Das Modul `http` wird nicht mehr benötigt, es sei denn, Sie müssen direkt mit dem Modul arbeiten (socket.io/SPDY/HTTPS). Die Anwendung kann mithilfe der Funktion `app.listen()` gestartet werden.
+
+
+
+
+`app.configure()`
+
+
+Die Funktion `app.configure()` wurde entfernt. Verwenden Sie die Funktion `process.env.NODE_ENV` oder `app.get('env')`, um die Umgebung zu erkennen und die Anwendung entsprechend zu konfigurieren.
+
+
+
+
+`json spaces`
+
+
+Die Anwendungseigenschaft `json spaces` ist in Express 4 standardmäßig inaktiviert.
+
+
+
+
+`req.accepted()`
+
+
+Verwenden Sie `req.accepts()`, `req.acceptsEncodings()`, `req.acceptsCharsets()` und `req.acceptsLanguages()`.
+
+
+
+
+`res.location()`
+
+
+Löst keine relativen URLs mehr auf.
+
+
+
+
+`req.params`
+
+
+War bisher ein Array, ist nun ein Objekt.
+
+
+
+
+`res.locals`
+
+
+War bisher eine Funktion, ist nun ein Objekt.
+
+
+
+
+`res.headerSent`
+
+
+Geändert in `res.headersSent`.
+
+
+
+
+`app.route`
+
+
+Nun verfügbar als `app.mountpath`.
+
+
+
+
+`res.on('header')`
+
+
+Entfernt.
+
+
+
+
+`res.charset`
+
+
+Entfernt.
+
+
+
+
+`res.setHeader('Set-Cookie', val)`
+
+
+Die Funktionalität ist nun auf die Einstellung des Basis-Cookiewerts begrenzt. Verwenden Sie `res.cookie()`, um weitere Funktionalität zu erhalten.
+
+
+
+
+Beispiel für eine Anwendungsmigration
+
+Dies ist ein Beispiel für die Migration einer Express 3-Anwendung auf Express 4.
+Die dabei interessanten Dateien sind `app.js` und `package.json`.
+
+
+Anwendung der Version 3
+
+
+app.js
+
+Es wird eine Express v.3-Anwendung mit der folgenden Datei `app.js` angenommen:
+
+```js
+var express = require('express');
+var routes = require('./routes');
+var user = require('./routes/user');
+var http = require('http');
+var path = require('path');
+
+var app = express();
+
+// all environments
+app.set('port', process.env.PORT || 3000);
+app.set('views', path.join(__dirname, 'views'));
+app.set('view engine', 'pug');
+app.use(express.favicon());
+app.use(express.logger('dev'));
+app.use(express.methodOverride());
+app.use(express.session({ secret: 'your secret here' }));
+app.use(express.bodyParser());
+app.use(app.router);
+app.use(express.static(path.join(__dirname, 'public')));
+
+// development only
+if (app.get('env') === 'development') {
+ app.use(express.errorHandler());
+}
+
+app.get('/', routes.index);
+app.get('/users', user.list);
+
+http.createServer(app).listen(app.get('port'), () => {
+ console.log('Express server listening on port ' + app.get('port'));
+});
+```
+
+package.json
+
+Die zugehörige `package.json`-Datei der Version 3 sieht in etwa wie folgt aus:
+
+```json
+{
+ "name": "application-name",
+ "version": "0.0.1",
+ "private": true,
+ "scripts": {
+ "start": "node app.js"
+ },
+ "dependencies": {
+ "express": "3.12.0",
+ "pug": "*"
+ }
+}
+```
+
+
+Prozess
+
+
+Beginnen Sie den Migrationsprozess mit der Installation der erforderlichen Middleware für die Express 4-Anwendung und der Aktualisierung von Express und Pug auf die aktuellen Versionen. Verwenden Sie hierzu den folgenden Befehl:
+
+```bash
+$ npm install serve-favicon morgan method-override express-session body-parser multer errorhandler express@latest pug@latest --save
+```
+
+Nehmen Sie an `app.js` die folgenden Änderungen vor:
+
+1. Die integrierten Express-Middlewarefunktionen `express.favicon`,
+ `express.logger`, `express.methodOverride`,
+ `express.session`, `express.bodyParser` und
+ `express.errorHandler` sind im Objekt `express` nicht mehr verfügbar. Sie müssen deren Alternativen manuell installieren und in die Anwendung laden.
+
+2. Sie müssen die Funktion `app.router` nicht mehr laden.
+ Sie ist kein gültiges Express 4-Anwendungsobjekt. Entfernen Sie also den Code `app.use(app.router);`.
+
+3. Stellen Sie sicher, dass die Middlewarefunktionen in der richtigen Reihenfolge geladen werden – laden Sie `errorHandler` nach dem Laden der Anwendungsweiterleitungen.
+
+Anwendung der Version 4
+
+package.json
+
+Durch Ausführung des Befehls `npm` wird `package.json` wie folgt aktualisiert:
+
+```json
+{
+ "name": "application-name",
+ "version": "0.0.1",
+ "private": true,
+ "scripts": {
+ "start": "node app.js"
+ },
+ "dependencies": {
+ "body-parser": "^1.5.2",
+ "errorhandler": "^1.1.1",
+ "express": "^4.8.0",
+ "express-session": "^1.7.2",
+ "pug": "^2.0.0",
+ "method-override": "^2.1.2",
+ "morgan": "^1.2.2",
+ "multer": "^0.1.3",
+ "serve-favicon": "^2.0.1"
+ }
+}
+```
+
+app.js
+
+Entfernen Sie dann ungültigen Code, laden Sie die erforderliche Middleware und nehmen Sie andere Änderungen nach Bedarf vor. Die Datei `app.js` sieht dann wie folgt aus:
+
+```js
+var http = require('http');
+var express = require('express');
+var routes = require('./routes');
+var user = require('./routes/user');
+var path = require('path');
+
+var favicon = require('serve-favicon');
+var logger = require('morgan');
+var methodOverride = require('method-override');
+var session = require('express-session');
+var bodyParser = require('body-parser');
+var multer = require('multer');
+var errorHandler = require('errorhandler');
+
+var app = express();
+
+// all environments
+app.set('port', process.env.PORT || 3000);
+app.set('views', path.join(__dirname, 'views'));
+app.set('view engine', 'pug');
+app.use(favicon(path.join(__dirname, '/public/favicon.ico')));
+app.use(logger('dev'));
+app.use(methodOverride());
+app.use(
+ session({
+ resave: true,
+ saveUninitialized: true,
+ secret: 'uwotm8',
+ })
+);
+app.use(bodyParser.json());
+app.use(bodyParser.urlencoded({ extended: true }));
+app.use(multer());
+app.use(express.static(path.join(__dirname, 'public')));
+
+app.get('/', routes.index);
+app.get('/users', user.list);
+
+// error handling middleware should be loaded after the loading the routes
+if (app.get('env') === 'development') {
+ app.use(errorHandler());
+}
+
+var server = http.createServer(app);
+server.listen(app.get('port'), () => {
+ console.log('Express server listening on port ' + app.get('port'));
+});
+```
+
+Wenn Sie nicht direkt mit dem Modul `http` arbeiten müssen (socket.io/SPDY/HTTPS), ist das Laden des Moduls nicht erforderlich. Die Anwendung kann dann einfach wie folgt gestartet werden:
+
+```js
+app.listen(app.get('port'), () => {
+ console.log('Express server listening on port ' + app.get('port'));
+});
+```
+
+
+
+Anwendung ausführen
+
+Der Migrationsprozess ist abgeschlossen und die Anwendung ist nun eine Express 4-Anwendung. Zum Bestätigen starten Sie die Anwendung mit dem folgenden Befehl:
+
+```bash
+$ node .
+```
+
+Laden Sie [http://localhost:3000](http://localhost:3000) und sehen Sie, wie die Homepage von Express 4 wiedergegeben wird.
+
+Upgrade auf den Express 4 App Generator
+
+Das Befehlszeilentool zum Generieren einer Express-Anwendung ist nach wie vor `express`. Für ein Upgrade auf die neue Version müssen Sie jedoch den Express 3 App Generator deinstallieren und dann den neuen Generator `express-generator` installieren.
+
+Installation
+
+Wenn der Express 3 App Generator bereits auf Ihrem System installiert ist, müssen Sie diesen deinstallieren:
+
+```bash
+$ npm uninstall -g express
+```
+
+Abhängig davon, wie Ihre Datei- und Verzeichnissberechtigungen konfiguriert sind, müssen Sie diesen Befehl möglicherweise mit `sudo` ausführen.
+
+Installieren Sie nun den neuen Generator:
+
+```bash
+$ npm install -g express-generator
+```
+
+Abhängig davon, wie Ihre Datei- und Verzeichnissberechtigungen konfiguriert sind, müssen Sie diesen Befehl möglicherweise mit `sudo` ausführen.
+
+Nun wird der Befehl `express` auf Ihrem System auf den Express 4 App Generator aktualisiert.
+
+Änderungen am App Generator
+
+Befehlsoptionen und -nutzung bleiben größtenteils unverändert. Es gelten jedoch folgende Ausnahmen:
+
+{: .doclist }
+
+- Option `--sessions` wurde entfernt.
+- Option `--jshtml` wurde entfernt.
+- Option `--hogan` wurde hinzugefügt, um [Hogan.js](http://twitter.github.io/hogan.js/) zu unterstützen.
+
+Beispiel
+
+Führen Sie den folgenden Befehl aus, um eine Express 4-Anwendung zu erstellen:
+
+```bash
+$ express app4
+```
+
+Wenn Sie sich den Inhalt der Datei `app4/app.js` ansehen, werden Sie feststellen, dass alle Middlewarefunktionen (außer `express.static`), die für die Anwendung erforderlich sind, als unabhängige Module geladen werden und die Middleware `router` nicht mehr explizit in die Anwendung geladen wird.
+
+Sie werden auch feststellen, dass die Datei `app.js` nun ein Node.js-Modul ist – im Gegensatz zur eigenständigen Anwendung, die vom bisherigen Generator generiert wurde.
+
+Starten Sie nach der Installation der Abhängigkeiten die Anwendung mit dem folgenden Befehl:
+
+```bash
+$ npm start
+```
+
+Wenn Sie sich das npm-Startscript in der Datei `package.json` näher ansehen, werden Sie feststellen, dass der eigentliche Befehl, der die Anwendung startet, `node ./bin/www` heißt. Dieser Befehl lautete in Express 3 `node app.js`.
+
+Da die Datei `app.js`, die vom Express 4 Generator erstellt wurde, nun ein Node.js-Modul ist, kann dieses nicht mehr wie bisher unabhängig als Anwendung gestartet werden (es sei denn, Sie ändern den Code). Das Modul muss in eine Node.js-Datei geladen und über die Node.js-Datei gestartet werden. Die Node.js-Datei ist in diesem Fall `./bin/www`.
+
+Weder das Verzeichnis `bin` noch die erweiterungslose Datei `www` ist für das Erstellen einer Express-Anwendung oder das Starten der Anwendung zwingend erforderlich. Dies sind lediglich Vorschläge des Generators. Sie können diese also je nach Ihren Anforderungen ändern.
+
+Um das Verzeichnis `www` zu löschen und alles im "Express 3-Stil" zu belassen, löschen Sie die Zeile mit dem Eintrag `module.exports = app;` am Ende der Datei `app.js`. Fügen Sie dann stattdessen den folgenden Code an derselben Position ein:
+
+```js
+app.set('port', process.env.PORT || 3000);
+
+var server = app.listen(app.get('port'), () => {
+ debug('Express server listening on port ' + server.address().port);
+});
+```
+
+Stellen Sie sicher, dass Sie das Modul `debug` am Anfang der Datei `app.js` laden. Verwenden Sie dazu den folgenden Code:
+
+```js
+var debug = require('debug')('app4');
+```
+
+Ändern Sie als Nächstes `"start": "node ./bin/www"` in der Datei `package.json` in `"start": "node app.js"`.
+
+Sie haben nun die Funktionalität von `./bin/www` wieder in `app.js` verschoben. Diese Änderung wird nicht empfohlen. Die Übung hat Ihnen jedoch geholfen, zu verstehen, wie die Datei `./bin/www` funktioniert und warum die Datei `app.js` nicht mehr automatisch gestartet wird.
diff --git a/astro/src/content/docs/de/5x/guide/migrating-5.md b/astro/src/content/docs/de/5x/guide/migrating-5.md
new file mode 100644
index 0000000000..1d1d033413
--- /dev/null
+++ b/astro/src/content/docs/de/5x/guide/migrating-5.md
@@ -0,0 +1,587 @@
+---
+title: Migration auf Express 5
+description: A comprehensive guide to migrating your Express.js applications from version 4 to 5, detailing breaking changes, deprecated methods, and new improvements.
+---
+
+# Wechsel zu Express 5
+
+Überblick
+
+Express 5.0 befindet sich noch in der Beta-Release-Phase. Hier finden Sie jedoch bereits eine Vorschau zu den Änderungen in diesem Release und zur Migration Ihrer Express 4-Anwendung auf Express 5.
+
+To install this version, you need to have a Node.js version 18 or higher. Then, execute the following command in your application directory:
+
+```sh
+npm install "express@5"
+```
+
+Sie können Ihre automatisierten Tests ausführen, um zu sehen, was fehlschlägt, und Probleme gemäß den folgenden Updates beheben. Nachdem Sie alle Testfehler behoben haben, führen Sie Ihre Anwendung aus, um zu sehen, welche Fehler noch auftreten. Sie werden sofort feststellen, ob die Anwendung Methoden oder Eigenschaften verwendet, die nicht unterstützt werden.
+
+## Express 5 Codemods
+
+To help you migrate your express server, we have created a set of codemods that will help you automatically update your code to the latest version of Express.
+
+Run the following command for run all the codemods available:
+
+```sh
+npx @expressjs/codemod upgrade
+```
+
+If you want to run a specific codemod, you can run the following command:
+
+```sh
+npx @expressjs/codemod name-of-the-codemod
+```
+
+You can find the list of available codemods [here](https://github.com/expressjs/codemod?tab=readme-ov-file#available-codemods).
+
+Änderungen in Express 5
+
+**Entfernte Methoden und Eigenschaften**
+
+
+
+**Verbesserungen**
+
+
+
+**Geändert**
+
+
+
+## Entfernte Methoden und Eigenschaften
+
+Wenn Sie eine dieser Methoden oder Eigenschaften in Ihrer Anwendung verwenden, stürzt die Anwendung ab. Sie müssen also Ihre Anwendung ändern, wenn Sie auf Version 5 umgestellt haben.
+
+app.del()
+
+Express 5 unterstützt die Funktion `app.del()` nicht mehr. Wenn Sie diese Funktion verwenden, wird ein Fehler ausgelöst. Für die Registrierung von HTTP DELETE-Weiterleitungen verwenden Sie stattdessen die Funktion `app.delete()`.
+
+Anfänglich wurde `del` statt `delete` verwendet, weil `delete` in JavaScript ein reserviertes Schlüsselwort ist. Ab ECMAScript 6 jedoch können `delete` und andere reservierte Schlüsselwörter legal als Eigenschaftsnamen verwendet werden.
+
+{% capture codemod-deprecated-signatures %}
+You can replace the deprecated signatures with the following command:
+
+```plaintext
+npx @expressjs/codemod v4-deprecated-signatures
+```
+
+{% endcapture %}
+
+{% include admonitions/note.html content=codemod-deprecated-signatures %}
+
+```js
+// v4
+app.del('/user/:id', (req, res) => {
+ res.send(`DELETE /user/${req.params.id}`);
+});
+
+// v5
+app.delete('/user/:id', (req, res) => {
+ res.send(`DELETE /user/${req.params.id}`);
+});
+```
+
+app.param(fn)
+
+Die Signatur `app.param(fn)` wurde für die Änderung der Verhaltensweise der Funktion `app.param(name, fn)` verwendet. Seit v4.11.0 wurde sie nicht mehr verwendet. In Express 5 wird sie überhaupt nicht mehr unterstützt.
+
+Pluralisierte Methodennamen
+
+Die folgenden Methodennamen wurden pluralisiert. In Express 4 wurde bei Verwendung der alten Methoden eine Warnung zur Einstellung der Unterstützung ausgegeben. Express 5 unterstützt diese Methoden nicht mehr.
+
+`req.acceptsLanguage()` wird durch `req.acceptsLanguages()` ersetzt.
+
+`req.acceptsCharset()` wird durch `req.acceptsCharsets()` ersetzt.
+
+`req.acceptsEncoding()` wird durch `req.acceptsEncodings()` ersetzt.
+
+{% capture codemod-pluralized-methods %}
+You can replace the deprecated signatures with the following command:
+
+```plaintext
+npx @expressjs/codemod pluralized-methods
+```
+
+{% endcapture %}
+
+{% include admonitions/note.html content=codemod-pluralized-methods %}
+
+```js
+// v4
+app.all('/', (req, res) => {
+ req.acceptsCharset('utf-8');
+ req.acceptsEncoding('br');
+ req.acceptsLanguage('en');
+
+ // ...
+});
+
+// v5
+app.all('/', (req, res) => {
+ req.acceptsCharsets('utf-8');
+ req.acceptsEncodings('br');
+ req.acceptsLanguages('en');
+
+ // ...
+});
+```
+
+Führender Doppelpunkt (:) im Namen für app.param(name, fn)
+
+Ein führendes Doppelpunktzeichen (:) im Namen für die Funktion `app.param(name, fn)` ist ein Überbleibsel aus Express 3. Aus Gründen der Abwärtskompatibilität wurde dieser Name in Express 4 mit einem Hinweis zu veralteten Versionen weiter unterstützt. In Express 5 wird dieser Name stillschwiegend ignoriert und der Namensparameter ohne einen vorangestellten Doppelpunkt verwendet.
+
+Dies dürfte keine Auswirkungen auf Ihren Code haben, wenn Sie die Express 4-Dokumentation zu [app.param](/en/4x/api#app.param) befolgen, da dort der führende Doppelpunkt nicht erwähnt wird.
+
+req.param(name)
+
+Dieses potenziell verwirrende und durchaus riskante Verfahren des Abrufens von Formulardaten wurde entfernt. Sie müssen nun ganz speziell nach dem übergebenen Parameternamen im Objekt `req.params`, `req.body` oder `req.query` suchen.
+
+{% capture codemod-req-param %}
+You can replace the deprecated signatures with the following command:
+
+```plaintext
+npx @expressjs/codemod req-param
+```
+
+{% endcapture %}
+
+{% include admonitions/note.html content=codemod-req-param %}
+
+```js
+// v4
+app.post('/user', (req, res) => {
+ const id = req.param('id');
+ const body = req.param('body');
+ const query = req.param('query');
+
+ // ...
+});
+
+// v5
+app.post('/user', (req, res) => {
+ const id = req.params.id;
+ const body = req.body;
+ const query = req.query;
+
+ // ...
+});
+```
+
+res.json(obj, status)
+
+Express 5 unterstützt die Signatur `res.json(obj, status)` nicht mehr. Stattdessen müssen Sie den Status festlegen und diesen dann mit `res.json()`-Methoden wie dieser verketten: `res.status(status).json(obj)`.
+
+{% include admonitions/note.html content=codemod-deprecated-signatures %}
+
+```js
+// v4
+app.post('/user', (req, res) => {
+ res.json({ name: 'Ruben' }, 201);
+});
+
+// v5
+app.post('/user', (req, res) => {
+ res.status(201).json({ name: 'Ruben' });
+});
+```
+
+res.jsonp(obj, status)
+
+Express 5 unterstützt die Signatur `res.jsonp(obj, status)` nicht mehr. Stattdessen müssen Sie den Status festlegen und diesen dann mit `res.jsonp()`-Methoden wie dieser verketten: `res.status(status).jsonp(obj)`.
+
+{% include admonitions/note.html content=codemod-deprecated-signatures %}
+
+```js
+// v4
+app.post('/user', (req, res) => {
+ res.jsonp({ name: 'Ruben' }, 201);
+});
+
+// v5
+app.post('/user', (req, res) => {
+ res.status(201).jsonp({ name: 'Ruben' });
+});
+```
+
+res.redirect(url, status)
+
+Express 5 unterstützt die Signatur `res.send(obj, status)` nicht mehr. Stattdessen müssen Sie den Status festlegen und diesen dann mit `res.send()`-Methoden wie dieser verketten: `res.status(status).send(obj)`.
+
+{% include admonitions/note.html content=codemod-deprecated-signatures %}
+
+```js
+// v4
+app.get('/user', (req, res) => {
+ res.redirect('/users', 301);
+});
+
+// v5
+app.get('/user', (req, res) => {
+ res.redirect(301, '/users');
+});
+```
+
+res.redirect('back') and res.location('back')
+
+Express 5 no longer supports the magic string `back` in the `res.redirect()` and `res.location()` methods. Instead, use the `req.get('Referrer') || '/'` value to redirect back to the previous page. In Express 4, the `res.redirect('back')` and `res.location('back')` methods were deprecated.
+
+{% capture codemod-magic-redirect %}
+You can replace the deprecated signatures with the following command:
+
+```plaintext
+npx @expressjs/codemod magic-redirect
+```
+
+{% endcapture %}
+
+{% include admonitions/note.html content=codemod-magic-redirect %}
+
+```js
+// v4
+app.get('/user', (req, res) => {
+ res.redirect('back');
+});
+
+// v5
+app.get('/user', (req, res) => {
+ res.redirect(req.get('Referrer') || '/');
+});
+```
+
+res.send(body, status)
+
+Express 5 no longer supports the signature `res.send(obj, status)`. Instead, set the status and then chain it to the `res.send()` method like this: `res.status(status).send(obj)`.
+
+{% include admonitions/note.html content=codemod-deprecated-signatures %}
+
+```js
+// v4
+app.get('/user', (req, res) => {
+ res.send({ name: 'Ruben' }, 200);
+});
+
+// v5
+app.get('/user', (req, res) => {
+ res.status(200).send({ name: 'Ruben' });
+});
+```
+
+res.send(status)
+
+Express 5 unterstützt die Signatur res.send(status ), nicht mehr, wobei _`status`_ für eine Zahl steht. Verwenden Sie stattdessen die Funktion `res.sendStatus(statusCode)`, mit der der Statuscode für den HTTP-Antwort-Header festgelegt und die Textversion des Codes gesendet wird: "Not Found" (Nicht gefunden), "Internal Server Error" (Interner Serverfehler) usw.
+Wenn Sie eine Zahl senden und hierfür die Funktion `res.send()` verwenden müssen, müssen Sie die Zahl in Anführungszeichen setzen, um diese in eine Zeichenfolge zu konvertieren. Dadurch interpretiert Express diese Zahl nicht als Versuch, die nicht mehr unterstützte alte Signatur zu verwenden.
+
+{% include admonitions/note.html content=codemod-deprecated-signatures %}
+
+```js
+// v4
+app.get('/user', (req, res) => {
+ res.send(200);
+});
+
+// v5
+app.get('/user', (req, res) => {
+ res.sendStatus(200);
+});
+```
+
+res.sendfile()
+
+Die Funktion `res.sendfile()` wurde durch eine Version in Camel-Schreibweise von `res.sendFile()` in Express 5 ersetzt.
+
+**Note:** In Express 5, `res.sendFile()` uses the `mime-types` package for MIME type detection, which returns different Content-Type values than Express 4 for several common file types:
+
+- JavaScript files (.js): now "text/javascript" instead of "application/javascript"
+- JSON files (.json): now "application/json" instead of "text/json"
+- CSS files (.css): now "text/css" instead of "text/plain"
+- XML files (.xml): now "application/xml" instead of "text/xml"
+- Font files (.woff): now "font/woff" instead of "application/font-woff"
+- SVG files (.svg): now "image/svg+xml" instead of "application/svg+xml"
+
+{% include admonitions/note.html content=codemod-deprecated-signatures %}
+
+```js
+// v4
+app.get('/user', (req, res) => {
+ res.sendfile('/path/to/file');
+});
+
+// v5
+app.get('/user', (req, res) => {
+ res.sendFile('/path/to/file');
+});
+```
+
+router.param(fn)
+
+The `router.param(fn)` signature was used for modifying the behavior of the `router.param(name, fn)` function. Seit v4.11.0 wurde sie nicht mehr verwendet. In Express 5 wird sie überhaupt nicht mehr unterstützt.
+
+express.static.mime
+
+In Express 5, `mime` is no longer an exported property of the `static` field.
+Use the [`mime-types` package](https://github.com/jshttp/mime-types) to work with MIME type values.
+
+**Important:** This change affects not only direct usage of `express.static.mime` but also other Express methods that rely on MIME type detection, such as `res.sendFile()`. The following MIME types have changed from Express 4:
+
+- JavaScript files (.js): now served as "text/javascript" instead of "application/javascript"
+- JSON files (.json): now served as "application/json" instead of "text/json"
+- CSS files (.css): now served as "text/css" instead of "text/plain"
+- HTML files (): now served as "text/html; charset=utf-8" instead of just "text/html"
+- XML files (.xml): now served as "application/xml" instead of "text/xml"
+- Font files (.woff): now served as "font/woff" instead of "application/font-woff"
+
+```js
+// v4
+express.static.mime.lookup('json');
+
+// v5
+const mime = require('mime-types');
+mime.lookup('json');
+```
+
+express:router debug logs
+
+In Express 5, router handling logic is performed by a dependency. Therefore, the
+debug logs for the router are no longer available under the `express:` namespace.
+In v4, the logs were available under the namespaces `express:router`, `express:router:layer`,
+and `express:router:route`. All of these were included under the namespace `express:*`.
+In v5.1+, the logs are available under the namespaces `router`, `router:layer`, and `router:route`.
+The logs from `router:layer` and `router:route` are included in the namespace `router:*`.
+To achieve the same detail of debug logging when using `express:*` in v4, use a conjunction of
+`express:*`, `router`, and `router:*`.
+
+```sh
+# v4
+DEBUG=express:* node index.js
+
+# v5
+DEBUG=express:*,router,router:* node index.js
+```
+
+## Geändert
+
+Path route matching syntax
+
+Path route matching syntax is when a string is supplied as the first parameter to the `app.all()`, `app.use()`, `app.METHOD()`, `router.all()`, `router.METHOD()`, and `router.use()` APIs. The following changes have been made to how the path string is matched to an incoming request:
+
+- The wildcard `*` must have a name, matching the behavior of parameters `:`, use `/*splat` instead of `/*`
+
+```js
+// v4
+app.get('/*', async (req, res) => {
+ res.send('ok');
+});
+
+// v5
+app.get('/*splat', async (req, res) => {
+ res.send('ok');
+});
+```
+
+{% capture note_wildcard %}
+`*splat` matches any path without the root path. If you need to match the root path as well `/`, you can use `/{*splat}`, wrapping the wildcard in braces.
+
+```js
+// v5
+app.get('/{*splat}', async (req, res) => {
+ res.send('ok');
+});
+```
+
+{% endcapture %}
+{% include admonitions/note.html content=note_wildcard %}
+
+- The optional character `?` is no longer supported, use braces instead.
+
+```js
+// v4
+app.get('/:file.:ext?', async (req, res) => {
+ res.send('ok');
+});
+
+// v5
+app.get('/:file{.:ext}', async (req, res) => {
+ res.send('ok');
+});
+```
+
+- Regexp characters are not supported. Beispiel:
+
+```js
+app.get('/[discussion|page]/:slug', async (req, res) => {
+ res.status(200).send('ok');
+});
+```
+
+should be changed to:
+
+```js
+app.get(['/discussion/:slug', '/page/:slug'], async (req, res) => {
+ res.status(200).send('ok');
+});
+```
+
+- Some characters have been reserved to avoid confusion during upgrade (`()[]?+!`), use `\` to escape them.
+- Parameter names now support valid JavaScript identifiers, or quoted like `:"this"`.
+
+Rejected promises handled from middleware and handlers
+
+Request middleware and handlers that return rejected promises are now handled by forwarding the rejected value as an `Error` to the error handling middleware. This means that using `async` functions as middleware and handlers are easier than ever. When an error is thrown in an `async` function or a rejected promise is `await`ed inside an async function, those errors will be passed to the error handler as if calling `next(err)`.
+
+Details of how Express handles errors is covered in the [error handling documentation](/en/guide/error-handling).
+
+express.urlencoded
+
+The `express.urlencoded` method makes the `extended` option `false` by default.
+
+express.static dotfiles
+
+In Express 5, the `express.static` middleware's `dotfiles` option now defaults to `"ignore"`. This is a change from Express 4, where dotfiles were served by default. As a result, files inside a directory that starts with a dot (`.`), such as `.well-known`, will no longer be accessible and will return a **404 Not Found** error. This can break functionality that depends on serving dot-directories, such as Android App Links, and Apple Universal Links.
+
+Example of breaking code:
+
+```js
+// v4
+app.use(express.static('public'));
+```
+
+After migrating to Express 5, a request to `/.well-known/assetlinks.json` will result in a **404 Not Found**.
+
+To fix this, serve specific dot-directories explicitly using the `dotfiles: "allow"` option:
+
+```js
+// v5
+app.use('/.well-known', express.static('public/.well-known', { dotfiles: 'allow' }));
+app.use(express.static('public'));
+```
+
+This approach allows you to safely serve only the intended dot-directories while keeping the default secure behavior for other dotfiles, which remain inaccessible.
+
+app.listen
+
+In Express 5, the `app.listen` method will invoke the user-provided callback function (if provided) when the server receives an error event. In Express 4, such errors would be thrown. This change shifts error-handling responsibility to the callback function in Express 5. If there is an error, it will be passed to the callback as an argument.
+Beispiel:
+
+```js
+const server = app.listen(8080, '0.0.0.0', (error) => {
+ if (error) {
+ throw error; // e.g. EADDRINUSE
+ }
+ console.log(`Listening on ${JSON.stringify(server.address())}`);
+});
+```
+
+app.router
+
+Das Objekt `app.router`, das in Express 4 entfernt wurde, ist in Express 5 wieder verfügbar. In der neuen Version fungiert dieses Objekt nur als Referenz zum Express-Basisrouter – im Gegensatz zu Express 3, wo die Anwendung dieses Objekt explizit laden musste.
+
+req.body
+
+The `req.body` property returns `undefined` when the body has not been parsed. In Express 4, it returns `{}` by default.
+
+req.host
+
+In Express 4 übergab die Funktion `req.host` nicht ordnungsgemäß eine eventuell vorhandene Portnummer. In Express 5 wird die Portnummer beibehalten.
+
+req.params
+
+The `req.params` object now has a **null prototype** when using string paths. However, if the path is defined with a regular expression, `req.params` remains a standard object with a normal prototype. Additionally, there are two important behavioral changes:
+
+**Wildcard parameters are now arrays:**
+
+Wildcards (e.g., `/*splat`) capture path segments as an array instead of a single string.
+
+```js
+app.get('/*splat', (req, res) => {
+ // GET /foo/bar
+ console.dir(req.params);
+ // => [Object: null prototype] { splat: [ 'foo', 'bar' ] }
+});
+```
+
+**Unmatched parameters are omitted:**
+
+In Express 4, unmatched wildcards were empty strings (`''`) and optional `:` parameters (using `?`) had a key with value `undefined`. In Express 5, unmatched parameters are completely omitted from `req.params`.
+
+```js
+// v4: unmatched wildcard is empty string
+app.get('/*', (req, res) => {
+ // GET /
+ console.dir(req.params);
+ // => { '0': '' }
+});
+
+// v4: unmatched optional param is undefined
+app.get('/:file.:ext?', (req, res) => {
+ // GET /image
+ console.dir(req.params);
+ // => { file: 'image', ext: undefined }
+});
+
+// v5: unmatched optional param is omitted
+app.get('/:file{.:ext}', (req, res) => {
+ // GET /image
+ console.dir(req.params);
+ // => [Object: null prototype] { file: 'image' }
+});
+```
+
+req.query
+
+The `req.query` property is no longer a writable property and is instead a getter. The default query parser has been changed from "extended" to "simple".
+
+res.clearCookie
+
+The `res.clearCookie` method ignores the `maxAge` and `expires` options provided by the user.
+
+res.status
+
+The `res.status` method only accepts integers in the range of `100` to `999`, following the behavior defined by Node.js, and it returns an error when the status code is not an integer.
+
+res.vary
+
+The `res.vary` throws an error when the `field` argument is missing. In Express 4, if the argument was omitted, it gave a warning in the console
+
+## Verbesserungen
+
+res.render()
+
+Diese Methode erzwingt nun asynchrones Verhalten für alle View-Engines, sodass durch View-Engines mit synchroner Implementierung verursachte Fehler vermieden werden, durch die die empfohlene Schnittstelle nicht verwendet werden konnte.
+
+Brotli encoding support
+
+Express 5 supports Brotli encoding for requests received from clients that support it.
diff --git a/astro/src/content/docs/de/5x/guide/overriding-express-api.md b/astro/src/content/docs/de/5x/guide/overriding-express-api.md
new file mode 100644
index 0000000000..8f78a06422
--- /dev/null
+++ b/astro/src/content/docs/de/5x/guide/overriding-express-api.md
@@ -0,0 +1,70 @@
+---
+title: Overriding the Express API
+description: Discover how to customize and extend the Express.js API by overriding methods and properties on the request and response objects using prototypes.
+---
+
+# Overriding the Express API
+
+The Express API consists of various methods and properties on the request and response objects. These are inherited by prototype. There are two extension points for the Express API:
+
+1. The global prototypes at `express.request` and `express.response`.
+2. App-specific prototypes at `app.request` and `app.response`.
+
+Altering the global prototypes will affect all loaded Express apps in the same process. If desired, alterations can be made app-specific by only altering the app-specific prototypes after creating a new app.
+
+## Methods
+
+You can override the signature and behavior of existing methods with your own, by assigning a custom function.
+
+Following is an example of overriding the behavior of [res.sendStatus](/en/4x/api#res.sendStatus).
+
+```js
+app.response.sendStatus = function (statusCode, type, message) {
+ // code is intentionally kept simple for demonstration purpose
+ return this.contentType(type).status(statusCode).send(message);
+};
+```
+
+The above implementation completely changes the original signature of `res.sendStatus`. It now accepts a status code, encoding type, and the message to be sent to the client.
+
+The overridden method may now be used this way:
+
+```js
+res.sendStatus(404, 'application/json', '{"error":"resource not found"}');
+```
+
+## Properties
+
+Properties in the Express API are either:
+
+1. Assigned properties (ex: `req.baseUrl`, `req.originalUrl`)
+2. Defined as getters (ex: `req.secure`, `req.ip`)
+
+Since properties under category 1 are dynamically assigned on the `request` and `response` objects in the context of the current request-response cycle, their behavior cannot be overridden.
+
+Properties under category 2 can be overwritten using the Express API extensions API.
+
+The following code rewrites how the value of `req.ip` is to be derived. Now, it simply returns the value of the `Client-IP` request header.
+
+```js
+Object.defineProperty(app.request, 'ip', {
+ configurable: true,
+ enumerable: true,
+ get() {
+ return this.get('Client-IP');
+ },
+});
+```
+
+## Prototype
+
+In order to provide the Express API, the request/response objects passed to Express (via `app(req, res)`, for example) need to inherit from the same prototype chain. By default, this is `http.IncomingRequest.prototype` for the request and `http.ServerResponse.prototype` for the response.
+
+Unless necessary, it is recommended that this be done only at the application level, rather than globally. Also, take care that the prototype that is being used matches the functionality as closely as possible to the default prototypes.
+
+```js
+// Use FakeRequest and FakeResponse in place of http.IncomingRequest and http.ServerResponse
+// for the given app reference
+Object.setPrototypeOf(Object.getPrototypeOf(app.request), FakeRequest.prototype);
+Object.setPrototypeOf(Object.getPrototypeOf(app.response), FakeResponse.prototype);
+```
diff --git a/astro/src/content/docs/de/5x/guide/routing.md b/astro/src/content/docs/de/5x/guide/routing.md
new file mode 100644
index 0000000000..5e5c52fbae
--- /dev/null
+++ b/astro/src/content/docs/de/5x/guide/routing.md
@@ -0,0 +1,417 @@
+---
+title: Weiterleitung in Express
+description: Learn how to define and use routes in Express.js applications, including route methods, route paths, parameters, and using Router for modular routing.
+---
+
+# Weiterleitung (Routing)
+
+Der Begriff _Weiterleitung_ (Routing) bezieht sich auf die Definition von Anwendungsendpunkten (URIs) und deren Antworten auf Clientanforderungen.
+Eine Einführung in dieses Routing siehe [Basisrouting](/en/starter/basic-routing).
+
+You define routing using methods of the Express `app` object that correspond to HTTP methods;
+for example, `app.get()` to handle GET requests and `app.post` to handle POST requests. For a full list,
+see [app.METHOD](/en/5x/api#app.METHOD). You can also use [app.all()](/en/5x/api#app.all) to handle all HTTP methods and [app.use()](/en/5x/api#app.use) to
+specify middleware as the callback function (See [Using middleware](/en/guide/using-middleware) for details).
+
+These routing methods specify a callback function (sometimes called "handler functions") called when the application receives a request to the specified route (endpoint) and HTTP method. In other words, the application "listens" for requests that match the specified route(s) and method(s), and when it detects a match, it calls the specified callback function.
+
+In fact, the routing methods can have more than one callback function as arguments.
+With multiple callback functions, it is important to provide `next` as an argument to the callback function and then call `next()` within the body of the function to hand off control
+to the next callback.
+
+Der folgende Code ist ein Beispiel für ein sehr einfaches Basisrouting.
+
+```js
+const express = require('express');
+const app = express();
+
+// respond with "hello world" when a GET request is made to the homepage
+app.get('/', (req, res) => {
+ res.send('hello world');
+});
+```
+
+Weiterleitungsmethoden
+
+Eine Weiterleitungsmethode wird von einer HTTP-Methode abgeleitet und an eine Instanz der Klasse `express` angehängt.
+
+Der folgende Code ist ein Beispiel für Weiterleitungen, die für die Methoden GET und POST zum Stamm (Root) der Anwendung definiert werden.
+
+```js
+// GET method route
+app.get('/', (req, res) => {
+ res.send('GET request to the homepage');
+});
+
+// POST method route
+app.post('/', (req, res) => {
+ res.send('POST request to the homepage');
+});
+```
+
+Express supports methods that correspond to all HTTP request methods: `get`, `post`, and so on.
+For a full list, see [app.METHOD](/en/5x/api#app.METHOD).
+
+Es gibt eine spezielle Weiterleitungsmethode, `app.all()`, die nicht von einer HTTP-Methode abgeleitet wird. Diese Methode wird zum Laden von Middlewarefunktionen bei einem Pfad für alle Anforderungsmethoden verwendet. Im folgenden Beispiel wird der Handler für Anforderungen zur Weiterleitung "/secret" ausgeführt, um herauszufinden, ob Sie GET-, POST-, PUT-, DELETE- oder andere HTTP-Anforderungsmethoden verwenden, die im [HTTP-Modul](https://nodejs.org/api/http.html#http_http_methods) unterstützt werden.
+
+```js
+app.all('/secret', (req, res, next) => {
+ console.log('Accessing the secret section ...');
+ next(); // pass control to the next handler
+});
+```
+
+Weiterleitungspfade
+
+Über Weiterleitungspfade werden in Kombination mit einer Anforderungsmethode die Endpunkte definiert, bei denen Anforderungen erfolgen können. Weiterleitungspfade können Zeichenfolgen, Zeichenfolgemuster oder reguläre Ausdrücke sein.
+
+{% capture caution-character %} In express 5, the characters `?`, `+`, `*`, `[]`, and `()` are handled differently than in version 4, please review the [migration guide](/en/guide/migrating-5#path-syntax) for more information.{% endcapture %}
+
+{% include admonitions/caution.html content=caution-character %}
+
+{% capture note-dollar-character %}In express 4, regular expression characters such as `$` need to be escaped with a `\`.
+{% endcapture %}
+
+{% include admonitions/caution.html content=note-dollar-character %}
+
+{% capture note-path-to-regexp %}
+
+Express uses [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) for matching the route paths; see the path-to-regexp documentation for all the possibilities in defining route paths. [Express Route Tester](http://forbeslindesay.github.io/express-route-tester/) ist ein handliches Tool zum Testen von Express-Basisweiterleitungen, auch wenn dieses Tool keine Musterabgleiche unterstützt.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=note-path-to-regexp %}
+
+{% capture query-string-note %}
+
+Query strings are not part of the route path.
+
+{% endcapture %}
+
+{% include admonitions/warning.html content=query-string-note %}
+
+### Route paths based on strings
+
+Dieser Weiterleitungspfad gleicht Weiterleitungsanforderungen zum Stammverzeichnis (`/`) ab.
+
+```js
+app.get('/', (req, res) => {
+ res.send('root');
+});
+```
+
+Dieser Weiterleitungspfad gleicht Anforderungen mit `/about` ab.
+
+```js
+app.get('/about', (req, res) => {
+ res.send('about');
+});
+```
+
+Dieser Weiterleitungspfad gleicht Anforderungen mit `/random.text` ab.
+
+```js
+app.get('/random.text', (req, res) => {
+ res.send('random.text');
+});
+```
+
+### Route paths based on string patterns
+
+{% capture caution-string-patterns %} The string patterns in Express 5 no longer work. Please refer to the [migration guide](/en/guide/migrating-5#path-syntax) for more information.{% endcapture %}
+
+{% include admonitions/caution.html content=caution-string-patterns %}
+
+Dieser Weiterleitungspfad gleicht `acd` und `abcd` ab.
+
+```js
+app.get('/ab?cd', (req, res) => {
+ res.send('ab?cd');
+});
+```
+
+Dies sind einige Beispiele für Weiterleitungspfade auf Basis von Zeichenfolgemustern.
+
+```js
+app.get('/ab+cd', (req, res) => {
+ res.send('ab+cd');
+});
+```
+
+Dies sind einige Beispiele für Weiterleitungspfade auf Basis von Zeichenfolgen.
+
+```js
+app.get('/ab*cd', (req, res) => {
+ res.send('ab*cd');
+});
+```
+
+Dieser Weiterleitungspfad gleicht `/abe` und `/abcde` ab.
+
+```js
+app.get('/ab(cd)?e', (req, res) => {
+ res.send('ab(cd)?e');
+});
+```
+
+### Route paths based on regular expressions
+
+Dieser Weiterleitungspfad gleicht alle Weiterleitungsnamen ab, die den Buchstaben "a" enthalten.
+
+```js
+app.get(/a/, (req, res) => {
+ res.send('/a/');
+});
+```
+
+Dieser Weiterleitungspfad gleicht `butterfly` und `dragonfly`, jedoch nicht `butterflyman`, `dragonfly man` usw.
+
+```js
+app.get(/.*fly$/, (req, res) => {
+ res.send('/.*fly$/');
+});
+```
+
+Route parameters
+
+Route parameters are named URL segments that are used to capture the values specified at their position in the URL. The captured values are populated in the `req.params` object, with the name of the route parameter specified in the path as their respective keys.
+
+```
+Route path: /users/:userId/books/:bookId
+Request URL: http://localhost:3000/users/34/books/8989
+req.params: { "userId": "34", "bookId": "8989" }
+```
+
+To define routes with route parameters, simply specify the route parameters in the path of the route as shown below.
+
+```js
+app.get('/users/:userId/books/:bookId', (req, res) => {
+ res.send(req.params);
+});
+```
+
+
+The name of route parameters must be made up of "word characters" ([A-Za-z0-9_]).
+
+
+Since the hyphen (`-`) and the dot (`.`) are interpreted literally, they can be used along with route parameters for useful purposes.
+
+```
+Route path: /flights/:from-:to
+Request URL: http://localhost:3000/flights/LAX-SFO
+req.params: { "from": "LAX", "to": "SFO" }
+```
+
+```
+Route path: /plantae/:genus.:species
+Request URL: http://localhost:3000/plantae/Prunus.persica
+req.params: { "genus": "Prunus", "species": "persica" }
+```
+
+{% capture warning-regexp %}
+In express 5, Regexp characters are not supported in route paths, for more information please refer to the [migration guide](/en/guide/migrating-5#path-syntax).{% endcapture %}
+
+{% include admonitions/caution.html content=warning-regexp %}
+
+To have more control over the exact string that can be matched by a route parameter, you can append a regular expression in parentheses (`()`):
+
+```
+Route path: /user/:userId(\d+)
+Request URL: http://localhost:3000/user/42
+req.params: {"userId": "42"}
+```
+
+{% capture escape-advisory %}
+
+Because the regular expression is usually part of a literal string, be sure to escape any `\` characters with an additional backslash, for example `\\d+`.
+
+{% endcapture %}
+
+{% include admonitions/warning.html content=escape-advisory %}
+
+{% capture warning-version %}
+
+In Express 4.x, the `*` character in regular expressions is not interpreted in the usual way . As a workaround, use `{0,}` instead of `*`. This will likely be fixed in Express 5.
+
+{% endcapture %}
+
+{% include admonitions/warning.html content=warning-version %}
+
+Routenhandler (Weiterleitungsroutinen)
+
+Sie können mehrere Callback-Funktionen angeben, die sich wie [Middleware](/en/guide/using-middleware) verhalten, um eine Anforderung zu verarbeiten. Die einzige Ausnahme hierbei ist, dass diese Callbacks möglicherweise `next('route')` aufrufen, um die verbleibenden Weiterleitungs-Callbacks zu umgehen. Mit diesem Verfahren können Sie Vorabbedingungen für eine Weiterleitung festlegen und dann die Steuerung an nachfolgende Weiterleitungen übergeben, wenn kein Grund vorliegt, mit der aktuellen Weiterleitung fortzufahren.
+
+```js
+app.get('/user/:id', (req, res, next) => {
+ if (req.params.id === '0') {
+ return next('route');
+ }
+ res.send(`User ${req.params.id}`);
+});
+
+app.get('/user/:id', (req, res) => {
+ res.send('Special handler for user ID 0');
+});
+```
+
+In this example:
+
+- `GET /user/5` → handled by first route → sends "User 5"
+- `GET /user/0` → first route calls `next('route')`, skipping to the next matching `/user/:id` route
+
+Routenhandler können eine Funktion und/oder ein Funktionsarray sein, wie in den folgenden Beispielen zu sehen ist.
+
+Eine einzelne Callback-Funktion kann eine Weiterleitung verarbeiten. Beispiel:
+
+```js
+app.get('/example/a', (req, res) => {
+ res.send('Hello from A!');
+});
+```
+
+Mehrere Callback-Funktionen können eine Weiterleitung verarbeiten (achten Sie darauf, dass Sie das Objekt `next` angeben). Beispiel:
+
+```js
+app.get(
+ '/example/b',
+ (req, res, next) => {
+ console.log('the response will be sent by the next function ...');
+ next();
+ },
+ (req, res) => {
+ res.send('Hello from B!');
+ }
+);
+```
+
+Ein Array von Callback-Funktionen kann eine Weiterleitung verarbeiten. Beispiel:
+
+```js
+const cb0 = function (req, res, next) {
+ console.log('CB0');
+ next();
+};
+
+const cb1 = function (req, res, next) {
+ console.log('CB1');
+ next();
+};
+
+const cb2 = function (req, res) {
+ res.send('Hello from C!');
+};
+
+app.get('/example/c', [cb0, cb1, cb2]);
+```
+
+Eine Kombination aus unabhängigen Funktionen und Funktionsarrays kann eine Weiterleitung verarbeiten. Beispiel:
+
+```js
+const cb0 = function (req, res, next) {
+ console.log('CB0');
+ next();
+};
+
+const cb1 = function (req, res, next) {
+ console.log('CB1');
+ next();
+};
+
+app.get(
+ '/example/d',
+ [cb0, cb1],
+ (req, res, next) => {
+ console.log('the response will be sent by the next function ...');
+ next();
+ },
+ (req, res) => {
+ res.send('Hello from D!');
+ }
+);
+```
+
+Antwortmethoden
+
+Über die Methoden für das Antwortobjekt (`res`) in der folgenden Tabelle kann eine Antwort an den Client gesendet und der Anforderung/Antwort-Zyklus beendet werden. Wenn keine dieser Methoden über einen Routenhandler aufgerufen wird, bleibt die Clientanforderung im Status "blockiert".
+
+| Methode | Beschreibung |
+| --------------------------------------------- | ----------------------------------------------------------------------------------------------- |
+| [res.download()](/en/4x/api#res.download) | Gibt eine Eingabeaufforderung zum Herunterladen einer Datei aus. |
+| [res.end()](/en/4x/api#res.end) | End the response process. |
+| [res.json()](/en/4x/api#res.json) | Sendet eine JSON-Antwort. |
+| [res.jsonp()](/en/4x/api#res.jsonp) | Sendet eine JSON-Antwort mit JSONP-Unterstützung. |
+| [res.redirect()](/en/4x/api#res.redirect) | Leitet eine Anforderung um. |
+| [res.render()](/en/4x/api#res.render) | Render a view template. |
+| [res.send()](/en/4x/api#res.send) | Sendet eine Antwort mit unterschiedlichen Typen. |
+| [res.sendFile](/en/4x/api#res.sendFile) | Sendet eine Datei als Oktett-Stream. |
+| [res.sendStatus()](/en/4x/api#res.sendStatus) | Legt den Antwortstatuscode fest und sendet dessen Zeichenfolgedarstellung als Antworthauptteil. |
+
+app.route()
+
+Sie können mithilfe von `app.route()` verkettbare Routenhandler für einen Weiterleitungspfad erstellen.
+Da der Pfad an einer einzelnen Position angegeben wird, ist das Erstellen modularer Weiterleitungen hilfreich, da Redundanzen und Schreibfehler reduziert werden. Weitere Informationen zu Weiterleitungen finden Sie in der Dokumentation zu [Router()](/en/4x/api#router).
+
+Dies ist ein Beispiel für verkettete Routenhandler, die mit der Funktion `app.route()` definiert werden.
+
+```js
+app
+ .route('/book')
+ .get((req, res) => {
+ res.send('Get a random book');
+ })
+ .post((req, res) => {
+ res.send('Add a book');
+ })
+ .put((req, res) => {
+ res.send('Update the book');
+ });
+```
+
+express.Router
+
+Mit der Klasse `express.Router` lassen sich modular einbindbare Routenhandler erstellen. Eine `Router`-Instanz ist ein vollständiges Middleware- und Routingsystem. Aus diesem Grund wird diese Instanz oft auch als "Mini-App" bezeichnet.
+
+Im folgenden Beispiel wird ein Router als Modul erstellt, eine Middlewarefunktion in das Modul geladen, es werden Weiterleitungen definiert und das Modul letztendlich in einen Pfad in der Hauptanwendung eingebunden.
+
+Erstellen Sie eine Routerdatei namens `birds.js` mit dem folgenden Inhalt im Anwendungsverzeichnis:
+
+```js
+const express = require('express');
+const router = express.Router();
+
+// middleware that is specific to this router
+const timeLog = (req, res, next) => {
+ console.log('Time: ', Date.now());
+ next();
+};
+router.use(timeLog);
+
+// define the home page route
+router.get('/', (req, res) => {
+ res.send('Birds home page');
+});
+// define the about route
+router.get('/about', (req, res) => {
+ res.send('About birds');
+});
+
+module.exports = router;
+```
+
+Laden Sie dann das Routermodul in die Anwendung:
+
+```js
+const birds = require('./birds');
+
+// ...
+
+app.use('/birds', birds);
+```
+
+Die Anwendung kann nun Anforderungen an die Pfade `/birds` und `/birds/about` bearbeiten und ruft die Middlewarefunktion `timeLog` auf, die speziell für diese Weiterleitung bestimmt ist.
+
+But if the parent route `/birds` has path parameters, it will not be accessible by default from the sub-routes. To make it accessible, you will need to pass the `mergeParams` option to the Router constructor [reference](/en/5x/api#app.use).
+
+```js
+const router = express.Router({ mergeParams: true });
+```
diff --git a/astro/src/content/docs/de/5x/guide/using-middleware.md b/astro/src/content/docs/de/5x/guide/using-middleware.md
new file mode 100644
index 0000000000..f5987bc806
--- /dev/null
+++ b/astro/src/content/docs/de/5x/guide/using-middleware.md
@@ -0,0 +1,293 @@
+---
+title: Express-Middleware verwenden
+description: Learn how to use middleware in Express.js applications, including application-level and router-level middleware, error handling, and integrating third-party middleware.
+---
+
+# Middleware verwenden
+
+Express ist ein Weiterleitungs- und Middleware-Web-Framework, das selbst nur minimale Funktionalität aufweist: Eine Express-Anwendung besteht im Wesentlichen aus einer Reihe von Middlewarefunktionsaufrufen.
+
+_Middleware_ functions are functions that have access to the [request object](/en/5x/api#req) (`req`), the [response object](/en/5x/api#res) (`res`), and the next middleware function in the application's request-response cycle. Die nächste Middlewarefunktion wird im Allgemeinen durch die Variable `next` bezeichnet.
+
+Über Middlewarefunktionen lassen sich die folgenden Tasks ausführen:
+
+- Ausführen von Code
+- Vornehmen von Änderungen an der Anforderung und an Antwortobjekten
+- End the request-response cycle.
+- Aufrufen der nächsten Middlewarefunktion im Stack
+
+Wenn über die aktuelle Middlewarefunktion der Anforderung/Antwort-Zyklus nicht beendet werden kann, muss `next()` aufgerufen werden, um die Steuerung an die nächste Middlewarefunktion zu übergeben. Andernfalls geht die Anforderung in den Status "Blockiert" über.
+
+Eine Express-Anwendung kann die folgenden Middlewaretypen verwenden:
+
+- [Middleware auf Anwendungsebene](#middleware.application)
+- [Middleware auf Routerebene](#middleware.router)
+- [Middleware für die Fehlerbehandlung](#middleware.error-handling)
+- [Integrierte Middleware](#middleware.built-in)
+- [Middleware anderer Anbieter](#middleware.third-party)
+
+Sie können Middleware auf Anwendungsebene und Routerebene mit einem optionalen Mountpfad laden.
+Sie können auch eine Reihe von Middlewarefunktionen zusammen laden. Dadurch wird ein Sub-Stack des Middlewaresystems am Mountpunkt erstellt.
+
+Middleware auf Anwendungsebene
+
+Bind application-level middleware to an instance of the [app object](/en/5x/api#app) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the HTTP method of the request that the middleware function handles (such as GET, PUT, or POST) in lowercase.
+
+Dieses Beispiel zeigt eine Middlewarefunktion ohne Mountpfad. Die Funktion wird immer dann ausgeführt, wenn die Anwendung eine Anforderung erhält.
+
+```js
+const express = require('express');
+const app = express();
+
+app.use((req, res, next) => {
+ console.log('Time:', Date.now());
+ next();
+});
+```
+
+Dieses Beispiel zeigt eine Middlewarefunktion mit dem Mountpfad `/user/:id`. Die Funktion wird für jede Art von HTTP-Anforderung auf dem Pfad `/user/:id` ausgeführt.
+
+```js
+app.use('/user/:id', (req, res, next) => {
+ console.log('Request Type:', req.method);
+ next();
+});
+```
+
+Dieses Beispiel zeigt eine Weiterleitung und deren Handlerfunktion (Middlewaresystem). Die Funktion verarbeitet GET-Anforderungen zum Pfad `/user/:id`.
+
+```js
+app.get('/user/:id', (req, res, next) => {
+ res.send('USER');
+});
+```
+
+Dies ist ein Beispiel zum Laden einer Reihe von Middlewarefunktionen an einem Mountpunkt mit einem Mountpfad.
+Das Beispiel veranschaulicht einen Middleware-Stack, über den Anforderungsinformationen zu einer HTTP-Anforderung zum Pfad `/user/:id` ausgegeben werden.
+
+```js
+app.use(
+ '/user/:id',
+ (req, res, next) => {
+ console.log('Request URL:', req.originalUrl);
+ next();
+ },
+ (req, res, next) => {
+ console.log('Request Type:', req.method);
+ next();
+ }
+);
+```
+
+Mit einem Routenhandler können Sie mehrere Weiterleitungen für einen Pfad definieren. Im folgenden Beispiel werden zwei Weiterleitungen für GET-Anforderungen zum Pfad `/user/:id` definiert. Die zweite Weiterleitung verursacht zwar keine Probleme, wird jedoch nie aufgerufen, da durch die erste Weiterleitung der Anforderung/Antwort-Zyklus beendet wird.
+
+Dieses Beispiel zeigt einen Middleware-Sub-Stack, über den GET-Anforderungen zum Pfad `/user/:id` verarbeitet werden.
+
+```js
+app.get(
+ '/user/:id',
+ (req, res, next) => {
+ console.log('ID:', req.params.id);
+ next();
+ },
+ (req, res, next) => {
+ res.send('User Info');
+ }
+);
+
+// handler for the /user/:id path, which prints the user ID
+app.get('/user/:id', (req, res, next) => {
+ res.send(req.params.id);
+});
+```
+
+Wenn Sie den Rest der Middlewarefunktionen eines Weiterleitungs-Middleware-Stack überspringen wollen, rufen Sie `next('route')` auf, um die Steuerung an die nächste Weiterleitung zu übergeben.
+
+{% capture next-function %}
+
+`next('route')` will work only in middleware functions that were loaded by using the `app.METHOD()` or `router.METHOD()` functions.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=next-function %}
+
+Dieses Beispiel zeigt einen Middleware-Sub-Stack, über den GET-Anforderungen zum Pfad `/user/:id` verarbeitet werden.
+
+```js
+app.get(
+ '/user/:id',
+ (req, res, next) => {
+ // if the user ID is 0, skip to the next route
+ if (req.params.id === '0') next('route');
+ // otherwise pass the control to the next middleware function in this stack
+ else next();
+ },
+ (req, res, next) => {
+ // send a regular response
+ res.send('regular');
+ }
+);
+
+// handler for the /user/:id path, which sends a special response
+app.get('/user/:id', (req, res, next) => {
+ res.send('special');
+});
+```
+
+Middleware can also be declared in an array for reusability.
+
+Dies ist ein Beispiel zur Verwendung der Middlewarefunktion `express.static` mit einem ausführlich dargestellten Optionsobjekt:
+
+```js
+function logOriginalUrl(req, res, next) {
+ console.log('Request URL:', req.originalUrl);
+ next();
+}
+
+function logMethod(req, res, next) {
+ console.log('Request Type:', req.method);
+ next();
+}
+
+const logStuff = [logOriginalUrl, logMethod];
+app.get('/user/:id', logStuff, (req, res, next) => {
+ res.send('User Info');
+});
+```
+
+Middleware auf Routerebene
+
+Middleware auf Routerebene funktioniert in der gleichen Weise wie Middleware auf Anwendungsebene, mit dem einzigen Unterschied, dass sie an eine Instanz von `express.Router()` gebunden ist.
+
+```js
+const router = express.Router();
+```
+
+Laden Sie Middleware auf Routerebene über die Funktionen `router.use()` und `router.METHOD()`.
+
+Der folgende Beispielcode repliziert das Middlewaresystem, das oben für die Middleware auf Anwendungsebene gezeigt wird, durch Verwendung von Middleware auf Routerebene.
+
+```js
+const express = require('express');
+const app = express();
+const router = express.Router();
+
+// a middleware function with no mount path. This code is executed for every request to the router
+router.use((req, res, next) => {
+ console.log('Time:', Date.now());
+ next();
+});
+
+// a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path
+router.use(
+ '/user/:id',
+ (req, res, next) => {
+ console.log('Request URL:', req.originalUrl);
+ next();
+ },
+ (req, res, next) => {
+ console.log('Request Type:', req.method);
+ next();
+ }
+);
+
+// a middleware sub-stack that handles GET requests to the /user/:id path
+router.get(
+ '/user/:id',
+ (req, res, next) => {
+ // if the user ID is 0, skip to the next router
+ if (req.params.id === '0') next('route');
+ // otherwise pass control to the next middleware function in this stack
+ else next();
+ },
+ (req, res, next) => {
+ // render a regular page
+ res.render('regular');
+ }
+);
+
+// handler for the /user/:id path, which renders a special page
+router.get('/user/:id', (req, res, next) => {
+ console.log(req.params.id);
+ res.render('special');
+});
+
+// mount the router on the app
+app.use('/', router);
+```
+
+To skip the rest of the router's middleware functions, call `next('router')`
+to pass control back out of the router instance.
+
+Dieses Beispiel zeigt einen Middleware-Sub-Stack, über den GET-Anforderungen zum Pfad `/user/:id` verarbeitet werden.
+
+```js
+const express = require('express');
+const app = express();
+const router = express.Router();
+
+// predicate the router with a check and bail out when needed
+router.use((req, res, next) => {
+ if (!req.headers['x-auth']) return next('router');
+ next();
+});
+
+router.get('/user/:id', (req, res) => {
+ res.send('hello, user!');
+});
+
+// use the router and 401 anything falling through
+app.use('/admin', router, (req, res) => {
+ res.sendStatus(401);
+});
+```
+
+Middleware für die Fehlerbehandlung
+
+
+Middleware für die Fehlerbehandlung benötigt immer *vier* Argumente. Sie müssen vier Argumente angeben, um die Erkennung als Middlewarefunktion für die Fehlerbehandlung zu ermöglichen. Selbst wenn das Objekt `next` nicht verwenden müssen, müssen Sie dies angeben, um die Signatur beizubehalten. Andernfalls wird das Objekt `next` als reguläre Middleware interpretiert, sodass keine Fehlerbehandlung möglich ist.
+
+
+Middlewarefunktionen für die Fehlerbehandlung werden in derselben Weise definiert wie andere Middlewarefunktionen, außer dass Fehlerbehandlungsfunktionen speziell bei Signaturen vier anstatt drei Argumente aufweisen `(err, req, res, next)`:
+
+```js
+app.use((err, req, res, next) => {
+ console.error(err.stack);
+ res.status(500).send('Something broke!');
+});
+```
+
+Details zu Middleware für die Fehlerbehandlung siehe [Fehlerbehandlung](/en/guide/error-handling).
+
+Integrierte Middleware
+
+Seit Version 4.x bestehen bei Express keine Abhängigkeiten zu [Connect](https://github.com/senchalabs/connect) mehr. Mit Ausnahme von `express.static` befinden sich nun alle Middlewarefunktionen, die bisher in Express enthalten waren, in separaten Modulen. Sehen Sie sich hierzu auch die [Liste der Middlewarefunktionen](https://github.com/senchalabs/connect#middleware) an.
+
+Die einzige integrierte Middlewarefunktion in Express ist `express.static`.
+
+- [express.static](/en/5x/api#express.static) serves static assets such as HTML files, images, and so on.
+- [express.json](/en/5x/api#express.json) parses incoming requests with JSON payloads. **NOTE: Available with Express 4.16.0+**
+- [express.urlencoded](/en/5x/api#express.urlencoded) parses incoming requests with URL-encoded payloads. **NOTE: Available with Express 4.16.0+**
+
+Middleware anderer Anbieter
+
+Mit Middleware anderer Anbieter können Sie Express-Anwendungen um neue Funktionalität erweitern.
+
+Installieren Sie das Modul Node.js für die erforderliche Funktionalität. Laden Sie das Modul dann in Ihre Anwendung auf Anwendungsebene oder auf Routerebene.
+
+Das folgende Beispiel veranschaulicht das Installieren und Laden der Middlewarefunktion `cookie-parser` für das Cookie-Parsing.
+
+```bash
+$ npm install cookie-parser
+```
+
+```js
+const express = require('express');
+const app = express();
+const cookieParser = require('cookie-parser');
+
+// load the cookie-parsing middleware
+app.use(cookieParser());
+```
+
+Eine nicht vollständige Liste zu den Middlewarefunktionen anderer Anbieter, die im Allgemeinen mit Express verwendet werden, finden Sie unter [Middleware anderer Anbieter](../resources/middleware).
diff --git a/astro/src/content/docs/de/5x/guide/using-template-engines.md b/astro/src/content/docs/de/5x/guide/using-template-engines.md
new file mode 100644
index 0000000000..0e99b8b839
--- /dev/null
+++ b/astro/src/content/docs/de/5x/guide/using-template-engines.md
@@ -0,0 +1,58 @@
+---
+title: Template-Engines in Express verwenden
+description: Discover how to integrate and use template engines like Pug, Handlebars, and EJS with Express.js to render dynamic HTML pages efficiently.
+---
+
+# Template-Engines in Express verwenden
+
+A _template engine_ enables you to use static template files in your application. At runtime, the template engine replaces
+variables in a template file with actual values, and transforms the template into an HTML file sent to the client.
+This approach makes it easier to design an HTML page.
+
+The [Express application generator](/en/starter/generator) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it also supports [Handlebars](https://www.npmjs.com/package/handlebars), and [EJS](https://www.npmjs.com/package/ejs), among others.
+
+To render template files, set the following [application setting properties](/en/4x/api#app.set), in the default `app.js` created by the generator:
+
+- `views`, das Verzeichnis, in dem sich die Vorlagendateien befinden. Beispiel: `app.set('views', './views')`
+ This defaults to the `views` directory in the application root directory.
+- `view engine`, die zu verwendende Template-Engine. Beispiel: `app.set('view engine', 'pug')`
+
+Installieren Sie dann das entsprechende npm-Paket für die Template-Engine:
+
+```bash
+$ npm install pug --save
+```
+
+Express-konforme Template-Engines wie Pug exportieren eine Funktion namens `__express(filePath, options, callback)`, die über die Funktion `res.render()` aufgerufen wird, um den Vorlagencode ausgeben zu können.
+
+Einige Template-Engines folgen dieser Konvention nicht. Die Bibliothek [Consolidate.js](https://www.npmjs.org/package/consolidate) folgt dieser Konvention, indem alle gängigen Node.js-Template-Engines zugeordnet werden. Daher ist eine reibungslose Funktion in Express gewährleistet.
+
+
+
+Nach der Festlegung der View-Engine muss die Engine nicht angegeben oder das Template-Engine-Modul nicht in Ihre Anwendung geladen werden. Express lädt das Modul intern (wie unten für das obige Beispiel gezeigt).
+
+```js
+app.set('view engine', 'pug');
+```
+
+Erstellen Sie eine Pug-Vorlagendatei namens `index.pug` im Verzeichnis `views` mit dem folgenden Inhalt:
+
+```pug
+html
+ head
+ title= title
+ body
+ h1= message
+```
+
+Dann erstellen Sie eine Weiterleitung, um die Datei `index.pug` auszugeben. Wenn die Eigenschaft `view engine` nicht festgelegt wurde, müssen Sie die Erweiterung der Datei `view` angeben. Andernfalls müssen Sie diese Erweiterung nicht angeben.
+
+```js
+app.get('/', (req, res) => {
+ res.render('index', { title: 'Hey', message: 'Hello there!' });
+});
+```
+
+Wenn Sie eine Anforderung zur Homepage ausführen, wird die Datei `index.pug` im HTML-Format ausgegeben.
+
+The view engine cache does not cache the contents of the template's output, only the underlying template itself. The view is still re-rendered with every request even when the cache is on.
diff --git a/astro/src/content/docs/de/5x/guide/writing-middleware.md b/astro/src/content/docs/de/5x/guide/writing-middleware.md
new file mode 100644
index 0000000000..3bc5fbb2fb
--- /dev/null
+++ b/astro/src/content/docs/de/5x/guide/writing-middleware.md
@@ -0,0 +1,217 @@
+---
+title: Middleware für die Verwendung in Express-Anwendungen schreiben
+description: Learn how to write custom middleware functions for Express.js applications, including examples and best practices for enhancing request and response handling.
+---
+
+# Middleware für die Verwendung in Express-Anwendungen schreiben
+
+Überblick
+
+_Middleware_ functions are functions that have access to the [request object](/en/5x/api#req) (`req`), the [response object](/en/5x/api#res) (`res`), and the `next` function in the application's request-response cycle. Die nächste Middlewarefunktion wird im Allgemeinen durch die Variable `next` bezeichnet.
+
+Über Middlewarefunktionen lassen sich die folgenden Tasks ausführen:
+
+- Ausführen von Code
+- Vornehmen von Änderungen an der Anforderung und an Antwortobjekten
+- End the request-response cycle.
+- Aufrufen der nächsten Middleware im Stack
+
+Wenn über die aktuelle Middlewarefunktion der Anforderung/Antwort-Zyklus nicht beendet werden kann, muss `next()` aufgerufen werden, um die Steuerung an die nächste Middlewarefunktion zu übergeben. Andernfalls geht die Anforderung in den Status "Blockiert" über.
+
+Das folgende Beispiel zeigt die Elemente eines Middlewarefunktionsaufrufs:
+
+
+
+Starting with Express 5, middleware functions that return a Promise will call `next(value)` when they reject or throw an error. `next` will be called with either the rejected value or the thrown Error.
+
+Beispiel
+
+Here is an example of a simple "Hello World" Express application.
+The remainder of this article will define and add three middleware functions to the application:
+one called `myLogger` that prints a simple log message, one called `requestTime` that
+displays the timestamp of the HTTP request, and one called `validateCookies` that validates incoming cookies.
+
+```js
+const express = require('express');
+const app = express();
+
+app.get('/', (req, res) => {
+ res.send('Hello World!');
+});
+
+app.listen(3000);
+```
+
+Dies ist ein Beispiel einer einfachen Express-Anwendung namens "Hello World", für die Sie zwei Middlewarefunktionen definieren:
+Dies ist ein einfaches Beispiel einer Middlewarefunktion namens "myLogger". Diese Funktion gibt lediglich "LOGGED" aus, wenn eine Anforderung zur Anwendung über diese Funktion läuft. Die Middlewarefunktion ist der Variablen `myLogger` zugeordnet.
+
+```js
+const myLogger = function (req, res, next) {
+ console.log('LOGGED');
+ next();
+};
+```
+
+
+Beachten Sie den Aufruf oben zu `next()`. Durch den Aufruf dieser Funktion wird die nächste Middlewarefunktion in der Anwendung aufgerufen.
+Die Funktion `next()` ist nicht Teil der Node.js- oder Express-API, sondern das dritte Argument, das an die Middlewarefunktion übergeben wird. Die Funktion `next()` kann jeden beliebigen Namen haben, per Konvention erhält sie jedoch immer den Namen "next".
+Um Unklarheiten zu vermeiden, sollten Sie immer diese Konvention verwenden.
+
+
+Zum Laden der Middlewarefunktion rufen Sie `app.use()` auf und geben die Middlewarefunktion an.
+Beispiel: Durch den folgenden Code wird die Middlewarefunktion `myLogger` vor der Weiterleitung zum Stammverzeichnispfad (/) geladen.
+
+```js
+const express = require('express');
+const app = express();
+
+const myLogger = function (req, res, next) {
+ console.log('LOGGED');
+ next();
+};
+
+app.use(myLogger);
+
+app.get('/', (req, res) => {
+ res.send('Hello World!');
+});
+
+app.listen(3000);
+```
+
+Sobald die Anwendung eine Anforderung erhält, gibt sie die Nachricht "LOGGED" an das Terminal aus.
+
+Die Reihenfolge beim Laden der Middleware ist wichtig: Middlewarefunktionen, die zuerst geladen werden, werden auch zuerst ausgeführt.
+
+Wenn `myLogger` nach der Weiterleitung zum Stammverzeichnispfad geladen wird, erreicht die Weiterleitung die Middlewarefunktion nicht. Die Anwendung gibt "LOGGED" nicht aus, weil der Routenhandler für den Stammverzeichnispfad den Anforderung/Antwort-Zyklus beendet.
+
+Die Middlewarefunktion `myLogger` gibt einfach eine Nachricht aus und übergibt dann die Anforderung zur nächsten Middlewarefunktion im Stack durch Aufruf der Funktion `next()`.
+
+Middleware function requestTime
+
+Im nächsten Beispiel wird die Eigenschaft `requestTime` zum Anforderungsobjekt hinzugefügt. Diese Middlewarefunktion erhält den Namen "requestTime".
+
+```js
+const requestTime = function (req, res, next) {
+ req.requestTime = Date.now();
+ next();
+};
+```
+
+Die Anwendung verwendet nun die Middlewarefunktion `requestTime`. Außerdem verwendet die Callback-Funktion der Weiterleitung zum Stammverzeichnispfad die Eigenschaft, die die Middlewarefunktion zu `req` (dem Anforderungsobjekt) hinzufügt.
+
+```js
+const express = require('express');
+const app = express();
+
+const requestTime = function (req, res, next) {
+ req.requestTime = Date.now();
+ next();
+};
+
+app.use(requestTime);
+
+app.get('/', (req, res) => {
+ let responseText = 'Hello World! ';
+ responseText += `Requested at: ${req.requestTime} `;
+ res.send(responseText);
+});
+
+app.listen(3000);
+```
+
+Wenn Sie eine Anforderung zum Stammverzeichnis der Anwendung einleiten, zeigt die Anwendung nun die Zeitmarke Ihrer Anforderung im Browser an.
+
+Middleware function validateCookies
+
+Finally, we'll create a middleware function that validates incoming cookies and sends a 400 response if cookies are invalid.
+
+Here's an example function that validates cookies with an external async service.
+
+```js
+async function cookieValidator(cookies) {
+ try {
+ await externallyValidateCookie(cookies.testCookie);
+ } catch {
+ throw new Error('Invalid cookies');
+ }
+}
+```
+
+Here, we use the [`cookie-parser`](/en/resources/middleware/cookie-parser) middleware to parse incoming cookies off the `req` object and pass them to our `cookieValidator` function. The `validateCookies` middleware returns a Promise that upon rejection will automatically trigger our error handler.
+
+```js
+const express = require('express');
+const cookieParser = require('cookie-parser');
+const cookieValidator = require('./cookieValidator');
+
+const app = express();
+
+async function validateCookies(req, res, next) {
+ await cookieValidator(req.cookies);
+ next();
+}
+
+app.use(cookieParser());
+
+app.use(validateCookies);
+
+// error handler
+app.use((err, req, res, next) => {
+ res.status(400).send(err.message);
+});
+
+app.listen(3000);
+```
+
+
+Note how `next()` is called after `await cookieValidator(req.cookies)`. This ensures that if `cookieValidator` resolves, the next middleware in the stack will get called. If you pass anything to the `next()` function (except the string `'route'` or `'router'`), Express regards the current request as being an error and will skip any remaining non-error handling routing and middleware functions.
+
+
+Da Sie Zugriff auf das Anforderungsobjekt, das Antwortobjekt, die nächste Middlewarefunktion im Stack und die gesamte Node.js-API haben, sind die Möglichkeiten, die Sie mit Middlewarefunktionen haben, nahezu unendlich.
+
+Weitere Informationen zur Verwendung von Middleware in Express siehe [ Express-Middleware verwenden](/en/guide/using-middleware).
+
+Configurable middleware
+
+If you need your middleware to be configurable, export a function which accepts an options object or other parameters, which, then returns the middleware implementation based on the input parameters.
+
+File: `my-middleware.js`
+
+```js
+module.exports = function (options) {
+ return function (req, res, next) {
+ // Implement the middleware function based on the options object
+ next();
+ };
+};
+```
+
+The middleware can now be used as shown below.
+
+```js
+const mw = require('./my-middleware.js');
+
+app.use(mw({ option1: '1', option2: '2' }));
+```
+
+Refer to [cookie-session](https://github.com/expressjs/cookie-session) and [compression](https://github.com/expressjs/compression) for examples of configurable middleware.
diff --git a/astro/src/content/docs/de/5x/starter/basic-routing.md b/astro/src/content/docs/de/5x/starter/basic-routing.md
new file mode 100644
index 0000000000..633da3f660
--- /dev/null
+++ b/astro/src/content/docs/de/5x/starter/basic-routing.md
@@ -0,0 +1,63 @@
+---
+title: Basisrouting in Express
+description: Learn the fundamentals of routing in Express.js applications, including how to define routes, handle HTTP methods, and create route handlers for your web server.
+---
+
+# Basisrouting
+
+Per _Routing_ wird bestimmt, wie eine Antwort auf eine Clientanforderung an einem bestimmten Endpunkt antwortet. Dies ist eine URI (oder ein Pfad) und eine bestimmte HTTP-Anforderungsmethode (GET, POST usw.).
+
+Jede Weiterleitung (Route) kann eine oder mehrere Handlerfunktionen haben, die ausgeführt werden, wenn die Weiterleitung abgeglichen wird.
+
+Weiterleitungsdefinitionen haben die folgende Struktur:
+
+```js
+app.METHOD(PATH, HANDLER);
+```
+
+Where:
+
+- `app` ist eine Instanz von `express`.
+- `METHOD` is an [HTTP request method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods), in lowercase.
+- `PATH` ist ein Pfad auf dem Server.
+- `HANDLER` ist die Funktion, die ausgeführt wird, wenn die Weiterleitung abgeglichen wird.
+
+
+In diesem Lernprogramm wird vorausgesetzt, dass eine Instanz von `express` namens `app` erstellt und der Server ausgeführt wird. Wenn Sie mit dem Erstellen und Starten von Anwendungen nicht vertraut sind, spielen Sie das [Beispiel "Hello World"](/en/starter/hello-world) durch.
+
+
+Die folgenden Beispiele veranschaulichen das Definieren einfacher Weiterleitungen.
+
+Antworten Sie mit `Hello World!` auf der Homepage:
+
+```js
+app.get('/', (req, res) => {
+ res.send('Hello World!');
+});
+```
+
+Respond to a POST request on the root route (`/`), the application's home page:
+
+```js
+app.post('/', (req, res) => {
+ res.send('Got a POST request');
+});
+```
+
+Antworten Sie auf eine PUT-Anforderung zur Weiterleitung `/user`:
+
+```js
+app.put('/user', (req, res) => {
+ res.send('Got a PUT request at /user');
+});
+```
+
+Antworten Sie auf eine DELETE-Anforderung zur Weiterleitung `/user`:
+
+```js
+app.delete('/user', (req, res) => {
+ res.send('Got a DELETE request at /user');
+});
+```
+
+Details zum Thema Routing finden Sie in der entsprechenden [Routinganleitung](/en/guide/routing).
diff --git a/astro/src/content/docs/de/5x/starter/examples.md b/astro/src/content/docs/de/5x/starter/examples.md
new file mode 100644
index 0000000000..a25a6d9834
--- /dev/null
+++ b/astro/src/content/docs/de/5x/starter/examples.md
@@ -0,0 +1,16 @@
+---
+title: Express examples
+description: Explore a collection of Express.js application examples covering various use cases, integrations, and advanced configurations to help you learn and build your projects.
+---
+
+{% capture examples %}{% include readmes/express-master/examples.md %}{% endcapture %}
+{{ examples | replace: "](.", "](https://github.com/expressjs/express/tree/master/examples" }}
+
+## Additional examples
+
+These are some additional examples with more extensive integrations.
+
+{% include community-caveat.html %}
+
+- [prisma-fullstack](https://github.com/prisma/prisma-examples/tree/latest/pulse/fullstack-simple-chat) - Fullstack app with Express and Next.js using [Prisma](https://www.npmjs.com/package/prisma) as an ORM
+- [prisma-rest-api-ts](https://github.com/prisma/prisma-examples/tree/latest/orm/express) - REST API with Express in TypeScript using [Prisma](https://www.npmjs.com/package/prisma) as an ORM
diff --git a/astro/src/content/docs/de/5x/starter/faq.md b/astro/src/content/docs/de/5x/starter/faq.md
new file mode 100644
index 0000000000..1ab5b58628
--- /dev/null
+++ b/astro/src/content/docs/de/5x/starter/faq.md
@@ -0,0 +1,75 @@
+---
+title: Häufig gestellte Fragen zu Express
+description: Finden Sie Antworten auf häufig gestellte Fragen zu Express.js, darunter Themen wie Anwendungsstruktur, Models, Authentifizierung, Template-Engines, Fehlerbehandlung und mehr.
+---
+
+# Häufig gestellte Fragen
+
+## Wie muss ich meine Anwendung strukturieren?
+
+Auf diese Frage gibt es keine verbindliche Antwort. Die Antwort hängt vom Umfang Ihrer Anwendung und dem eingebundenen Team ab. Um so flexibel wie möglich zu sein, gibt es bei Express keine Voraussetzungen hinsichtlich der Struktur.
+
+Weiterleitungen und andere anwendungsspezifische Logik können in einer beliebigen Anzahl von Dateien und in jeder von Ihnen bevorzugten Verzeichnisstruktur vorkommen. Die folgenden Beispiele sollen als Entscheidungshilfe dienen:
+
+- [Weiterleitungslisten](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-47)
+- [Weiterleitungszuordnung](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66)
+- [Controller im MVC-Stil](https://github.com/expressjs/express/tree/master/examples/mvc)
+
+Darüber hinaus gibt es Erweiterungen anderer Anbieter für Express, die zur Vereinfachung einiger dieser Muster beitragen:
+
+- [Weiterleitung mit "express-resource"](https://github.com/expressjs/express-resource)
+
+## Wie definiere ich Modelle?
+
+Express hat keine Vorstellungen von einer Datenbank. Dieses Konzept bleibt Node-Modulen anderer Anbieter überlassen, wodurch Schnittstellen zu allen Datenbank möglich sind.
+
+[LoopBack](http://loopback.io) zeigt ein Express-basiertes Framework, um das Modelle angeordnet sind.
+
+## Wie kann ich Benutzer authentifizieren?
+
+Die Authentifizierung ist ein weiterer meinungsstarker Bereich, in den Express nicht eingreift. Sie können ein Authentifizierungsschema nach Ihren Vorstellungen verwenden.
+Ein einfaches Benutzername/Kennwort-Schema können Sie in [diesem Beispiel](https://github.com/expressjs/express/tree/master/examples/auth) sehen.
+
+## Welche Template-Engines unterstützt Express?
+
+Express unterstützt jede Template-Engine, die der `(path, locals, callback)`-Signatur entspricht.
+Informationen zur Normalisierung von Template-Engine-Schnittstellen und -Caching siehe das Projekt [consolidate.js](https://github.com/visionmedia/consolidate.js). Nicht aufgelistete Template-Engines können trotzdem die Express-Signatur unterstützen.
+
+For more information, see [Using template engines with Express](/en/guide/using-template-engines).
+
+## Wie handhabe ich 404-Antworten?
+
+In Express sind 404-Antworten nicht das Ergebnis eines Fehlers, sodass diese Antworten von der Fehlerbehandlungsroutine nicht erfasst werden. Dieses Verhalten ist damit zu erklären, dass eine 404-Antwort einfach angibt, dass keine weiteren Arbeiten auszuführen sind. In anderen Worten: Express hat alle Middlewarefunktionen und Weiterleitungen ausgeführt und festgestellt, dass keine Funktion eine Antwort zurückgegeben hat. Sie müssen also bei der Handhabung der 404-Antwort nur eine Middlewarefunktion am Ende des Stacks (unterhalb von allen anderen Funktionen) hinzufügen:
+
+```js
+app.use((req, res, next) => {
+ res.status(404).send("Sorry can't find that!");
+});
+```
+
+Add routes dynamically at runtime on an instance of `express.Router()`
+so the routes are not superseded by a middleware function.
+
+## Wie richte ich eine Fehlerbehandlungsroutine ein?
+
+Middleware für die Fehlerbehandlung wird in derselben Weise definiert wie andere Middleware; außer dass sie vier anstatt drei Argumente aufweist. Dies gilt speziell bei der Signatur `(err, req, res, next)`:
+
+```js
+app.use((err, req, res, next) => {
+ console.error(err.stack);
+ res.status(500).send('Something broke!');
+});
+```
+
+Weitere Informationen siehe [Fehlerbehandlung](/en/guide/error-handling).
+
+## Wie gebe ich normales HTML-Format aus?
+
+Das ist nicht Ihre Aufgabe! Sie müssen kein HTML-Format mit der Funktion `res.render()` ausgeben.
+Verwenden Sie die Funktion `res.sendFile()`, wenn Sie es mit einer bestimmten Datei zu tun haben.
+Wenn Sie viele Assets aus einem Verzeichnis bedienen müssen, verwenden Sie die Middlewarefunktion `express.static()`.
+
+## Welche Version von Node.js benötigt Express?
+
+- [Express 4.x](/en/4x/api) requires Node.js 0.10 or higher.
+- [Express 5.x](/en/5x/api) requires Node.js 18 or higher.
diff --git a/astro/src/content/docs/de/5x/starter/generator.md b/astro/src/content/docs/de/5x/starter/generator.md
new file mode 100644
index 0000000000..cf23c63154
--- /dev/null
+++ b/astro/src/content/docs/de/5x/starter/generator.md
@@ -0,0 +1,122 @@
+---
+title: Express-Anwendungsgenerator
+description: Learn how to use the Express application generator tool to quickly create a skeleton for your Express.js applications, streamlining setup and configuration.
+---
+
+# Express-Anwendungsgenerator
+
+Mit dem Application Generator Tool `express` können Sie innerhalb kürzester Zeit ein Anwendungsgerüst erstellen.
+
+You can run the application generator with the `npx` command (available in Node.js 8.2.0).
+
+```bash
+$ npx express-generator
+```
+
+For earlier Node versions, install the application generator as a global npm package and then launch it:
+
+```bash
+$ npm install -g express-generator
+$ express
+```
+
+Zeigen Sie die Befehlsoptionen mit der Option `-h` an:
+
+```bash
+$ express -h
+
+ Usage: express [options] [dir]
+
+ Options:
+
+ -h, --help output usage information
+ --version output the version number
+ -e, --ejs add ejs engine support
+ --hbs add handlebars engine support
+ --pug add pug engine support
+ -H, --hogan add hogan.js engine support
+ --no-view generate without view engine
+ -v, --view add view support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
+ -c, --css add stylesheet support (less|stylus|compass|sass) (defaults to plain css)
+ --git add .gitignore
+ -f, --force force on non-empty directory
+```
+
+Im folgenden Beispiel wird eine Express-Anwendung mit dem Namen _myapp_ im aktuellen Arbeitsverzeichnis erstellt: The app will be created in a folder named _myapp_ in the current working directory and the view engine will be set to Pug :
+
+```bash
+$ express --view=pug myapp
+
+ create : myapp
+ create : myapp/package.json
+ create : myapp/app.js
+ create : myapp/public
+ create : myapp/public/javascripts
+ create : myapp/public/images
+ create : myapp/routes
+ create : myapp/routes/index.js
+ create : myapp/routes/users.js
+ create : myapp/public/stylesheets
+ create : myapp/public/stylesheets/style.css
+ create : myapp/views
+ create : myapp/views/index.pug
+ create : myapp/views/layout.pug
+ create : myapp/views/error.pug
+ create : myapp/bin
+ create : myapp/bin/www
+```
+
+Installieren Sie dann Abhängigkeiten:
+
+```bash
+$ cd myapp
+$ npm install
+```
+
+Verwenden Sie unter Windows diesen Befehl:
+
+```bash
+$ DEBUG=myapp:* npm start
+```
+
+Führen Sie unter MacOS oder Linux die Anwendung mit diesem Befehl aus:
+
+```bash
+> set DEBUG=myapp:* & npm start
+```
+
+On Windows PowerShell, use this command:
+
+```bash
+PS> $env:DEBUG='myapp:*'; npm start
+```
+
+Laden Sie dann `http://localhost:3000/` in Ihren Browser, um auf die Anwendung zuzugreifen.
+
+Die erstellte Anwendung hat die folgende Verzeichnisstruktur:
+
+```bash
+.
+├── app.js
+├── bin
+│ └── www
+├── package.json
+├── public
+│ ├── images
+│ ├── javascripts
+│ └── stylesheets
+│ └── style.css
+├── routes
+│ ├── index.js
+│ └── users.js
+└── views
+ ├── error.pug
+ ├── index.pug
+ └── layout.pug
+
+7 directories, 9 files
+```
+
+
+Die vom Generator erstellte Anwendungsstruktur ist nur eine der vielen Möglichkeiten, Express-Anwendungen zu strukturieren. Sie können diese Struktur verwenden oder sie an Ihre Anforderungen anpassen.
+
diff --git a/astro/src/content/docs/de/5x/starter/hello-world.md b/astro/src/content/docs/de/5x/starter/hello-world.md
new file mode 100644
index 0000000000..d6e9f141a6
--- /dev/null
+++ b/astro/src/content/docs/de/5x/starter/hello-world.md
@@ -0,0 +1,42 @@
+---
+title: Beispiel "Hello World" in Express
+description: Get started with Express.js by building a simple 'Hello World' application, demonstrating the basic setup and server creation for beginners.
+---
+
+# Beispiel "Hello World"
+
+
+Dies ist wohl die einfachste Express-Anwendung, die Sie erstellen können. Es handelt sich um eine Anwendung mit nur einer Datei und — *nicht* das, was Sie mit dem [Express Generator](/en/starter/generator) erhalten würden. Mit dem Generator würde das Gerüst für eine vollständige Anwendung mit zahlreichen JavaScript-Dateien, Jade-Vorlagen und Unterverzeichnissen für verschiedene Zwecke erstellt werden.
+
+
+```js
+const express = require('express');
+const app = express();
+const port = 3000;
+
+app.get('/', (req, res) => {
+ res.send('Hello World!');
+});
+
+app.listen(port, () => {
+ console.log(`Example app listening on port ${port}`);
+});
+```
+
+Die Anwendung startet einen Server und ist an Port 3000 empfangsbereit für Verbindungen. Die Anwendung antwortet mit "Hello World!" auf Anforderungen zur Stamm-URL (`/`) oder zu _route_. Bei jedem anderen Pfad lautet die Antwort **404 Not Found**.
+
+### Running Locally
+
+Erstellen Sie zunächst ein Verzeichnis namens `myapp`, wechseln Sie in das Verzeichnis und führen Sie `npm init` aus. Installieren Sie dann `express` als Abhängigkeit, wie im [Installationshandbuch](/en/starter/installing) beschrieben.
+
+Erstellen Sie im Verzeichnis `myapp` eine Datei namens `app.js` und fügen Sie den folgenden Code hinzu:
+
+`req` (Anforderung) und `res` (Antwort) sind genau dieselben Objekte, die Node bereitstellt. Sie können also `req.pipe()`, `req.on('data', callback)` und alle anderen Tasks, die Sie ausführen wollen, ohne Express ausführen.
+
+Führen Sie die Anwendung mit dem folgenden Befehl aus:
+
+```bash
+$ node app.js
+```
+
+Laden Sie dann [http://localhost:3000/](http://localhost:3000/) in einen Browser, um die Ausgabe zu sehen.
diff --git a/astro/src/content/docs/de/5x/starter/installing.md b/astro/src/content/docs/de/5x/starter/installing.md
new file mode 100644
index 0000000000..371e979f5f
--- /dev/null
+++ b/astro/src/content/docs/de/5x/starter/installing.md
@@ -0,0 +1,48 @@
+---
+title: Express installieren
+description: Erfahren Sie, wie Sie Express.js in Ihrer Node.js-Umgebung installieren, wie Sie Ihr Projektverzeichnis aufsetzen und Abhängigkeiten mit npm verwalten.
+---
+
+# Installation
+
+Angenommen, Sie haben [Node.js](https://nodejs.org/) bereits installiert. Erstellen Sie ein Verzeichnis für Ihre Anwendung und definieren Sie dieses Verzeichnis als Ihr Arbeitsverzeichnis.
+
+- [Express 4.x](/en/4x/api) requires Node.js 0.10 or higher.
+- [Express 5.x](/en/5x/api) requires Node.js 18 or higher.
+
+```bash
+$ mkdir myapp
+$ cd myapp
+```
+
+Erstellen Sie mit dem Befehl `npm init` eine Datei namens `package.json` für Ihre Anwendung.
+Weitere Informationen zur Funktionsweise von `package.json` finden Sie in den [Angaben zur Handhabung der npm-Datei package.json](https://docs.npmjs.com/files/package.json).
+
+```bash
+$ npm init
+```
+
+Dieser Befehl fordert Sie zur Eingabe verschiedener Angaben wie Name und Version Ihrer Anwendung auf.
+For now, you can simply hit RETURN to accept the defaults for most of them, with the following exception:
+
+```
+entry point: (index.js)
+```
+
+Geben Sie `app.js` oder einen Namen Ihrer Vorstellung als Namen für die Hauptdatei ein. Wenn dieser Name `index.js` lauten soll, drücken Sie die Eingabetaste, um den vorgeschlagenen Standarddateinamen zu akzeptieren.
+
+Installieren Sie jetzt Express im Verzeichnis `myapp` und speichern Sie es in der Abhängigkeitsliste. Beispiel:
+
+```bash
+$ npm install express
+```
+
+Wenn Sie Express vorübergehend installieren und nicht zur Abhängigkeitsliste hinzufügen wollen, geben Sie die Option `--save` nicht an:
+
+```bash
+$ npm install express --no-save
+```
+
+
+Node-Module, die mit der Option `--save` installiert werden, werden zur `Abhängigkeitsliste` in der Datei `package.json` hinzugefügt. Danach werden bei der Ausführung von `npm install` im Verzeichnis `app` automatisch alle Module in der Abhängigkeitsliste installiert.
+
diff --git a/astro/src/content/docs/de/5x/starter/static-files.md b/astro/src/content/docs/de/5x/starter/static-files.md
new file mode 100644
index 0000000000..fb36f85ca5
--- /dev/null
+++ b/astro/src/content/docs/de/5x/starter/static-files.md
@@ -0,0 +1,74 @@
+---
+title: Statische Dateien in Express bereitstellen
+description: Understand how to serve static files like images, CSS, and JavaScript in Express.js applications using the built-in 'static' middleware.
+---
+
+# Statische Dateien in Express bereitstellen
+
+Wenn Sie statische Dateien wie Bilder, CSS-Dateien und JavaScript-Dateien bereitstellen wollen, verwenden Sie die in Express integrierte Middlewarefunktion `express.static`.
+
+The function signature is:
+
+```js
+express.static(root, [options]);
+```
+
+The `root` argument specifies the root directory from which to serve static assets.
+For more information on the `options` argument, see [express.static](/en/5x/api#express.static).
+
+Beispiel: Verwenden Sie den folgenden Code, um Bilder, CSS-Dateien und JavaScript-Dateien in einem Verzeichnis namens `public` bereitzustellen:
+
+```js
+app.use(express.static('public'));
+```
+
+Jetzt können Sie die Dateien laden, die sich im Verzeichnis `public` befinden:
+
+```text
+http://localhost:3000/images/kitten.jpg
+http://localhost:3000/css/style.css
+http://localhost:3000/js/app.js
+http://localhost:3000/images/bg.png
+http://localhost:3000/hello.html
+```
+
+Express sucht nach den Dateien, die sich auf das Verzeichnis mit den statischen Assets beziehen. Der Name dieses Verzeichnisses ist also nicht Teil der URL.
+
+Wenn Sie mehrere Verzeichnisse mit statischen Assets verwenden wollen, rufen Sie die Middlewarefunktion `express.static` mehrmals auf:
+
+```js
+app.use(express.static('public'));
+app.use(express.static('files'));
+```
+
+Express sucht in der Reihenfolge nach den Dateien, in der sie die Verzeichnisse mit den statischen Assets über die Middlewarefunktion `express.static` festgelegt haben.
+
+{% capture alert_content %}
+For best results, [use a reverse proxy](/en/advanced/best-practice-performance#use-a-reverse-proxy) cache to improve performance of serving static assets.
+{% endcapture %}
+{% include admonitions/note.html content=alert_content %}
+
+To create a virtual path prefix (where the path does not actually exist in the file system) for files that are served by the `express.static` function, [specify a mount path](/en/5x/api#app.use) for the static directory, as shown below:
+
+```js
+app.use('/static', express.static('public'));
+```
+
+Jetzt können Sie die Dateien, die sich im Verzeichnis `public` befinden, aus dem Pfadpräfix `/static` laden.
+
+```text
+http://localhost:3000/static/images/kitten.jpg
+http://localhost:3000/static/css/style.css
+http://localhost:3000/static/js/app.js
+http://localhost:3000/static/images/bg.png
+http://localhost:3000/static/hello.html
+```
+
+Der Pfad, den Sie für die Funktion `express.static` angeben, ist jedoch relativ zum Verzeichnis, aus dem Sie Ihren Prozess `node` starten. Wenn Sie die Express-Anwendung aus einem anderen Verzeichnis ausführen, ist es sicherer, den absoluten Pfad des Verzeichnisses zu verwenden, das Sie bereitstellen wollen:
+
+```js
+const path = require('path');
+app.use('/static', express.static(path.join(__dirname, 'public')));
+```
+
+For more details about the `serve-static` function and its options, see [serve-static](/en/resources/middleware/serve-static).
diff --git a/astro/src/content/docs/en/3x/api.md b/astro/src/content/docs/en/3x/api.md
new file mode 100644
index 0000000000..53c2135058
--- /dev/null
+++ b/astro/src/content/docs/en/3x/api.md
@@ -0,0 +1,25 @@
+---
+title: Express 3.x - Referencia de API
+description: Access the API reference for Express.js version 3.x, noting that this version is end-of-life and no longer maintained - includes details on modules and methods.
+---
+
+
+
+
+ **Express 3.x IS END-OF-LIFE AND NO LONGER MAINTAINED**
+
+Known and unknown security and performance issues in 3.x have not been addressed since the last update (1 August, 2015). It is highly recommended to use the latest version of Express.
+
+If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/en/support#commercial-support-options).
+
+
+
+
3.x API
+
+{% include api/en/3x/express.md %}
+{% include api/en/3x/app.md %}
+{% include api/en/3x/req.md %}
+{% include api/en/3x/res.md %}
+{% include api/en/3x/middleware.md %}
+
+
diff --git a/astro/src/content/docs/en/4x/advanced/best-practice-performance.md b/astro/src/content/docs/en/4x/advanced/best-practice-performance.md
new file mode 100644
index 0000000000..74ee1b634e
--- /dev/null
+++ b/astro/src/content/docs/en/4x/advanced/best-practice-performance.md
@@ -0,0 +1,307 @@
+---
+title: Performance Best Practices Using Express in Production
+description: Discover performance and reliability best practices for Express apps in production, covering code optimizations and environment setups for optimal performance.
+---
+
+# Production best practices: performance and reliability
+
+This article discusses performance and reliability best practices for Express applications deployed to production.
+
+This topic clearly falls into the "devops" world, spanning both traditional development and operations. Accordingly, the information is divided into two parts:
+
+- Things to do in your code (the dev part):
+ - [Use gzip compression](#use-gzip-compression)
+ - [Don't use synchronous functions](#dont-use-synchronous-functions)
+ - [Do logging correctly](#do-logging-correctly)
+ - [Handle exceptions properly](#handle-exceptions-properly)
+- Things to do in your environment / setup (the ops part):
+ - [Set NODE_ENV to "production"](#set-node_env-to-production)
+ - [Ensure your app automatically restarts](#ensure-your-app-automatically-restarts)
+ - [Run your app in a cluster](#run-your-app-in-a-cluster)
+ - [Cache request results](#cache-request-results)
+ - [Use a load balancer](#use-a-load-balancer)
+ - [Use a reverse proxy](#use-a-reverse-proxy)
+
+## Things to do in your code {#in-code}
+
+Here are some things you can do in your code to improve your application's performance:
+
+- [Use gzip compression](#use-gzip-compression)
+- [Don't use synchronous functions](#dont-use-synchronous-functions)
+- [Do logging correctly](#do-logging-correctly)
+- [Handle exceptions properly](#handle-exceptions-properly)
+
+### Use gzip compression
+
+Gzip compressing can greatly decrease the size of the response body and hence increase the speed of a web app. Use the [compression](https://www.npmjs.com/package/compression) middleware for gzip compression in your Express app. For example:
+
+```js
+const compression = require('compression');
+const express = require('express');
+const app = express();
+
+app.use(compression());
+```
+
+For a high-traffic website in production, the best way to put compression in place is to implement it at a reverse proxy level (see [Use a reverse proxy](#use-a-reverse-proxy)). In that case, you do not need to use compression middleware. For details on enabling gzip compression in Nginx, see [Module ngx_http_gzip_module](http://nginx.org/en/docs/http/ngx_http_gzip_module) in the Nginx documentation.
+
+### Don't use synchronous functions
+
+Synchronous functions and methods tie up the executing process until they return. A single call to a synchronous function might return in a few microseconds or milliseconds, however in high-traffic websites, these calls add up and reduce the performance of the app. Avoid their use in production.
+
+Although Node and many modules provide synchronous and asynchronous versions of their functions, always use the asynchronous version in production. The only time when a synchronous function can be justified is upon initial startup.
+
+You can use the `--trace-sync-io` command-line flag to print a warning and a stack trace whenever your application uses a synchronous API. Of course, you wouldn't want to use this in production, but rather to ensure that your code is ready for production. See the [node command-line options documentation](https://nodejs.org/api/cli#cli_trace_sync_io) for more information.
+
+### Do logging correctly
+
+In general, there are two reasons for logging from your app: For debugging and for logging app activity (essentially, everything else). Using `console.log()` or `console.error()` to print log messages to the terminal is common practice in development. But [these functions are synchronous](https://nodejs.org/api/console#console) when the destination is a terminal or a file, so they are not suitable for production, unless you pipe the output to another program.
+
+#### For debugging
+
+If you're logging for purposes of debugging, then instead of using `console.log()`, use a special debugging module like [debug](https://www.npmjs.com/package/debug). This module enables you to use the DEBUG environment variable to control what debug messages are sent to `console.error()`, if any. To keep your app purely asynchronous, you'd still want to pipe `console.error()` to another program. But then, you're not really going to debug in production, are you?
+
+#### For app activity
+
+If you're logging app activity (for example, tracking traffic or API calls), instead of using `console.log()`, use a logging library like [Pino](https://www.npmjs.com/package/pino), which is the fastest and most efficient option available.
+
+### Handle exceptions properly
+
+Node apps crash when they encounter an uncaught exception. Not handling exceptions and taking appropriate actions will make your Express app crash and go offline. If you follow the advice in [Ensure your app automatically restarts](#ensure-your-app-automatically-restarts) below, then your app will recover from a crash. Fortunately, Express apps typically have a short startup time. Nevertheless, you want to avoid crashing in the first place, and to do that, you need to handle exceptions properly.
+
+To ensure you handle all exceptions, use the following techniques:
+
+- [Use try-catch](#use-try-catch)
+- [Use promises](#use-promises)
+
+Before diving into these topics, you should have a basic understanding of Node/Express error handling: using error-first callbacks, and propagating errors in middleware. Node uses an "error-first callback" convention for returning errors from asynchronous functions, where the first parameter to the callback function is the error object, followed by result data in succeeding parameters. To indicate no error, pass null as the first parameter. The callback function must correspondingly follow the error-first callback convention to meaningfully handle the error. And in Express, the best practice is to use the next() function to propagate errors through the middleware chain.
+
+For more on the fundamentals of error handling, see:
+
+- [Error Handling in Node.js](https://www.tritondatacenter.com/node-js/production/design/errors)
+
+#### Use try-catch
+
+Try-catch is a JavaScript language construct that you can use to catch exceptions in synchronous code. Use try-catch, for example, to handle JSON parsing errors as shown below.
+
+Here is an example of using try-catch to handle a potential process-crashing exception.
+This middleware function accepts a query field parameter named "params" that is a JSON object.
+
+```js
+app.get('/search', (req, res) => {
+ // Simulating async operation
+ setImmediate(() => {
+ const jsonStr = req.query.params;
+ try {
+ const jsonObj = JSON.parse(jsonStr);
+ res.send('Success');
+ } catch (e) {
+ res.status(400).send('Invalid JSON string');
+ }
+ });
+});
+```
+
+However, try-catch works only for synchronous code. Because the Node platform is primarily asynchronous (particularly in a production environment), try-catch won't catch a lot of exceptions.
+
+#### Use promises
+
+When an error is thrown in an `async` function or a rejected promise is awaited inside an `async` function, those errors will be passed to the error handler as if calling `next(err)`
+
+```js
+app.get('/', async (req, res, next) => {
+ const data = await userData(); // If this promise fails, it will automatically call `next(err)` to handle the error.
+
+ res.send(data);
+});
+
+app.use((err, req, res, next) => {
+ res.status(err.status ?? 500).send({ error: err.message });
+});
+```
+
+Also, you can use asynchronous functions for your middleware, and the router will handle errors if the promise fails, for example:
+
+```js
+app.use(async (req, res, next) => {
+ req.locals.user = await getUser(req);
+
+ next(); // This will be called if the promise does not throw an error.
+});
+```
+
+Best practice is to handle errors as close to the site as possible. So while this is now handled in the router, it’s best to catch the error in the middleware and handle it without relying on separate error-handling middleware.
+
+#### What not to do
+
+One thing you should _not_ do is to listen for the `uncaughtException` event, emitted when an exception bubbles all the way back to the event loop. Adding an event listener for `uncaughtException` will change the default behavior of the process that is encountering an exception; the process will continue to run despite the exception. This might sound like a good way of preventing your app from crashing, but continuing to run the app after an uncaught exception is a dangerous practice and is not recommended, because the state of the process becomes unreliable and unpredictable.
+
+Additionally, using `uncaughtException` is officially recognized as [crude](https://nodejs.org/api/process#process_event_uncaughtexception). So listening for `uncaughtException` is just a bad idea. This is why we recommend things like multiple processes and supervisors: crashing and restarting is often the most reliable way to recover from an error.
+
+We also don't recommend using [domains](https://nodejs.org/api/domain). It generally doesn't solve the problem and is a deprecated module.
+
+## Things to do in your environment / setup {#in-environment}
+
+Here are some things you can do in your system environment to improve your app's performance:
+
+- [Set NODE_ENV to "production"](#set-node_env-to-production)
+- [Ensure your app automatically restarts](#ensure-your-app-automatically-restarts)
+- [Run your app in a cluster](#run-your-app-in-a-cluster)
+- [Cache request results](#cache-request-results)
+- [Use a load balancer](#use-a-load-balancer)
+- [Use a reverse proxy](#use-a-reverse-proxy)
+
+### Set NODE_ENV to "production"
+
+The NODE_ENV environment variable specifies the environment in which an application is running (usually, development or production). One of the simplest things you can do to improve performance is to set NODE_ENV to `production`.
+
+Setting NODE_ENV to "production" makes Express:
+
+- Cache view templates.
+- Cache CSS files generated from CSS extensions.
+- Generate less verbose error messages.
+
+[Tests indicate](https://www.dynatrace.com/news/blog/the-drastic-effects-of-omitting-node-env-in-your-express-js-applications/) that just doing this can improve app performance by a factor of three!
+
+If you need to write environment-specific code, you can check the value of NODE_ENV with `process.env.NODE_ENV`. Be aware that checking the value of any environment variable incurs a performance penalty, and so should be done sparingly.
+
+In development, you typically set environment variables in your interactive shell, for example by using `export` or your `.bash_profile` file. But in general, you shouldn't do that on a production server; instead, use your OS's init system (systemd). The next section provides more details about using your init system in general, but setting `NODE_ENV` is so important for performance (and easy to do), that it's highlighted here.
+
+With systemd, use the `Environment` directive in your unit file. For example:
+
+```sh
+# /etc/systemd/system/myservice.service
+Environment=NODE_ENV=production
+```
+
+For more information, see [Using Environment Variables In systemd Units](https://www.flatcar.org/docs/latest/setup/systemd/environment-variables/).
+
+### Ensure your app automatically restarts
+
+In production, you don't want your application to be offline, ever. This means you need to make sure it restarts both if the app crashes and if the server itself crashes. Although you hope that neither of those events occurs, realistically you must account for both eventualities by:
+
+- Using a process manager to restart the app (and Node) when it crashes.
+- Using the init system provided by your OS to restart the process manager when the OS crashes. It's also possible to use the init system without a process manager.
+
+Node applications crash if they encounter an uncaught exception. The foremost thing you need to do is to ensure your app is well-tested and handles all exceptions (see [handle exceptions properly](#handle-exceptions-properly) for details). But as a fail-safe, put a mechanism in place to ensure that if and when your app crashes, it will automatically restart.
+
+#### Use a process manager
+
+In development, you started your app simply from the command line with `node server.js` or something similar. But doing this in production is a recipe for disaster. If the app crashes, it will be offline until you restart it. To ensure your app restarts if it crashes, use a process manager. A process manager is a "container" for applications that facilitates deployment, provides high availability, and enables you to manage the application at runtime.
+
+In addition to restarting your app when it crashes, a process manager can enable you to:
+
+- Gain insights into runtime performance and resource consumption.
+- Modify settings dynamically to improve performance.
+- Control clustering (pm2).
+
+Historically, it was popular to use a Node.js process manager like [PM2](https://github.com/Unitech/pm2). See their documentation if you wish to do this. However, we recommend using your init system for process management.
+
+#### Use an init system
+
+The next layer of reliability is to ensure that your app restarts when the server restarts. Systems can still go down for a variety of reasons. To ensure that your app restarts if the server crashes, use the init system built into your OS. The main init system in use today is [systemd](https://wiki.debian.org/systemd).
+
+There are two ways to use init systems with your Express app:
+
+- Run your app in a process manager, and install the process manager as a service with the init system. The process manager will restart your app when the app crashes, and the init system will restart the process manager when the OS restarts. This is the recommended approach.
+- Run your app (and Node) directly with the init system. This is somewhat simpler, but you don't get the additional advantages of using a process manager.
+
+##### Systemd
+
+Systemd is a Linux system and service manager. Most major Linux distributions have adopted systemd as their default init system.
+
+A systemd service configuration file is called a _unit file_, with a filename ending in `.service`. Here's an example unit file to manage a Node app directly. Replace the values enclosed in `` for your system and app:
+
+```sh
+[Unit]
+Description=
+
+[Service]
+Type=simple
+ExecStart=/usr/local/bin/node
+WorkingDirectory=
+
+User=nobody
+Group=nogroup
+
+# Environment variables:
+Environment=NODE_ENV=production
+
+# Allow many incoming connections
+LimitNOFILE=infinity
+
+# Allow core dumps for debugging
+LimitCORE=infinity
+
+StandardInput=null
+StandardOutput=syslog
+StandardError=syslog
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
+```
+
+For more information on systemd, see the [systemd reference (man page)](http://www.freedesktop.org/software/systemd/man/systemd.unit).
+
+### Run your app in a cluster
+
+In a multi-core system, you can increase the performance of a Node app by many times by launching a cluster of processes. A cluster runs multiple instances of the app, ideally one instance on each CPU core, thereby distributing the load and tasks among the instances.
+
+
+
+IMPORTANT: Since the app instances run as separate processes, they do not share the same memory space. That is, objects are local to each instance of the app. Therefore, you cannot maintain state in the application code. However, you can use an in-memory datastore like [Redis](http://redis.io/) to store session-related data and state. This caveat applies to essentially all forms of horizontal scaling, whether clustering with multiple processes or multiple physical servers.
+
+In clustered apps, worker processes can crash individually without affecting the rest of the processes. Apart from performance advantages, failure isolation is another reason to run a cluster of app processes. Whenever a worker process crashes, always make sure to log the event and spawn a new process using cluster.fork().
+
+#### Using Node's cluster module
+
+Clustering is made possible with Node's [cluster module](https://nodejs.org/api/cluster). This enables a master process to spawn worker processes and distribute incoming connections among the workers.
+
+#### Using PM2
+
+If you deploy your application with PM2, then you can take advantage of clustering _without_ modifying your application code. You should ensure your [application is stateless](https://pm2.keymetrics.io/docs/usage/specifics/#stateless-apps) first, meaning no local data is stored in the process (such as sessions, websocket connections and the like).
+
+When running an application with PM2, you can enable **cluster mode** to run it in a cluster with a number of instances of your choosing, such as the matching the number of available CPUs on the machine. You can manually change the number of processes in the cluster using the `pm2` command line tool without stopping the app.
+
+To enable cluster mode, start your application like so:
+
+```bash
+# Start 4 worker processes
+$ pm2 start npm --name my-app -i 4 -- start
+# Auto-detect number of available CPUs and start that many worker processes
+$ pm2 start npm --name my-app -i max -- start
+```
+
+This can also be configured within a PM2 process file (`ecosystem.config.js` or similar) by setting `exec_mode` to `cluster` and `instances` to the number of workers to start.
+
+Once running, the application can be scaled like so:
+
+```bash
+# Add 3 more workers
+$ pm2 scale my-app +3
+# Scale to a specific number of workers
+$ pm2 scale my-app 2
+```
+
+For more information on clustering with PM2, see [Cluster Mode](https://pm2.keymetrics.io/docs/usage/cluster-mode/) in the PM2 documentation.
+
+### Cache request results
+
+Another strategy to improve the performance in production is to cache the result of requests, so that your app does not repeat the operation to serve the same request repeatedly.
+
+Use a caching server like [Varnish](https://www.varnish-cache.org/) or [Nginx](https://blog.nginx.org/blog/nginx-caching-guide) (see also [Nginx Caching](https://serversforhackers.com/nginx-caching/)) to greatly improve the speed and performance of your app.
+
+### Use a load balancer
+
+No matter how optimized an app is, a single instance can handle only a limited amount of load and traffic. One way to scale an app is to run multiple instances of it and distribute the traffic via a load balancer. Setting up a load balancer can improve your app's performance and speed, and enable it to scale more than is possible with a single instance.
+
+A load balancer is usually a reverse proxy that orchestrates traffic to and from multiple application instances and servers. You can easily set up a load balancer for your app by using [Nginx](https://nginx.org/en/docs/http/load_balancing) or [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts).
+
+With load balancing, you might have to ensure that requests that are associated with a particular session ID connect to the process that originated them. This is known as _session affinity_, or _sticky sessions_, and may be addressed by the suggestion above to use a data store such as Redis for session data (depending on your application). For a discussion, see [Using multiple nodes](https://socket.io/docs/v4/using-multiple-nodes/).
+
+### Use a reverse proxy
+
+A reverse proxy sits in front of a web app and performs supporting operations on the requests, apart from directing requests to the app. It can handle error pages, compression, caching, serving files, and load balancing among other things.
+
+Handing over tasks that do not require knowledge of application state to a reverse proxy frees up Express to perform specialized application tasks. For this reason, it is recommended to run Express behind a reverse proxy like [Nginx](https://www.nginx.org/) or [HAProxy](https://www.haproxy.org/) in production.
diff --git a/astro/src/content/docs/en/4x/advanced/best-practice-security.md b/astro/src/content/docs/en/4x/advanced/best-practice-security.md
new file mode 100644
index 0000000000..1341252dad
--- /dev/null
+++ b/astro/src/content/docs/en/4x/advanced/best-practice-security.md
@@ -0,0 +1,283 @@
+---
+title: Security Best Practices for Express in Production
+description: Discover crucial security best practices for Express apps in production, including using TLS, input validation, secure cookies, and preventing vulnerabilities.
+---
+
+# Production Best Practices: Security
+
+## Overview
+
+The term _"production"_ refers to the stage in the software lifecycle when an application or API is generally available to its end-users or consumers. In contrast, in the _"development"_ stage, you're still actively writing and testing code, and the application is not open to external access. The corresponding system environments are known as _production_ and _development_ environments, respectively.
+
+Development and production environments are usually set up differently and have vastly different requirements. What's fine in development may not be acceptable in production. For example, in a development environment you may want verbose logging of errors for debugging, while the same behavior can become a security concern in a production environment. And in development, you don't need to worry about scalability, reliability, and performance, while those concerns become critical in production.
+
+{% capture security-note %}
+
+If you believe you have discovered a security vulnerability in Express, please see
+[Security Policies and Procedures](/en/resources/contributing#security-policies-and-procedures).
+
+{% endcapture %}
+
+{% include admonitions/note.html content=security-note %}
+
+Security best practices for Express applications in production include:
+
+- [Production Best Practices: Security](#production-best-practices-security)
+ - [Overview](#overview)
+ - [Don't use deprecated or vulnerable versions of Express](#dont-use-deprecated-or-vulnerable-versions-of-express)
+ - [Use TLS](#use-tls)
+ - [Do not trust user input](#do-not-trust-user-input)
+ - [Prevent open redirects](#prevent-open-redirects)
+ - [Use Helmet](#use-helmet)
+ - [Reduce fingerprinting](#reduce-fingerprinting)
+ - [Use cookies securely](#use-cookies-securely)
+ - [Don't use the default session cookie name](#dont-use-the-default-session-cookie-name)
+ - [Set cookie security options](#set-cookie-security-options)
+ - [Prevent brute-force attacks against authorization](#prevent-brute-force-attacks-against-authorization)
+ - [Ensure your dependencies are secure](#ensure-your-dependencies-are-secure)
+ - [Avoid other known vulnerabilities](#avoid-other-known-vulnerabilities)
+ - [Additional considerations](#additional-considerations)
+
+## Don't use deprecated or vulnerable versions of Express
+
+Express 2.x and 3.x are no longer maintained. Security and performance issues in these versions won't be fixed. Do not use them! If you haven't moved to version 4, follow the [migration guide](/en/guide/migrating-4) or consider [Commercial Support Options](/en/support#commercial-support-options).
+
+Also ensure you are not using any of the vulnerable Express versions listed on the [Security updates page](/en/advanced/security-updates). If you are, update to one of the stable releases, preferably the latest.
+
+## Use TLS
+
+If your app deals with or transmits sensitive data, use [Transport Layer Security](https://en.wikipedia.org/wiki/Transport_Layer_Security) (TLS) to secure the connection and the data. This technology encrypts data before it is sent from the client to the server, thus preventing some common (and easy) hacks. Although Ajax and POST requests might not be visibly obvious and seem "hidden" in browsers, their network traffic is vulnerable to [packet sniffing](https://en.wikipedia.org/wiki/Packet_analyzer) and [man-in-the-middle attacks](https://en.wikipedia.org/wiki/Man-in-the-middle_attack).
+
+You may be familiar with Secure Socket Layer (SSL) encryption. [TLS is simply the next progression of SSL](). In other words, if you were using SSL before, consider upgrading to TLS. In general, we recommend Nginx to handle TLS. For a good reference to configure TLS on Nginx (and other servers), see [Recommended Server Configurations (Mozilla Wiki)](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations).
+
+Also, a handy tool to get a free TLS certificate is [Let's Encrypt](https://letsencrypt.org/about/), a free, automated, and open certificate authority (CA) provided by the [Internet Security Research Group (ISRG)](https://www.abetterinternet.org/).
+
+## Do not trust user input
+
+For web applications, one of the most critical security requirements is proper user input validation and handling. This comes in many forms and we will not cover all of them here.
+Ultimately, the responsibility for validating and correctly handling the types of user input your application accepts is yours.
+
+### Prevent open redirects
+
+An example of potentially dangerous user input is an _open redirect_, where an application accepts a URL as user input (often in the URL query, for example `?url=https://example.com`) and uses `res.redirect` to set the `location` header and
+return a 3xx status.
+
+An application must validate that it supports redirecting to the incoming URL to avoid sending users to malicious links such as phishing websites, among other risks.
+
+Here is an example of checking URLs before using `res.redirect` or `res.location`:
+
+```js
+app.use((req, res) => {
+ try {
+ if (new Url(req.query.url).host !== 'example.com') {
+ return res.status(400).end(`Unsupported redirect to host: ${req.query.url}`);
+ }
+ } catch (e) {
+ return res.status(400).end(`Invalid url: ${req.query.url}`);
+ }
+ res.redirect(req.query.url);
+});
+```
+
+## Use Helmet
+
+[Helmet][helmet] can help protect your app from some well-known web vulnerabilities by setting HTTP headers appropriately.
+
+Helmet is a middleware function that sets security-related HTTP response headers. Helmet sets the following headers by default:
+
+- `Content-Security-Policy`: A powerful allow-list of what can happen on your page which mitigates many attacks
+- `Cross-Origin-Opener-Policy`: Helps process-isolate your page
+- `Cross-Origin-Resource-Policy`: Blocks others from loading your resources cross-origin
+- `Origin-Agent-Cluster`: Changes process isolation to be origin-based
+- `Referrer-Policy`: Controls the [`Referer`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) header
+- `Strict-Transport-Security`: Tells browsers to prefer HTTPS
+- `X-Content-Type-Options`: Avoids [MIME sniffing](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing)
+- `X-DNS-Prefetch-Control`: Controls DNS prefetching
+- `X-Download-Options`: Forces downloads to be saved (Internet Explorer only)
+- `X-Frame-Options`: Legacy header that mitigates [Clickjacking](https://en.wikipedia.org/wiki/Clickjacking) attacks
+- `X-Permitted-Cross-Domain-Policies`: Controls cross-domain behavior for Adobe products, like Acrobat
+- `X-Powered-By`: Info about the web server. Removed because it could be used in simple attacks
+- `X-XSS-Protection`: Legacy header that tries to mitigate [XSS attacks](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting), but makes things worse, so Helmet disables it
+
+Each header can be configured or disabled. To read more about it please go to [its documentation website][helmet].
+
+Install Helmet like any other module:
+
+```bash
+$ npm install helmet
+```
+
+Then to use it in your code:
+
+```js
+// ...
+
+const helmet = require('helmet');
+app.use(helmet());
+
+// ...
+```
+
+## Reduce fingerprinting
+
+It can help to provide an extra layer of security to reduce the ability of attackers to determine
+the software that a server uses, known as "fingerprinting." Though not a security issue itself,
+reducing the ability to fingerprint an application improves its overall security posture.
+Server software can be fingerprinted by quirks in how it responds to specific requests, for example in
+the HTTP response headers.
+
+By default, Express sends the `X-Powered-By` response header that you can
+disable using the `app.disable()` method:
+
+```js
+app.disable('x-powered-by');
+```
+
+{% capture powered-advisory %}
+
+Disabling the `X-Powered-By header` does not prevent
+a sophisticated attacker from determining that an app is running Express. It may
+discourage a casual exploit, but there are other ways to determine an app is running
+Express.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=powered-advisory %}
+
+Express also sends its own formatted "404 Not Found" messages and formatter error
+response messages. These can be changed by
+[adding your own not found handler](/en/starter/faq#how-do-i-handle-404-responses)
+and
+[writing your own error handler](/en/guide/error-handling#writing-error-handlers):
+
+```js
+// last app.use calls right before app.listen():
+
+// custom 404
+app.use((req, res, next) => {
+ res.status(404).send("Sorry can't find that!");
+});
+
+// custom error handler
+app.use((err, req, res, next) => {
+ console.error(err.stack);
+ res.status(500).send('Something broke!');
+});
+```
+
+## Use cookies securely
+
+To ensure cookies don't open your app to exploits, don't use the default session cookie name and set cookie security options appropriately.
+
+There are two main middleware cookie session modules:
+
+- [express-session](https://www.npmjs.com/package/express-session) that replaces `express.session` middleware built-in to Express 3.x.
+- [cookie-session](https://www.npmjs.com/package/cookie-session) that replaces `express.cookieSession` middleware built-in to Express 3.x.
+
+The main difference between these two modules is how they save cookie session data. The [express-session](https://www.npmjs.com/package/express-session) middleware stores session data on the server; it only saves the session ID in the cookie itself, not session data. By default, it uses in-memory storage and is not designed for a production environment. In production, you'll need to set up a scalable session-store; see the list of [compatible session stores](https://github.com/expressjs/session#compatible-session-stores).
+
+In contrast, [cookie-session](https://www.npmjs.com/package/cookie-session) middleware implements cookie-backed storage: it serializes the entire session to the cookie, rather than just a session key. Only use it when session data is relatively small and easily encoded as primitive values (rather than objects). Although browsers are supposed to support at least 4096 bytes per cookie, to ensure you don't exceed the limit, don't exceed a size of 4093 bytes per domain. Also, be aware that the cookie data will be visible to the client, so if there is any reason to keep it secure or obscure, then `express-session` may be a better choice.
+
+### Don't use the default session cookie name
+
+Using the default session cookie name can open your app to attacks. The security issue posed is similar to `X-Powered-By`: a potential attacker can use it to fingerprint the server and target attacks accordingly.
+
+To avoid this problem, use generic cookie names; for example using [express-session](https://www.npmjs.com/package/express-session) middleware:
+
+```js
+const session = require('express-session');
+app.set('trust proxy', 1); // trust first proxy
+app.use(
+ session({
+ secret: 's3Cur3',
+ name: 'sessionId',
+ })
+);
+```
+
+### Set cookie security options
+
+Set the following cookie options to enhance security:
+
+- `secure` - Ensures the browser only sends the cookie over HTTPS.
+- `httpOnly` - Ensures the cookie is sent only over HTTP(S), not client JavaScript, helping to protect against cross-site scripting attacks.
+- `domain` - indicates the domain of the cookie; use it to compare against the domain of the server in which the URL is being requested. If they match, then check the path attribute next.
+- `path` - indicates the path of the cookie; use it to compare against the request path. If this and domain match, then send the cookie in the request.
+- `expires` - use to set expiration date for persistent cookies.
+
+Here is an example using [cookie-session](https://www.npmjs.com/package/cookie-session) middleware:
+
+```js
+const session = require('cookie-session');
+const express = require('express');
+const app = express();
+
+const expiryDate = new Date(Date.now() + 60 * 60 * 1000); // 1 hour
+app.use(
+ session({
+ name: 'session',
+ keys: ['key1', 'key2'],
+ cookie: {
+ secure: true,
+ httpOnly: true,
+ domain: 'example.com',
+ path: 'foo/bar',
+ expires: expiryDate,
+ },
+ })
+);
+```
+
+## Prevent brute-force attacks against authorization
+
+Make sure login endpoints are protected to make private data more secure.
+
+A simple and powerful technique is to block authorization attempts using two metrics:
+
+1. The number of consecutive failed attempts by the same user name and IP address.
+1. The number of failed attempts from an IP address over some long period of time. For example, block an IP address if it makes 100 failed attempts in one day.
+
+[rate-limiter-flexible](https://github.com/animir/node-rate-limiter-flexible) package provides tools to make this technique easy and fast. You can find [an example of brute-force protection in the documentation](https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#login-endpoint-protection)
+
+## Ensure your dependencies are secure
+
+Using npm to manage your application's dependencies is powerful and convenient. But the packages that you use may contain critical security vulnerabilities that could also affect your application. The security of your app is only as strong as the "weakest link" in your dependencies.
+
+Since npm@6, npm automatically reviews every install request. Also, you can use `npm audit` to analyze your dependency tree.
+
+```bash
+$ npm audit
+```
+
+If you want to stay more secure, consider [Snyk](https://snyk.io/).
+
+Snyk offers both a [command-line tool](https://www.npmjs.com/package/snyk) and a [Github integration](https://snyk.io/docs/github) that checks your application against [Snyk's open source vulnerability database](https://snyk.io/vuln/) for any known vulnerabilities in your dependencies. Install the CLI as follows:
+
+```bash
+$ npm install -g snyk
+$ cd your-app
+```
+
+Use this command to test your application for vulnerabilities:
+
+```bash
+$ snyk test
+```
+
+### Avoid other known vulnerabilities
+
+Keep an eye out for [Node Security Project](https://npmjs.com/advisories) or [Snyk](https://snyk.io/vuln/) advisories that may affect Express or other modules that your app uses. In general, these databases are excellent resources for knowledge and tools about Node security.
+
+Finally, Express apps—like any other web apps—can be vulnerable to a variety of web-based attacks. Familiarize yourself with known [web vulnerabilities](https://www.owasp.org/www-project-top-ten/) and take precautions to avoid them.
+
+## Additional considerations
+
+Here are some further recommendations from the excellent [Node.js Security Checklist](https://blog.risingstack.com/node-js-security-checklist/). Refer to that blog post for all the details on these recommendations:
+
+- Always filter and sanitize user input to protect against cross-site scripting (XSS) and command injection attacks.
+- Defend against SQL injection attacks by using parameterized queries or prepared statements.
+- Use the open-source [sqlmap](http://sqlmap.org/) tool to detect SQL injection vulnerabilities in your app.
+- Use the [nmap](https://nmap.org/) and [sslyze](https://github.com/nabla-c0d3/sslyze) tools to test the configuration of your SSL ciphers, keys, and renegotiation as well as the validity of your certificate.
+- Use [safe-regex](https://www.npmjs.com/package/safe-regex) to ensure your regular expressions are not susceptible to [regular expression denial of service](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS) attacks.
+
+[helmet]: https://helmetjs.github.io/
diff --git a/astro/src/content/docs/en/4x/advanced/developing-template-engines.md b/astro/src/content/docs/en/4x/advanced/developing-template-engines.md
new file mode 100755
index 0000000000..80e28ba8c9
--- /dev/null
+++ b/astro/src/content/docs/en/4x/advanced/developing-template-engines.md
@@ -0,0 +1,45 @@
+---
+title: Developing template engines for Express
+description: Learn how to develop custom template engines for Express.js using app.engine(), with examples on creating and integrating your own template rendering logic.
+---
+
+# Developing template engines for Express
+
+Use the `app.engine(ext, callback)` method to create your own template engine. `ext` refers to the file extension, and `callback` is the template engine function, which accepts the following items as parameters: the location of the file, the options object, and the callback function.
+
+The following code is an example of implementing a very simple template engine for rendering `.ntl` files.
+
+```js
+const fs = require('fs'); // this engine requires the fs module
+app.engine('ntl', (filePath, options, callback) => {
+ // define the template engine
+ fs.readFile(filePath, (err, content) => {
+ if (err) return callback(err);
+ // this is an extremely simple template engine
+ const rendered = content
+ .toString()
+ .replace('#title#', `${options.title} `)
+ .replace('#message#', `${options.message} `);
+ return callback(null, rendered);
+ });
+});
+app.set('views', './views'); // specify the views directory
+app.set('view engine', 'ntl'); // register the template engine
+```
+
+Your app will now be able to render `.ntl` files. Create a file named `index.ntl` in the `views` directory with the following content.
+
+```pug
+#title#
+#message#
+```
+
+Then, create the following route in your app.
+
+```js
+app.get('/', (req, res) => {
+ res.render('index', { title: 'Hey', message: 'Hello there!' });
+});
+```
+
+When you make a request to the home page, `index.ntl` will be rendered as HTML.
diff --git a/astro/src/content/docs/en/4x/advanced/healthcheck-graceful-shutdown.md b/astro/src/content/docs/en/4x/advanced/healthcheck-graceful-shutdown.md
new file mode 100644
index 0000000000..1018345076
--- /dev/null
+++ b/astro/src/content/docs/en/4x/advanced/healthcheck-graceful-shutdown.md
@@ -0,0 +1,30 @@
+---
+title: Health Checks and Graceful Shutdown
+description: Learn how to implement health checks and graceful shutdown in Express apps to enhance reliability, manage deployments, and integrate with load balancers like Kubernetes.
+---
+
+# Health Checks and Graceful Shutdown
+
+## Graceful shutdown
+
+When you deploy a new version of your application, you must replace the previous version. The process manager you're using will first send a SIGTERM signal to the application to notify it that it will be killed. Once the application gets this signal, it should stop accepting new requests, finish all the ongoing requests, clean up the resources it used, including database connections and file locks then exit.
+
+### Example
+
+```js
+const server = app.listen(port);
+
+process.on('SIGTERM', () => {
+ debug('SIGTERM signal received: closing HTTP server');
+ server.close(() => {
+ debug('HTTP server closed');
+ });
+});
+```
+
+## Health checks
+
+A load balancer uses health checks to determine if an application instance is healthy and can accept requests. For example, [Kubernetes has two health checks](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/):
+
+- `liveness`, that determines when to restart a container.
+- `readiness`, that determines when a container is ready to start accepting traffic. When a pod is not ready, it is removed from the service load balancers.
diff --git a/astro/src/content/docs/en/4x/advanced/security-updates.md b/astro/src/content/docs/en/4x/advanced/security-updates.md
new file mode 100755
index 0000000000..72d02e161c
--- /dev/null
+++ b/astro/src/content/docs/en/4x/advanced/security-updates.md
@@ -0,0 +1,83 @@
+---
+title: Express security updates
+description: Review the latest security updates and patches for Express.js, including detailed vulnerability lists for different versions to help maintain a secure application.
+---
+
+# Security updates
+
+
+Node.js vulnerabilities directly affect Express. Therefore, [keep a watch on Node.js vulnerabilities](https://nodejs.org/en/blog/vulnerability/) and make sure you are using the latest stable version of Node.js.
+
+
+The list below enumerates the Express vulnerabilities that were fixed in the specified version update.
+
+{% capture security-policy %}
+If you believe you have discovered a security vulnerability in Express, please see
+[Security Policies and Procedures](/en/resources/contributing#security-policies-and-procedures).
+{% endcapture %}
+
+{% include admonitions/note.html content=security-policy %}
+
+## 4.x
+
+- 4.21.2
+ - The dependency `path-to-regexp` has been updated to address a [vulnerability](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-rhx6-c78j-4q9w).
+- 4.21.1
+ - The dependency `cookie` has been updated to address a [vulnerability](https://github.com/jshttp/cookie/security/advisories/GHSA-pxg6-pf52-xh8x), This may affect your application if you use `res.cookie`.
+- 4.20.0
+ - Fixed XSS vulnerability in `res.redirect` ([advisory](https://github.com/expressjs/express/security/advisories/GHSA-qw6h-vgh9-j6wx), [CVE-2024-43796](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-43796)).
+ - The dependency `serve-static` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-cm22-4g7w-348p).
+ - The dependency `send` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-m6fv-jmcg-4jfg).
+ - The dependency `path-to-regexp` has been updated to address a [vulnerability](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-9wv6-86v2-598j).
+ - The dependency `body-parser` has been updated to addres a [vulnerability](https://github.com/advisories/GHSA-qwcr-r2fm-qrc7), This may affect your application if you had url enconding activated.
+- 4.19.0, 4.19.1
+ - Fixed open redirect vulnerability in `res.location` and `res.redirect` ([advisory](https://github.com/expressjs/express/security/advisories/GHSA-rv95-896h-c2vc), [CVE-2024-29041](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-29041)).
+- 4.17.3
+ - The dependency `qs` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-hrpp-h998-j3pp). This may affect your application if the following APIs are used: `req.query`, `req.body`, `req.param`.
+- 4.16.0
+ - The dependency `forwarded` has been updated to address a [vulnerability](https://npmjs.com/advisories/527). This may affect your application if the following APIs are used: `req.host`, `req.hostname`, `req.ip`, `req.ips`, `req.protocol`.
+ - The dependency `mime` has been updated to address a [vulnerability](https://npmjs.com/advisories/535), but this issue does not impact Express.
+ - The dependency `send` has been updated to provide a protection against a [Node.js 8.5.0 vulnerability](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/). This only impacts running Express on the specific Node.js version 8.5.0.
+- 4.15.5
+ - The dependency `debug` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:debug:20170905), but this issue does not impact Express.
+ - The dependency `fresh` has been updated to address a [vulnerability](https://npmjs.com/advisories/526). This will affect your application if the following APIs are used: `express.static`, `req.fresh`, `res.json`, `res.jsonp`, `res.send`, `res.sendfile` `res.sendFile`, `res.sendStatus`.
+- 4.15.3
+ - The dependency `ms` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:ms:20170412). This may affect your application if untrusted string input is passed to the `maxAge` option in the following APIs: `express.static`, `res.sendfile`, and `res.sendFile`.
+- 4.15.2
+ - The dependency `qs` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:qs:20170213), but this issue does not impact Express. Updating to 4.15.2 is a good practice, but not required to address the vulnerability.
+- 4.11.1
+ - Fixed root path disclosure vulnerability in `express.static`, `res.sendfile`, and `res.sendFile`
+- 4.10.7
+ - Fixed open redirect vulnerability in `express.static` ([advisory](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)).
+- 4.8.8
+ - Fixed directory traversal vulnerabilities in `express.static` ([advisory](http://npmjs.com/advisories/32) , [CVE-2014-6394](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6394)).
+- 4.8.4
+ - Node.js 0.10 can leak `fd`s in certain situations that affect `express.static` and `res.sendfile`. Malicious requests could cause `fd`s to leak and eventually lead to `EMFILE` errors and server unresponsiveness.
+- 4.8.0
+ - Sparse arrays that have extremely high indexes in the query string could cause the process to run out of memory and crash the server.
+ - Extremely nested query string objects could cause the process to block and make the server unresponsive temporarily.
+
+## 3.x
+
+
+ **Express 3.x IS END-OF-LIFE AND NO LONGER MAINTAINED**
+
+Known and unknown security and performance issues in 3.x have not been addressed since the last update (1 August, 2015). It is highly recommended to use the latest version of Express.
+
+If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/en/support#commercial-support-options).
+
+
+
+- 3.19.1
+ - Fixed root path disclosure vulnerability in `express.static`, `res.sendfile`, and `res.sendFile`
+- 3.19.0
+ - Fixed open redirect vulnerability in `express.static` ([advisory](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)).
+- 3.16.10
+ - Fixed directory traversal vulnerabilities in `express.static`.
+- 3.16.6
+ - Node.js 0.10 can leak `fd`s in certain situations that affect `express.static` and `res.sendfile`. Malicious requests could cause `fd`s to leak and eventually lead to `EMFILE` errors and server unresponsiveness.
+- 3.16.0
+ - Sparse arrays that have extremely high indexes in query string could cause the process to run out of memory and crash the server.
+ - Extremely nested query string objects could cause the process to block and make the server unresponsive temporarily.
+- 3.3.0
+ - The 404 response of an unsupported method override attempt was susceptible to cross-site scripting attacks.
diff --git a/astro/src/content/docs/en/4x/api.md b/astro/src/content/docs/en/4x/api.md
new file mode 100644
index 0000000000..0cc0143122
--- /dev/null
+++ b/astro/src/content/docs/en/4x/api.md
@@ -0,0 +1,8 @@
+---
+title: 4x API Reference
+description: API Reference for version 4.x
+---
+
+# 4.x API
+
+Some content here...
diff --git a/astro/src/content/docs/en/4x/guide/behind-proxies.md b/astro/src/content/docs/en/4x/guide/behind-proxies.md
new file mode 100755
index 0000000000..7c217b3e2a
--- /dev/null
+++ b/astro/src/content/docs/en/4x/guide/behind-proxies.md
@@ -0,0 +1,92 @@
+---
+title: Express behind proxies
+description: Learn how to configure Express.js applications to work correctly behind reverse proxies, including using the trust proxy setting to handle client IP addresses.
+---
+
+# Express behind proxies
+
+When running an Express app behind a reverse proxy, some of the Express APIs may return different values than expected. In order to adjust for this, the `trust proxy` application setting may be used to expose information provided by the reverse proxy in the Express APIs. The most common issue is express APIs that expose the client's IP address may instead show an internal IP address of the reverse proxy.
+
+
+When configuring the `trust proxy` setting, it is important to understand the exact setup of the reverse proxy. Since this setting will trust values provided in the request, it is important that the combination of the setting in Express matches how the reverse proxy operates.
+
+
+The application setting `trust proxy` may be set to one of the values listed in the following table.
+
+
+ Type Value
+
+
+ Boolean
+
+If `true`, the client's IP address is understood as the left-most entry in the `X-Forwarded-For` header.
+
+If `false`, the app is understood as directly facing the client and the client's IP address is derived from `req.socket.remoteAddress`. This is the default setting.
+
+
+When setting to `true`, it is important to ensure that the last reverse proxy trusted is removing/overwriting all of the following HTTP headers: `X-Forwarded-For`, `X-Forwarded-Host`, and `X-Forwarded-Proto`, otherwise it may be possible for the client to provide any value.
+
+
+
+
+ IP addresses
+
+An IP address, subnet, or an array of IP addresses and subnets to trust as being a reverse proxy. The following list shows the pre-configured subnet names:
+
+- loopback - `127.0.0.1/8`, `::1/128`
+- linklocal - `169.254.0.0/16`, `fe80::/10`
+- uniquelocal - `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7`
+
+You can set IP addresses in any of the following ways:
+
+```js
+app.set('trust proxy', 'loopback'); // specify a single subnet
+app.set('trust proxy', 'loopback, 123.123.123.123'); // specify a subnet and an address
+app.set('trust proxy', 'loopback, linklocal, uniquelocal'); // specify multiple subnets as CSV
+app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']); // specify multiple subnets as an array
+```
+
+When specified, the IP addresses or the subnets are excluded from the address determination process, and the untrusted IP address nearest to the application server is determined as the client's IP address. This works by checking if `req.socket.remoteAddress` is trusted. If so, then each address in `X-Forwarded-For` is checked from right to left until the first non-trusted address.
+
+
+
+
+ Number
+
+Use the address that is at most `n` number of hops away from the Express application. `req.socket.remoteAddress` is the first hop, and the rest are looked for in the `X-Forwarded-For` header from right to left. A value of `0` means that the first untrusted address would be `req.socket.remoteAddress`, i.e. there is no reverse proxy.
+
+
+When using this setting, it is important to ensure there are not multiple, different-length paths to the Express application such that the client can be less than the configured number of hops away, otherwise it may be possible for the client to provide any value.
+
+
+
+
+ Function
+
+Custom trust implementation.
+
+```js
+app.set('trust proxy', (ip) => {
+ if (ip === '127.0.0.1' || ip === '123.123.123.123')
+ return true; // trusted IPs
+ else return false;
+});
+```
+
+
+
+
+
+
+Enabling `trust proxy` will have the following impact:
+
+
+ The value of [req.hostname](/en/api#req.hostname) is derived from the value set in the `X-Forwarded-Host` header, which can be set by the client or by the proxy.
+
+ `X-Forwarded-Proto` can be set by the reverse proxy to tell the app whether it is `https` or `http` or even an invalid name. This value is reflected by [req.protocol](/en/api#req.protocol).
+
+ The [req.ip](/en/api#req.ip) and [req.ips](/en/api#req.ips) values are populated based on the socket address and `X-Forwarded-For` header, starting at the first untrusted address.
+
+
+
+The `trust proxy` setting is implemented using the [proxy-addr](https://www.npmjs.com/package/proxy-addr) package. For more information, see its documentation.
diff --git a/astro/src/content/docs/en/4x/guide/database-integration.md b/astro/src/content/docs/en/4x/guide/database-integration.md
new file mode 100644
index 0000000000..3c653355ad
--- /dev/null
+++ b/astro/src/content/docs/en/4x/guide/database-integration.md
@@ -0,0 +1,501 @@
+---
+title: Express database integration
+description: Discover how to integrate various databases with Express.js applications, including setup examples for MongoDB, MySQL, PostgreSQL, and more.
+---
+
+# Database integration
+
+Adding the capability to connect databases to Express apps is just a matter of loading an appropriate Node.js driver for the database in your app. This document briefly explains how to add and use some of the most popular Node.js modules for database systems in your Express app:
+
+- [Cassandra](#cassandra)
+- [Couchbase](#couchbase)
+- [CouchDB](#couchdb)
+- [LevelDB](#leveldb)
+- [MySQL](#mysql)
+- [MongoDB](#mongodb)
+- [Neo4j](#neo4j)
+- [Oracle](#oracle)
+- [PostgreSQL](#postgresql)
+- [Redis](#redis)
+- [SQL Server](#sql-server)
+- [SQLite](#sqlite)
+- [Elasticsearch](#elasticsearch)
+
+
+These database drivers are among many that are available. For other options,
+search on the [npm](https://www.npmjs.com/) site.
+
+
+## Cassandra
+
+**Module**: [cassandra-driver](https://github.com/datastax/nodejs-driver)
+
+### Installation
+
+```bash
+$ npm install cassandra-driver
+```
+
+### Example
+
+```js
+const cassandra = require('cassandra-driver');
+const client = new cassandra.Client({ contactPoints: ['localhost'] });
+
+client.execute('select key from system.local', (err, result) => {
+ if (err) throw err;
+ console.log(result.rows[0]);
+});
+```
+
+## Couchbase
+
+**Module**: [couchnode](https://github.com/couchbase/couchnode)
+
+### Installation
+
+```bash
+$ npm install couchbase
+```
+
+### Example
+
+```js
+const couchbase = require('couchbase');
+const bucket = new couchbase.Cluster('http://localhost:8091').openBucket('bucketName');
+
+// add a document to a bucket
+bucket.insert('document-key', { name: 'Matt', shoeSize: 13 }, (err, result) => {
+ if (err) {
+ console.log(err);
+ } else {
+ console.log(result);
+ }
+});
+
+// get all documents with shoe size 13
+const n1ql = 'SELECT d.* FROM `bucketName` d WHERE shoeSize = $1';
+const query = N1qlQuery.fromString(n1ql);
+bucket.query(query, [13], (err, result) => {
+ if (err) {
+ console.log(err);
+ } else {
+ console.log(result);
+ }
+});
+```
+
+## CouchDB
+
+**Module**: [nano](https://github.com/dscape/nano)
+
+### Installation
+
+```bash
+$ npm install nano
+```
+
+### Example
+
+```js
+const nano = require('nano')('http://localhost:5984');
+nano.db.create('books');
+const books = nano.db.use('books');
+
+// Insert a book document in the books database
+books.insert({ name: 'The Art of war' }, null, (err, body) => {
+ if (err) {
+ console.log(err);
+ } else {
+ console.log(body);
+ }
+});
+
+// Get a list of all books
+books.list((err, body) => {
+ if (err) {
+ console.log(err);
+ } else {
+ console.log(body.rows);
+ }
+});
+```
+
+## LevelDB
+
+**Module**: [levelup](https://github.com/rvagg/node-levelup)
+
+### Installation
+
+```bash
+$ npm install level levelup leveldown
+```
+
+### Example
+
+```js
+const levelup = require('levelup');
+const db = levelup('./mydb');
+
+db.put('name', 'LevelUP', (err) => {
+ if (err) return console.log('Ooops!', err);
+
+ db.get('name', (err, value) => {
+ if (err) return console.log('Ooops!', err);
+
+ console.log(`name=${value}`);
+ });
+});
+```
+
+## MySQL
+
+**Module**: [mysql](https://github.com/felixge/node-mysql/)
+
+### Installation
+
+```bash
+$ npm install mysql
+```
+
+### Example
+
+```js
+const mysql = require('mysql');
+const connection = mysql.createConnection({
+ host: 'localhost',
+ user: 'dbuser',
+ password: 's3kreee7',
+ database: 'my_db',
+});
+
+connection.connect();
+
+connection.query('SELECT 1 + 1 AS solution', (err, rows, fields) => {
+ if (err) throw err;
+
+ console.log('The solution is: ', rows[0].solution);
+});
+
+connection.end();
+```
+
+## MongoDB
+
+**Module**: [mongodb](https://github.com/mongodb/node-mongodb-native)
+
+### Installation
+
+```bash
+$ npm install mongodb
+```
+
+### Example (v2.\*)
+
+```js
+const MongoClient = require('mongodb').MongoClient;
+
+MongoClient.connect('mongodb://localhost:27017/animals', (err, db) => {
+ if (err) throw err;
+
+ db.collection('mammals')
+ .find()
+ .toArray((err, result) => {
+ if (err) throw err;
+
+ console.log(result);
+ });
+});
+```
+
+### Example (v3.\*)
+
+```js
+const MongoClient = require('mongodb').MongoClient;
+
+MongoClient.connect('mongodb://localhost:27017/animals', (err, client) => {
+ if (err) throw err;
+
+ const db = client.db('animals');
+
+ db.collection('mammals')
+ .find()
+ .toArray((err, result) => {
+ if (err) throw err;
+
+ console.log(result);
+ });
+});
+```
+
+If you want an object model driver for MongoDB, look at [Mongoose](https://github.com/LearnBoost/mongoose).
+
+## Neo4j
+
+**Module**: [neo4j-driver](https://github.com/neo4j/neo4j-javascript-driver)
+
+### Installation
+
+```bash
+$ npm install neo4j-driver
+```
+
+### Example
+
+```js
+const neo4j = require('neo4j-driver');
+const driver = neo4j.driver('neo4j://localhost:7687', neo4j.auth.basic('neo4j', 'letmein'));
+
+const session = driver.session();
+
+session.readTransaction((tx) => {
+ return tx
+ .run('MATCH (n) RETURN count(n) AS count')
+ .then((res) => {
+ console.log(res.records[0].get('count'));
+ })
+ .catch((error) => {
+ console.log(error);
+ });
+});
+```
+
+## Oracle
+
+**Module**: [oracledb](https://github.com/oracle/node-oracledb)
+
+### Installation
+
+NOTE: [See installation prerequisites](https://github.com/oracle/node-oracledb#-installation).
+
+```bash
+$ npm install oracledb
+```
+
+### Example
+
+```js
+const oracledb = require('oracledb');
+const config = {
+ user: '',
+ password: '',
+ connectString: 'localhost:1521/orcl',
+};
+
+async function getEmployee(empId) {
+ let conn;
+
+ try {
+ conn = await oracledb.getConnection(config);
+
+ const result = await conn.execute('select * from employees where employee_id = :id', [empId]);
+
+ console.log(result.rows[0]);
+ } catch (err) {
+ console.log('Ouch!', err);
+ } finally {
+ if (conn) {
+ // conn assignment worked, need to close
+ await conn.close();
+ }
+ }
+}
+
+getEmployee(101);
+```
+
+## PostgreSQL
+
+**Module**: [pg-promise](https://github.com/vitaly-t/pg-promise)
+
+### Installation
+
+```bash
+$ npm install pg-promise
+```
+
+### Example
+
+```js
+const pgp = require('pg-promise')(/* options */);
+const db = pgp('postgres://username:password@host:port/database');
+
+db.one('SELECT $1 AS value', 123)
+ .then((data) => {
+ console.log('DATA:', data.value);
+ })
+ .catch((error) => {
+ console.log('ERROR:', error);
+ });
+```
+
+## Redis
+
+**Module**: [redis](https://github.com/mranney/node_redis)
+
+### Installation
+
+```bash
+$ npm install redis
+```
+
+### Example
+
+```js
+const redis = require('redis');
+const client = redis.createClient();
+
+client.on('error', (err) => {
+ console.log(`Error ${err}`);
+});
+
+client.set('string key', 'string val', redis.print);
+client.hset('hash key', 'hashtest 1', 'some value', redis.print);
+client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print);
+
+client.hkeys('hash key', (err, replies) => {
+ console.log(`${replies.length} replies:`);
+
+ replies.forEach((reply, i) => {
+ console.log(` ${i}: ${reply}`);
+ });
+
+ client.quit();
+});
+```
+
+## SQL Server
+
+**Module**: [tedious](https://github.com/tediousjs/tedious)
+
+### Installation
+
+```bash
+$ npm install tedious
+```
+
+### Example
+
+```js
+const Connection = require('tedious').Connection;
+const Request = require('tedious').Request;
+
+const config = {
+ server: 'localhost',
+ authentication: {
+ type: 'default',
+ options: {
+ userName: 'your_username', // update me
+ password: 'your_password', // update me
+ },
+ },
+};
+
+const connection = new Connection(config);
+
+connection.on('connect', (err) => {
+ if (err) {
+ console.log(err);
+ } else {
+ executeStatement();
+ }
+});
+
+function executeStatement() {
+ request = new Request("select 123, 'hello world'", (err, rowCount) => {
+ if (err) {
+ console.log(err);
+ } else {
+ console.log(`${rowCount} rows`);
+ }
+ connection.close();
+ });
+
+ request.on('row', (columns) => {
+ columns.forEach((column) => {
+ if (column.value === null) {
+ console.log('NULL');
+ } else {
+ console.log(column.value);
+ }
+ });
+ });
+
+ connection.execSql(request);
+}
+```
+
+## SQLite
+
+**Module**: [sqlite3](https://github.com/mapbox/node-sqlite3)
+
+### Installation
+
+```bash
+$ npm install sqlite3
+```
+
+### Example
+
+```js
+const sqlite3 = require('sqlite3').verbose();
+const db = new sqlite3.Database(':memory:');
+
+db.serialize(() => {
+ db.run('CREATE TABLE lorem (info TEXT)');
+ const stmt = db.prepare('INSERT INTO lorem VALUES (?)');
+
+ for (let i = 0; i < 10; i++) {
+ stmt.run(`Ipsum ${i}`);
+ }
+
+ stmt.finalize();
+
+ db.each('SELECT rowid AS id, info FROM lorem', (err, row) => {
+ console.log(`${row.id}: ${row.info}`);
+ });
+});
+
+db.close();
+```
+
+## Elasticsearch
+
+**Module**: [elasticsearch](https://github.com/elastic/elasticsearch-js)
+
+### Installation
+
+```bash
+$ npm install elasticsearch
+```
+
+### Example
+
+```js
+const elasticsearch = require('elasticsearch');
+const client = elasticsearch.Client({
+ host: 'localhost:9200',
+});
+
+client
+ .search({
+ index: 'books',
+ type: 'book',
+ body: {
+ query: {
+ multi_match: {
+ query: 'express js',
+ fields: ['title', 'description'],
+ },
+ },
+ },
+ })
+ .then(
+ (response) => {
+ const hits = response.hits.hits;
+ },
+ (error) => {
+ console.trace(error.message);
+ }
+ );
+```
diff --git a/astro/src/content/docs/en/4x/guide/debugging.md b/astro/src/content/docs/en/4x/guide/debugging.md
new file mode 100755
index 0000000000..dfd3374883
--- /dev/null
+++ b/astro/src/content/docs/en/4x/guide/debugging.md
@@ -0,0 +1,127 @@
+---
+title: Debugging Express
+description: Learn how to enable and use debugging logs in Express.js applications by setting the DEBUG environment variable for enhanced troubleshooting.
+---
+
+# Debugging Express
+
+To see all the internal logs used in Express, set the `DEBUG` environment variable to
+`express:*` when launching your app.
+
+```bash
+$ DEBUG=express:* node index.js
+```
+
+On Windows, use the corresponding command.
+
+```bash
+> $env:DEBUG = "express:*"; node index.js
+```
+
+Running this command on the default app generated by the [express generator](/en/starter/generator) prints the following output:
+
+```bash
+$ DEBUG=express:* node ./bin/www
+ express:router:route new / +0ms
+ express:router:layer new / +1ms
+ express:router:route get / +1ms
+ express:router:layer new / +0ms
+ express:router:route new / +1ms
+ express:router:layer new / +0ms
+ express:router:route get / +0ms
+ express:router:layer new / +0ms
+ express:application compile etag weak +1ms
+ express:application compile query parser extended +0ms
+ express:application compile trust proxy false +0ms
+ express:application booting in development mode +1ms
+ express:router use / query +0ms
+ express:router:layer new / +0ms
+ express:router use / expressInit +0ms
+ express:router:layer new / +0ms
+ express:router use / favicon +1ms
+ express:router:layer new / +0ms
+ express:router use / logger +0ms
+ express:router:layer new / +0ms
+ express:router use / jsonParser +0ms
+ express:router:layer new / +1ms
+ express:router use / urlencodedParser +0ms
+ express:router:layer new / +0ms
+ express:router use / cookieParser +0ms
+ express:router:layer new / +0ms
+ express:router use / stylus +90ms
+ express:router:layer new / +0ms
+ express:router use / serveStatic +0ms
+ express:router:layer new / +0ms
+ express:router use / router +0ms
+ express:router:layer new / +1ms
+ express:router use /users router +0ms
+ express:router:layer new /users +0ms
+ express:router use / <anonymous> +0ms
+ express:router:layer new / +0ms
+ express:router use / <anonymous> +0ms
+ express:router:layer new / +0ms
+ express:router use / <anonymous> +0ms
+ express:router:layer new / +0ms
+```
+
+When a request is then made to the app, you will see the logs specified in the Express code:
+
+```bash
+ express:router dispatching GET / +4h
+ express:router query : / +2ms
+ express:router expressInit : / +0ms
+ express:router favicon : / +0ms
+ express:router logger : / +1ms
+ express:router jsonParser : / +0ms
+ express:router urlencodedParser : / +1ms
+ express:router cookieParser : / +0ms
+ express:router stylus : / +0ms
+ express:router serveStatic : / +2ms
+ express:router router : / +2ms
+ express:router dispatching GET / +1ms
+ express:view lookup "index.pug" +338ms
+ express:view stat "/projects/example/views/index.pug" +0ms
+ express:view render "/projects/example/views/index.pug" +1ms
+```
+
+To see the logs only from the router implementation, set the value of `DEBUG` to `express:router`. Likewise, to see logs only from the application implementation, set the value of `DEBUG` to `express:application`, and so on.
+
+## Applications generated by `express`
+
+An application generated by the `express` command uses the `debug` module and its debug namespace is scoped to the name of the application.
+
+For example, if you generated the app with `$ express sample-app`, you can enable the debug statements with the following command:
+
+```bash
+$ DEBUG=sample-app:* node ./bin/www
+```
+
+You can specify more than one debug namespace by assigning a comma-separated list of names:
+
+```bash
+$ DEBUG=http,mail,express:* node index.js
+```
+
+## Advanced options
+
+When running through Node.js, you can set a few environment variables that will change the behavior of the debug logging:
+
+| Name | Purpose |
+| ------------------- | ------------------------------------------------- |
+| `DEBUG` | Enables/disables specific debugging namespaces. |
+| `DEBUG_COLORS` | Whether or not to use colors in the debug output. |
+| `DEBUG_DEPTH` | Object inspection depth. |
+| `DEBUG_FD` | File descriptor to write debug output to. |
+| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. |
+
+{% capture debug-text %}
+
+The environment variables beginning with `DEBUG_` end up being
+converted into an Options object that gets used with `%o`/`%O` formatters.
+See the Node.js documentation for
+[`util.inspect()`](https://nodejs.org/api/util#util_util_inspect_object_options)
+for the complete list.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=debug-text %}
diff --git a/astro/src/content/docs/en/4x/guide/error-handling.md b/astro/src/content/docs/en/4x/guide/error-handling.md
new file mode 100755
index 0000000000..2a8263931f
--- /dev/null
+++ b/astro/src/content/docs/en/4x/guide/error-handling.md
@@ -0,0 +1,306 @@
+---
+title: Express error handling
+description: Understand how Express.js handles errors in synchronous and asynchronous code, and learn to implement custom error handling middleware for your applications.
+---
+
+# Error Handling
+
+_Error Handling_ refers to how Express catches and processes errors that
+occur both synchronously and asynchronously. Express comes with a default error
+handler so you don't need to write your own to get started.
+
+## Catching Errors
+
+It's important to ensure that Express catches all errors that occur while
+running route handlers and middleware.
+
+Errors that occur in synchronous code inside route handlers and middleware
+require no extra work. If synchronous code throws an error, then Express will
+catch and process it. For example:
+
+```js
+app.get('/', (req, res) => {
+ throw new Error('BROKEN'); // Express will catch this on its own.
+});
+```
+
+For errors returned from asynchronous functions invoked by route handlers
+and middleware, you must pass them to the `next()` function, where Express will
+catch and process them. For example:
+
+```js
+app.get('/', (req, res, next) => {
+ fs.readFile('/file-does-not-exist', (err, data) => {
+ if (err) {
+ next(err); // Pass errors to Express.
+ } else {
+ res.send(data);
+ }
+ });
+});
+```
+
+Starting with Express 5, route handlers and middleware that return a Promise
+will call `next(value)` automatically when they reject or throw an error.
+For example:
+
+```js
+app.get('/user/:id', async (req, res, next) => {
+ const user = await getUserById(req.params.id);
+ res.send(user);
+});
+```
+
+If `getUserById` throws an error or rejects, `next` will be called with either
+the thrown error or the rejected value. If no rejected value is provided, `next`
+will be called with a default Error object provided by the Express router.
+
+If you pass anything to the `next()` function (except the string `'route'`),
+Express regards the current request as being an error and will skip any
+remaining non-error handling routing and middleware functions.
+
+If the callback in a sequence provides no data, only errors, you can simplify
+this code as follows:
+
+```js
+app.get('/', [
+ function (req, res, next) {
+ fs.writeFile('/inaccessible-path', 'data', next);
+ },
+ function (req, res) {
+ res.send('OK');
+ },
+]);
+```
+
+In the above example, `next` is provided as the callback for `fs.writeFile`,
+which is called with or without errors. If there is no error, the second
+handler is executed, otherwise Express catches and processes the error.
+
+You must catch errors that occur in asynchronous code invoked by route handlers or
+middleware and pass them to Express for processing. For example:
+
+```js
+app.get('/', (req, res, next) => {
+ setTimeout(() => {
+ try {
+ throw new Error('BROKEN');
+ } catch (err) {
+ next(err);
+ }
+ }, 100);
+});
+```
+
+The above example uses a `try...catch` block to catch errors in the
+asynchronous code and pass them to Express. If the `try...catch`
+block were omitted, Express would not catch the error since it is not part of the synchronous
+handler code.
+
+Use promises to avoid the overhead of the `try...catch` block or when using functions
+that return promises. For example:
+
+```js
+app.get('/', (req, res, next) => {
+ Promise.resolve()
+ .then(() => {
+ throw new Error('BROKEN');
+ })
+ .catch(next); // Errors will be passed to Express.
+});
+```
+
+Since promises automatically catch both synchronous errors and rejected promises,
+you can simply provide `next` as the final catch handler and Express will catch errors,
+because the catch handler is given the error as the first argument.
+
+You could also use a chain of handlers to rely on synchronous error
+catching, by reducing the asynchronous code to something trivial. For example:
+
+```js
+app.get('/', [
+ function (req, res, next) {
+ fs.readFile('/maybe-valid-file', 'utf-8', (err, data) => {
+ res.locals.data = data;
+ next(err);
+ });
+ },
+ function (req, res) {
+ res.locals.data = res.locals.data.split(',')[1];
+ res.send(res.locals.data);
+ },
+]);
+```
+
+The above example has a couple of trivial statements from the `readFile`
+call. If `readFile` causes an error, then it passes the error to Express, otherwise you
+quickly return to the world of synchronous error handling in the next handler
+in the chain. Then, the example above tries to process the data. If this fails, then the
+synchronous error handler will catch it. If you had done this processing inside
+the `readFile` callback, then the application might exit and the Express error
+handlers would not run.
+
+Whichever method you use, if you want Express error handlers to be called in and the
+application to survive, you must ensure that Express receives the error.
+
+## The default error handler
+
+Express comes with a built-in error handler that takes care of any errors that might be encountered in the app. This default error-handling middleware function is added at the end of the middleware function stack.
+
+If you pass an error to `next()` and you do not handle it in a custom error
+handler, it will be handled by the built-in error handler; the error will be
+written to the client with the stack trace. The stack trace is not included
+in the production environment.
+
+
+Set the environment variable `NODE_ENV` to `production`, to run the app in production mode.
+
+
+When an error is written, the following information is added to the
+response:
+
+- The `res.statusCode` is set from `err.status` (or `err.statusCode`). If
+ this value is outside the 4xx or 5xx range, it will be set to 500.
+- The `res.statusMessage` is set according to the status code.
+- The body will be the HTML of the status code message when in production
+ environment, otherwise will be `err.stack`.
+- Any headers specified in an `err.headers` object.
+
+If you call `next()` with an error after you have started writing the
+response (for example, if you encounter an error while streaming the
+response to the client), the Express default error handler closes the
+connection and fails the request.
+
+So when you add a custom error handler, you must delegate to
+the default Express error handler, when the headers
+have already been sent to the client:
+
+```js
+function errorHandler(err, req, res, next) {
+ if (res.headersSent) {
+ return next(err);
+ }
+ res.status(500);
+ res.render('error', { error: err });
+}
+```
+
+Note that the default error handler can get triggered if you call `next()` with an error
+in your code more than once, even if custom error handling middleware is in place.
+
+Other error handling middleware can be found at [Express middleware](/en/resources/middleware).
+
+## Writing error handlers
+
+Define error-handling middleware functions in the same way as other middleware functions,
+except error-handling functions have four arguments instead of three:
+`(err, req, res, next)`. For example:
+
+```js
+app.use((err, req, res, next) => {
+ console.error(err.stack);
+ res.status(500).send('Something broke!');
+});
+```
+
+You define error-handling middleware last, after other `app.use()` and routes calls; for example:
+
+```js
+const bodyParser = require('body-parser');
+const methodOverride = require('method-override');
+
+app.use(
+ bodyParser.urlencoded({
+ extended: true,
+ })
+);
+app.use(bodyParser.json());
+app.use(methodOverride());
+app.use((err, req, res, next) => {
+ // logic
+});
+```
+
+Responses from within a middleware function can be in any format, such as an HTML error page, a simple message, or a JSON string.
+
+For organizational (and higher-level framework) purposes, you can define
+several error-handling middleware functions, much as you would with
+regular middleware functions. For example, to define an error-handler
+for requests made by using `XHR` and those without:
+
+```js
+const bodyParser = require('body-parser');
+const methodOverride = require('method-override');
+
+app.use(
+ bodyParser.urlencoded({
+ extended: true,
+ })
+);
+app.use(bodyParser.json());
+app.use(methodOverride());
+app.use(logErrors);
+app.use(clientErrorHandler);
+app.use(errorHandler);
+```
+
+In this example, the generic `logErrors` might write request and
+error information to `stderr`, for example:
+
+```js
+function logErrors(err, req, res, next) {
+ console.error(err.stack);
+ next(err);
+}
+```
+
+Also in this example, `clientErrorHandler` is defined as follows; in this case, the error is explicitly passed along to the next one.
+
+Notice that when _not_ calling "next" in an error-handling function, you are responsible for writing (and ending) the response. Otherwise, those requests will "hang" and will not be eligible for garbage collection.
+
+```js
+function clientErrorHandler(err, req, res, next) {
+ if (req.xhr) {
+ res.status(500).send({ error: 'Something failed!' });
+ } else {
+ next(err);
+ }
+}
+```
+
+Implement the "catch-all" `errorHandler` function as follows (for example):
+
+```js
+function errorHandler(err, req, res, next) {
+ res.status(500);
+ res.render('error', { error: err });
+}
+```
+
+If you have a route handler with multiple callback functions, you can use the `route` parameter to skip to the next route handler. For example:
+
+```js
+app.get(
+ '/a_route_behind_paywall',
+ (req, res, next) => {
+ if (!req.user.hasPaid) {
+ // continue handling this request
+ next('route');
+ } else {
+ next();
+ }
+ },
+ (req, res, next) => {
+ PaidContent.find((err, doc) => {
+ if (err) return next(err);
+ res.json(doc);
+ });
+ }
+);
+```
+
+In this example, the `getPaidContent` handler will be skipped but any remaining handlers in `app` for `/a_route_behind_paywall` would continue to be executed.
+
+
+Calls to `next()` and `next(err)` indicate that the current handler is complete and in what state. `next(err)` will skip all remaining handlers in the chain except for those that are set up to handle errors as described above.
+
diff --git a/astro/src/content/docs/en/4x/guide/migrating-4.md b/astro/src/content/docs/en/4x/guide/migrating-4.md
new file mode 100755
index 0000000000..3e35818153
--- /dev/null
+++ b/astro/src/content/docs/en/4x/guide/migrating-4.md
@@ -0,0 +1,613 @@
+---
+title: Migrating to Express 4
+description: A guide to migrating your Express.js applications from version 3 to 4, covering changes in middleware, routing, and how to update your codebase effectively.
+---
+
+# Moving to Express 4
+
+Overview
+
+Express 4 is a breaking change from Express 3. That means an existing Express 3 app will _not_ work if you update the Express version in its dependencies.
+
+This article covers:
+
+
+
+Changes in Express 4
+
+There are several significant changes in Express 4:
+
+
+
+See also:
+
+- [New features in 4.x.](https://github.com/expressjs/express/wiki/New-features-in-4.x)
+- [Migrating from 3.x to 4.x.](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x)
+
+
+Changes to Express core and middleware system
+
+
+Express 4 no longer depends on Connect, and removes all built-in
+middleware from its core, except for the `express.static` function. This means that
+Express is now an independent routing and middleware web framework, and
+Express versioning and releases are not affected by middleware updates.
+
+Without built-in middleware, you must explicitly add all the
+middleware that is required to run your app. Simply follow these steps:
+
+1. Install the module: `npm install --save `
+2. In your app, require the module: `require('module-name')`
+3. Use the module according to its documentation: `app.use( ... )`
+
+The following table lists Express 3 middleware and their counterparts in Express 4.
+
+
+
+Here is the [complete list](https://github.com/senchalabs/connect#middleware) of Express 4 middleware.
+
+In most cases, you can simply replace the old version 3 middleware with
+its Express 4 counterpart. For details, see the module documentation in
+GitHub.
+
+app.use accepts parameters
+
+In version 4 you can use a variable parameter to define the path where middleware functions are loaded, then read the value of the parameter from the route handler.
+For example:
+
+```js
+app.use('/book/:id', (req, res, next) => {
+ console.log('ID:', req.params.id);
+ next();
+});
+```
+
+
+The routing system
+
+
+Apps now implicitly load routing middleware, so you no longer have to
+worry about the order in which middleware is loaded with respect to
+the `router` middleware.
+
+The way you define routes is unchanged, but the routing system has two
+new features to help organize your routes:
+
+{: .doclist }
+
+- A new method, `app.route()`, to create chainable route handlers for a route path.
+- A new class, `express.Router`, to create modular mountable route handlers.
+
+app.route() method
+
+The new `app.route()` method enables you to create chainable route handlers
+for a route path. Because the path is specified in a single location, creating modular routes is helpful, as is reducing redundancy and typos. For more
+information about routes, see [`Router()` documentation](/en/4x/api#router).
+
+Here is an example of chained route handlers that are defined by using the `app.route()` function.
+
+```js
+app
+ .route('/book')
+ .get((req, res) => {
+ res.send('Get a random book');
+ })
+ .post((req, res) => {
+ res.send('Add a book');
+ })
+ .put((req, res) => {
+ res.send('Update the book');
+ });
+```
+
+express.Router class
+
+The other feature that helps to organize routes is a new class,
+`express.Router`, that you can use to create modular mountable
+route handlers. A `Router` instance is a complete middleware and
+routing system; for this reason it is often referred to as a "mini-app".
+
+The following example creates a router as a module, loads middleware in
+it, defines some routes, and mounts it on a path on the main app.
+
+For example, create a router file named `birds.js` in the app directory,
+with the following content:
+
+```js
+var express = require('express');
+var router = express.Router();
+
+// middleware specific to this router
+router.use((req, res, next) => {
+ console.log('Time: ', Date.now());
+ next();
+});
+// define the home page route
+router.get('/', (req, res) => {
+ res.send('Birds home page');
+});
+// define the about route
+router.get('/about', (req, res) => {
+ res.send('About birds');
+});
+
+module.exports = router;
+```
+
+Then, load the router module in the app:
+
+```js
+var birds = require('./birds');
+
+// ...
+
+app.use('/birds', birds);
+```
+
+The app will now be able to handle requests to the `/birds` and
+`/birds/about` paths, and will call the `timeLog`
+middleware that is specific to the route.
+
+
+Other changes
+
+
+The following table lists other small but important changes in Express 4:
+
+
+
+Object
+Description
+
+
+Node.js
+Express 4 requires Node.js 0.10.x or later and has dropped support for
+Node.js 0.8.x.
+
+
+
+`http.createServer()`
+
+
+The `http` module is no longer needed, unless you need to directly work with it (socket.io/SPDY/HTTPS). The app can be started by using the
+`app.listen()` function.
+
+
+
+
+`app.configure()`
+
+
+The `app.configure()` function has been removed. Use the
+`process.env.NODE_ENV` or
+`app.get('env')` function to detect the environment and configure the app accordingly.
+
+
+
+
+`json spaces`
+
+
+The `json spaces` application property is disabled by default in Express 4.
+
+
+
+
+`req.accepted()`
+
+
+Use `req.accepts()`, `req.acceptsEncodings()`,
+`req.acceptsCharsets()`, and `req.acceptsLanguages()`.
+
+
+
+
+`res.location()`
+
+
+No longer resolves relative URLs.
+
+
+
+
+`req.params`
+
+
+Was an array; now an object.
+
+
+
+
+`res.locals`
+
+
+Was a function; now an object.
+
+
+
+
+`res.headerSent`
+
+
+Changed to `res.headersSent`.
+
+
+
+
+`app.route`
+
+
+Now available as `app.mountpath`.
+
+
+
+
+`res.on('header')`
+
+
+Removed.
+
+
+
+
+`res.charset`
+
+
+Removed.
+
+
+
+
+`res.setHeader('Set-Cookie', val)`
+
+
+Functionality is now limited to setting the basic cookie value. Use
+`res.cookie()` for added functionality.
+
+
+
+
+Example app migration
+
+Here is an example of migrating an Express 3 application to Express 4.
+The files of interest are `app.js` and `package.json`.
+
+
+Version 3 app
+
+
+app.js
+
+Consider an Express v.3 application with the following `app.js` file:
+
+```js
+var express = require('express');
+var routes = require('./routes');
+var user = require('./routes/user');
+var http = require('http');
+var path = require('path');
+
+var app = express();
+
+// all environments
+app.set('port', process.env.PORT || 3000);
+app.set('views', path.join(__dirname, 'views'));
+app.set('view engine', 'pug');
+app.use(express.favicon());
+app.use(express.logger('dev'));
+app.use(express.methodOverride());
+app.use(express.session({ secret: 'your secret here' }));
+app.use(express.bodyParser());
+app.use(app.router);
+app.use(express.static(path.join(__dirname, 'public')));
+
+// development only
+if (app.get('env') === 'development') {
+ app.use(express.errorHandler());
+}
+
+app.get('/', routes.index);
+app.get('/users', user.list);
+
+http.createServer(app).listen(app.get('port'), () => {
+ console.log('Express server listening on port ' + app.get('port'));
+});
+```
+
+package.json
+
+The accompanying version 3 `package.json` file might look
+something like this:
+
+```json
+{
+ "name": "application-name",
+ "version": "0.0.1",
+ "private": true,
+ "scripts": {
+ "start": "node app.js"
+ },
+ "dependencies": {
+ "express": "3.12.0",
+ "pug": "*"
+ }
+}
+```
+
+
+Process
+
+
+Begin the migration process by installing the required middleware for the
+Express 4 app and updating Express and Pug to their respective latest
+version with the following command:
+
+```bash
+$ npm install serve-favicon morgan method-override express-session body-parser multer errorhandler express@latest pug@latest --save
+```
+
+Make the following changes to `app.js`:
+
+1. The built-in Express middleware functions `express.favicon`,
+ `express.logger`, `express.methodOverride`,
+ `express.session`, `express.bodyParser` and
+ `express.errorHandler` are no longer available on the
+ `express` object. You must install their alternatives
+ manually and load them in the app.
+
+2. You no longer need to load the `app.router` function.
+ It is not a valid Express 4 app object, so remove the
+ `app.use(app.router);` code.
+
+3. Make sure that the middleware functions are loaded in the correct order - load `errorHandler` after loading the app routes.
+
+Version 4 app
+
+package.json
+
+Running the above `npm` command will update `package.json` as follows:
+
+```json
+{
+ "name": "application-name",
+ "version": "0.0.1",
+ "private": true,
+ "scripts": {
+ "start": "node app.js"
+ },
+ "dependencies": {
+ "body-parser": "^1.5.2",
+ "errorhandler": "^1.1.1",
+ "express": "^4.8.0",
+ "express-session": "^1.7.2",
+ "pug": "^2.0.0",
+ "method-override": "^2.1.2",
+ "morgan": "^1.2.2",
+ "multer": "^0.1.3",
+ "serve-favicon": "^2.0.1"
+ }
+}
+```
+
+app.js
+
+Then, remove invalid code, load the required middleware, and make other
+changes as necessary. The `app.js` file will look like this:
+
+```js
+var http = require('http');
+var express = require('express');
+var routes = require('./routes');
+var user = require('./routes/user');
+var path = require('path');
+
+var favicon = require('serve-favicon');
+var logger = require('morgan');
+var methodOverride = require('method-override');
+var session = require('express-session');
+var bodyParser = require('body-parser');
+var multer = require('multer');
+var errorHandler = require('errorhandler');
+
+var app = express();
+
+// all environments
+app.set('port', process.env.PORT || 3000);
+app.set('views', path.join(__dirname, 'views'));
+app.set('view engine', 'pug');
+app.use(favicon(path.join(__dirname, '/public/favicon.ico')));
+app.use(logger('dev'));
+app.use(methodOverride());
+app.use(
+ session({
+ resave: true,
+ saveUninitialized: true,
+ secret: 'uwotm8',
+ })
+);
+app.use(bodyParser.json());
+app.use(bodyParser.urlencoded({ extended: true }));
+app.use(multer());
+app.use(express.static(path.join(__dirname, 'public')));
+
+app.get('/', routes.index);
+app.get('/users', user.list);
+
+// error handling middleware should be loaded after the loading the routes
+if (app.get('env') === 'development') {
+ app.use(errorHandler());
+}
+
+var server = http.createServer(app);
+server.listen(app.get('port'), () => {
+ console.log('Express server listening on port ' + app.get('port'));
+});
+```
+
+
+Unless you need to work directly with the `http` module (socket.io/SPDY/HTTPS), loading it is not required, and the app can be simply started this way:
+
+```js
+app.listen(app.get('port'), () => {
+ console.log('Express server listening on port ' + app.get('port'));
+});
+```
+
+
+
+Run the app
+
+The migration process is complete, and the app is now an
+Express 4 app. To confirm, start the app by using the following command:
+
+```bash
+$ node .
+```
+
+Load [http://localhost:3000](http://localhost:3000)
+and see the home page being rendered by Express 4.
+
+Upgrading to the Express 4 app generator
+
+The command-line tool to generate an Express app is still
+`express`, but to upgrade to the new version, you must uninstall
+the Express 3 app generator and then install the new
+`express-generator`.
+
+Installing
+
+If you already have the Express 3 app generator installed on your system,
+you must uninstall it:
+
+```bash
+$ npm uninstall -g express
+```
+
+Depending on how your file and directory privileges are configured,
+you might need to run this command with `sudo`.
+
+Now install the new generator:
+
+```bash
+$ npm install -g express-generator
+```
+
+Depending on how your file and directory privileges are configured,
+you might need to run this command with `sudo`.
+
+Now the `express` command on your system is updated to the
+Express 4 generator.
+
+Changes to the app generator
+
+Command options and use largely remain the same, with the following exceptions:
+
+{: .doclist }
+
+- Removed the `--sessions` option.
+- Removed the `--jshtml` option.
+- Added the `--hogan` option to support [Hogan.js](http://twitter.github.io/hogan.js/).
+
+Example
+
+Execute the following command to create an Express 4 app:
+
+```bash
+$ express app4
+```
+
+If you look at the contents of the `app4/app.js` file, you will notice
+that all the middleware functions (except `express.static`) that are required for
+the app are loaded as independent modules, and the `router` middleware
+is no longer explicitly loaded in the app.
+
+You will also notice that the `app.js` file is now a Node.js module, in contrast to the standalone app that was generated by the old generator.
+
+After installing the dependencies, start the app by using the following command:
+
+```bash
+$ npm start
+```
+
+If you look at the `npm start` script in the `package.json` file,
+you will notice that the actual command that starts the app is
+`node ./bin/www`, which used to be `node app.js`
+in Express 3.
+
+Because the `app.js` file that was generated by the Express 4 generator
+is now a Node.js module, it can no longer be started independently as an app
+(unless you modify the code). The module must be loaded in a Node.js file
+and started via the Node.js file. The Node.js file is `./bin/www`
+in this case.
+
+Neither the `bin` directory nor the extensionless `www`
+file is mandatory for creating an Express app or starting the app. They are
+just suggestions made by the generator, so feel free to modify them to suit your
+needs.
+
+To get rid of the `www` directory and keep things the "Express 3 way",
+delete the line that says `module.exports = app;` at the end of the
+`app.js` file, then paste the following code in its place:
+
+```js
+app.set('port', process.env.PORT || 3000);
+
+var server = app.listen(app.get('port'), () => {
+ debug('Express server listening on port ' + server.address().port);
+});
+```
+
+Ensure that you load the `debug` module at the top of the `app.js` file by using the following code:
+
+```js
+var debug = require('debug')('app4');
+```
+
+Next, change `"start": "node ./bin/www"` in the `package.json` file to `"start": "node app.js"`.
+
+You have now moved the functionality of `./bin/www` back to
+`app.js`. This change is not recommended, but the exercise helps you
+to understand how the `./bin/www` file works, and why the `app.js` file
+no longer starts on its own.
diff --git a/en/guide/migrating-5.md b/astro/src/content/docs/en/4x/guide/migrating-5.md
similarity index 91%
rename from en/guide/migrating-5.md
rename to astro/src/content/docs/en/4x/guide/migrating-5.md
index 4541a282c9..f042d5ffb4 100755
--- a/en/guide/migrating-5.md
+++ b/astro/src/content/docs/en/4x/guide/migrating-5.md
@@ -1,10 +1,6 @@
---
-layout: page
title: Migrating to Express 5
description: A comprehensive guide to migrating your Express.js applications from version 4 to 5, detailing breaking changes, deprecated methods, and new improvements.
-menu: guide
-order: 10
-redirect_from: "/guide/migrating-5.html"
---
# Moving to Express 5
@@ -79,7 +75,6 @@ You can find the list of available codemods [here](https://codemod.link/express)
res.vary
-
**Improvements**
@@ -100,9 +95,10 @@ Initially, `del` was used instead of `delete`, because `delete` is a reserved ke
{% capture codemod-route-del-to-delete %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx codemod@latest @expressjs/route-del-to-delete
```
+
{% endcapture %}
{% include admonitions/note.html content=codemod-route-del-to-delete %}
@@ -110,13 +106,13 @@ npx codemod@latest @expressjs/route-del-to-delete
```js
// v4
app.del('/user/:id', (req, res) => {
- res.send(`DELETE /user/${req.params.id}`)
-})
+ res.send(`DELETE /user/${req.params.id}`);
+});
// v5
app.delete('/user/:id', (req, res) => {
- res.send(`DELETE /user/${req.params.id}`)
-})
+ res.send(`DELETE /user/${req.params.id}`);
+});
```
app.param(fn)
@@ -136,9 +132,10 @@ The following method names have been pluralized. In Express 4, using the old met
{% capture codemod-pluralized-methods %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx codemod@latest @expressjs/pluralize-method-names
```
+
{% endcapture %}
{% include admonitions/note.html content=codemod-pluralized-methods %}
@@ -146,28 +143,28 @@ npx codemod@latest @expressjs/pluralize-method-names
```js
// v4
app.all('/', (req, res) => {
- req.acceptsCharset('utf-8')
- req.acceptsEncoding('br')
- req.acceptsLanguage('en')
+ req.acceptsCharset('utf-8');
+ req.acceptsEncoding('br');
+ req.acceptsLanguage('en');
// ...
-})
+});
// v5
app.all('/', (req, res) => {
- req.acceptsCharsets('utf-8')
- req.acceptsEncodings('br')
- req.acceptsLanguages('en')
+ req.acceptsCharsets('utf-8');
+ req.acceptsEncodings('br');
+ req.acceptsLanguages('en');
// ...
-})
+});
```
Leading colon (:) in the name for app.param(name, fn)
A leading colon character (:) in the name for the `app.param(name, fn)` function is a remnant of Express 3, and for the sake of backwards compatibility, Express 4 supported it with a deprecation notice. Express 5 will silently ignore it and use the name parameter without prefixing it with a colon.
-This should not affect your code if you follow the Express 4 documentation of [app.param](/{{ page.lang }}/4x/api.html#app.param), as it makes no mention of the leading colon.
+This should not affect your code if you follow the Express 4 documentation of [app.param](/en/4x/api#app.param), as it makes no mention of the leading colon.
req.param(name)
@@ -176,9 +173,10 @@ This potentially confusing and dangerous method of retrieving form data has been
{% capture codemod-req-param %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx codemod@latest @expressjs/explicit-request-params
```
+
{% endcapture %}
{% include admonitions/note.html content=codemod-req-param %}
@@ -186,21 +184,21 @@ npx codemod@latest @expressjs/explicit-request-params
```js
// v4
app.post('/user', (req, res) => {
- const id = req.param('id')
- const body = req.param('body')
- const query = req.param('query')
+ const id = req.param('id');
+ const body = req.param('body');
+ const query = req.param('query');
// ...
-})
+});
// v5
app.post('/user', (req, res) => {
- const id = req.params.id
- const body = req.body
- const query = req.query
+ const id = req.params.id;
+ const body = req.body;
+ const query = req.query;
// ...
-})
+});
```
res.json(obj, status)
@@ -210,9 +208,10 @@ Express 5 no longer supports the signature `res.json(obj, status)`. Instead, set
{% capture codemod-status-send-order %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx codemod@latest @expressjs/status-send-order
```
+
{% endcapture %}
{% include admonitions/note.html content=codemod-status-send-order %}
@@ -220,13 +219,13 @@ npx codemod@latest @expressjs/status-send-order
```js
// v4
app.post('/user', (req, res) => {
- res.json({ name: 'Ruben' }, 201)
-})
+ res.json({ name: 'Ruben' }, 201);
+});
// v5
app.post('/user', (req, res) => {
- res.status(201).json({ name: 'Ruben' })
-})
+ res.status(201).json({ name: 'Ruben' });
+});
```
res.jsonp(obj, status)
@@ -235,17 +234,16 @@ Express 5 no longer supports the signature `res.jsonp(obj, status)`. Instead, se
{% include admonitions/note.html content=codemod-status-send-order %}
-
```js
// v4
app.post('/user', (req, res) => {
- res.jsonp({ name: 'Ruben' }, 201)
-})
+ res.jsonp({ name: 'Ruben' }, 201);
+});
// v5
app.post('/user', (req, res) => {
- res.status(201).jsonp({ name: 'Ruben' })
-})
+ res.status(201).jsonp({ name: 'Ruben' });
+});
```
res.redirect(url, status)
@@ -255,9 +253,10 @@ Express 5 no longer supports the signature `res.redirect(url, status)`. Instead,
{% capture codemod-redirect-arg-order %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx codemod@latest @expressjs/redirect-arg-order
```
+
{% endcapture %}
{% include admonitions/note.html content=codemod-redirect-arg-order %}
@@ -265,16 +264,15 @@ npx codemod@latest @expressjs/redirect-arg-order
```js
// v4
app.get('/user', (req, res) => {
- res.redirect('/users', 301)
-})
+ res.redirect('/users', 301);
+});
// v5
app.get('/user', (req, res) => {
- res.redirect(301, '/users')
-})
+ res.redirect(301, '/users');
+});
```
-
res.redirect('back') and res.location('back')
Express 5 no longer supports the magic string `back` in the `res.redirect()` and `res.location()` methods. Instead, use the `req.get('Referrer') || '/'` value to redirect back to the previous page. In Express 4, the `res.redirect('back')` and `res.location('back')` methods were deprecated.
@@ -282,9 +280,10 @@ Express 5 no longer supports the magic string `back` in the `res.redirect()` and
{% capture codemod-back-redirect-deprecated %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx codemod@latest @expressjs/back-redirect-deprecated
```
+
{% endcapture %}
{% include admonitions/note.html content=codemod-back-redirect-deprecated %}
@@ -292,13 +291,13 @@ npx codemod@latest @expressjs/back-redirect-deprecated
```js
// v4
app.get('/user', (req, res) => {
- res.redirect('back')
-})
+ res.redirect('back');
+});
// v5
app.get('/user', (req, res) => {
- res.redirect(req.get('Referrer') || '/')
-})
+ res.redirect(req.get('Referrer') || '/');
+});
```
res.send(body, status)
@@ -307,17 +306,16 @@ Express 5 no longer supports the signature `res.send(obj, status)`. Instead, set
{% include admonitions/note.html content=codemod-status-send-order %}
-
```js
// v4
app.get('/user', (req, res) => {
- res.send({ name: 'Ruben' }, 200)
-})
+ res.send({ name: 'Ruben' }, 200);
+});
// v5
app.get('/user', (req, res) => {
- res.status(200).send({ name: 'Ruben' })
-})
+ res.status(200).send({ name: 'Ruben' });
+});
```
res.send(status)
@@ -327,17 +325,16 @@ If you need to send a number by using the `res.send()` function, quote the numbe
{% include admonitions/note.html content=codemod-status-send-order %}
-
```js
// v4
app.get('/user', (req, res) => {
- res.send(200)
-})
+ res.send(200);
+});
// v5
app.get('/user', (req, res) => {
- res.sendStatus(200)
-})
+ res.sendStatus(200);
+});
```
res.sendfile()
@@ -356,9 +353,10 @@ The `res.sendfile()` function has been replaced by a camel-cased version `res.se
{% capture codemod-camelcase-sendfile %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx codemod@latest @expressjs/camelcase-sendfile
```
+
{% endcapture %}
{% include admonitions/note.html content=codemod-camelcase-sendfile %}
@@ -366,13 +364,13 @@ npx codemod@latest @expressjs/camelcase-sendfile
```js
// v4
app.get('/user', (req, res) => {
- res.sendfile('/path/to/file')
-})
+ res.sendfile('/path/to/file');
+});
// v5
app.get('/user', (req, res) => {
- res.sendFile('/path/to/file')
-})
+ res.sendFile('/path/to/file');
+});
```
router.param(fn)
@@ -389,17 +387,17 @@ Use the [`mime-types` package](https://github.com/jshttp/mime-types) to work wit
- JavaScript files (.js): now served as "text/javascript" instead of "application/javascript"
- JSON files (.json): now served as "application/json" instead of "text/json"
- CSS files (.css): now served as "text/css" instead of "text/plain"
-- HTML files (.html): now served as "text/html; charset=utf-8" instead of just "text/html"
+- HTML files (): now served as "text/html; charset=utf-8" instead of just "text/html"
- XML files (.xml): now served as "application/xml" instead of "text/xml"
- Font files (.woff): now served as "font/woff" instead of "application/font-woff"
```js
// v4
-express.static.mime.lookup('json')
+express.static.mime.lookup('json');
// v5
-const mime = require('mime-types')
-mime.lookup('json')
+const mime = require('mime-types');
+mime.lookup('json');
```
express:router debug logs
@@ -432,13 +430,13 @@ Path route matching syntax is when a string is supplied as the first parameter t
```js
// v4
app.get('/*', async (req, res) => {
- res.send('ok')
-})
+ res.send('ok');
+});
// v5
app.get('/*splat', async (req, res) => {
- res.send('ok')
-})
+ res.send('ok');
+});
```
{% capture note_wildcard %}
@@ -447,9 +445,10 @@ app.get('/*splat', async (req, res) => {
```js
// v5
app.get('/{*splat}', async (req, res) => {
- res.send('ok')
-})
+ res.send('ok');
+});
```
+
{% endcapture %}
{% include admonitions/note.html content=note_wildcard %}
@@ -458,26 +457,29 @@ app.get('/{*splat}', async (req, res) => {
```js
// v4
app.get('/:file.:ext?', async (req, res) => {
- res.send('ok')
-})
+ res.send('ok');
+});
// v5
app.get('/:file{.:ext}', async (req, res) => {
- res.send('ok')
-})
+ res.send('ok');
+});
```
- Regexp characters are not supported. For example:
+
```js
app.get('/[discussion|page]/:slug', async (req, res) => {
- res.status(200).send('ok')
-})
+ res.status(200).send('ok');
+});
```
+
should be changed to:
+
```js
app.get(['/discussion/:slug', '/page/:slug'], async (req, res) => {
- res.status(200).send('ok')
-})
+ res.status(200).send('ok');
+});
```
- Some characters have been reserved to avoid confusion during upgrade (`()[]?+!`), use `\` to escape them.
@@ -487,7 +489,7 @@ app.get(['/discussion/:slug', '/page/:slug'], async (req, res) => {
Request middleware and handlers that return rejected promises are now handled by forwarding the rejected value as an `Error` to the error handling middleware. This means that using `async` functions as middleware and handlers are easier than ever. When an error is thrown in an `async` function or a rejected promise is `await`ed inside an async function, those errors will be passed to the error handler as if calling `next(err)`.
-Details of how Express handles errors is covered in the [error handling documentation](/en/guide/error-handling.html).
+Details of how Express handles errors is covered in the [error handling documentation](/en/guide/error-handling).
express.urlencoded
@@ -501,7 +503,7 @@ Example of breaking code:
```js
// v4
-app.use(express.static('public'))
+app.use(express.static('public'));
```
After migrating to Express 5, a request to `/.well-known/assetlinks.json` will result in a **404 Not Found**.
@@ -510,13 +512,12 @@ To fix this, serve specific dot-directories explicitly using the `dotfiles: "all
```js
// v5
-app.use('/.well-known', express.static('public/.well-known', { dotfiles: 'allow' }))
-app.use(express.static('public'))
+app.use('/.well-known', express.static('public/.well-known', { dotfiles: 'allow' }));
+app.use(express.static('public'));
```
This approach allows you to safely serve only the intended dot-directories while keeping the default secure behavior for other dotfiles, which remain inaccessible.
-
app.listen
In Express 5, the `app.listen` method will invoke the user-provided callback function (if provided) when the server receives an error event. In Express 4, such errors would be thrown. This change shifts error-handling responsibility to the callback function in Express 5. If there is an error, it will be passed to the callback as an argument.
@@ -525,10 +526,10 @@ For example:
```js
const server = app.listen(8080, '0.0.0.0', (error) => {
if (error) {
- throw error // e.g. EADDRINUSE
+ throw error; // e.g. EADDRINUSE
}
- console.log(`Listening on ${JSON.stringify(server.address())}`)
-})
+ console.log(`Listening on ${JSON.stringify(server.address())}`);
+});
```
app.router
@@ -554,9 +555,9 @@ Wildcards (e.g., `/*splat`) capture path segments as an array instead of a singl
```js
app.get('/*splat', (req, res) => {
// GET /foo/bar
- console.dir(req.params)
+ console.dir(req.params);
// => [Object: null prototype] { splat: [ 'foo', 'bar' ] }
-})
+});
```
**Unmatched parameters are omitted:**
@@ -567,23 +568,23 @@ In Express 4, unmatched wildcards were empty strings (`''`) and optional `:` par
// v4: unmatched wildcard is empty string
app.get('/*', (req, res) => {
// GET /
- console.dir(req.params)
+ console.dir(req.params);
// => { '0': '' }
-})
+});
// v4: unmatched optional param is undefined
app.get('/:file.:ext?', (req, res) => {
// GET /image
- console.dir(req.params)
+ console.dir(req.params);
// => { file: 'image', ext: undefined }
-})
+});
// v5: unmatched optional param is omitted
app.get('/:file{.:ext}', (req, res) => {
// GET /image
- console.dir(req.params)
+ console.dir(req.params);
// => [Object: null prototype] { file: 'image' }
-})
+});
```
req.query
diff --git a/astro/src/content/docs/en/4x/guide/overriding-express-api.md b/astro/src/content/docs/en/4x/guide/overriding-express-api.md
new file mode 100644
index 0000000000..8f78a06422
--- /dev/null
+++ b/astro/src/content/docs/en/4x/guide/overriding-express-api.md
@@ -0,0 +1,70 @@
+---
+title: Overriding the Express API
+description: Discover how to customize and extend the Express.js API by overriding methods and properties on the request and response objects using prototypes.
+---
+
+# Overriding the Express API
+
+The Express API consists of various methods and properties on the request and response objects. These are inherited by prototype. There are two extension points for the Express API:
+
+1. The global prototypes at `express.request` and `express.response`.
+2. App-specific prototypes at `app.request` and `app.response`.
+
+Altering the global prototypes will affect all loaded Express apps in the same process. If desired, alterations can be made app-specific by only altering the app-specific prototypes after creating a new app.
+
+## Methods
+
+You can override the signature and behavior of existing methods with your own, by assigning a custom function.
+
+Following is an example of overriding the behavior of [res.sendStatus](/en/4x/api#res.sendStatus).
+
+```js
+app.response.sendStatus = function (statusCode, type, message) {
+ // code is intentionally kept simple for demonstration purpose
+ return this.contentType(type).status(statusCode).send(message);
+};
+```
+
+The above implementation completely changes the original signature of `res.sendStatus`. It now accepts a status code, encoding type, and the message to be sent to the client.
+
+The overridden method may now be used this way:
+
+```js
+res.sendStatus(404, 'application/json', '{"error":"resource not found"}');
+```
+
+## Properties
+
+Properties in the Express API are either:
+
+1. Assigned properties (ex: `req.baseUrl`, `req.originalUrl`)
+2. Defined as getters (ex: `req.secure`, `req.ip`)
+
+Since properties under category 1 are dynamically assigned on the `request` and `response` objects in the context of the current request-response cycle, their behavior cannot be overridden.
+
+Properties under category 2 can be overwritten using the Express API extensions API.
+
+The following code rewrites how the value of `req.ip` is to be derived. Now, it simply returns the value of the `Client-IP` request header.
+
+```js
+Object.defineProperty(app.request, 'ip', {
+ configurable: true,
+ enumerable: true,
+ get() {
+ return this.get('Client-IP');
+ },
+});
+```
+
+## Prototype
+
+In order to provide the Express API, the request/response objects passed to Express (via `app(req, res)`, for example) need to inherit from the same prototype chain. By default, this is `http.IncomingRequest.prototype` for the request and `http.ServerResponse.prototype` for the response.
+
+Unless necessary, it is recommended that this be done only at the application level, rather than globally. Also, take care that the prototype that is being used matches the functionality as closely as possible to the default prototypes.
+
+```js
+// Use FakeRequest and FakeResponse in place of http.IncomingRequest and http.ServerResponse
+// for the given app reference
+Object.setPrototypeOf(Object.getPrototypeOf(app.request), FakeRequest.prototype);
+Object.setPrototypeOf(Object.getPrototypeOf(app.response), FakeResponse.prototype);
+```
diff --git a/astro/src/content/docs/en/4x/guide/routing.md b/astro/src/content/docs/en/4x/guide/routing.md
new file mode 100755
index 0000000000..cb7868d359
--- /dev/null
+++ b/astro/src/content/docs/en/4x/guide/routing.md
@@ -0,0 +1,417 @@
+---
+title: Express routing
+description: Learn how to define and use routes in Express.js applications, including route methods, route paths, parameters, and using Router for modular routing.
+---
+
+# Routing
+
+_Routing_ refers to how an application's endpoints (URIs) respond to client requests.
+For an introduction to routing, see [Basic routing](/en/starter/basic-routing).
+
+You define routing using methods of the Express `app` object that correspond to HTTP methods;
+for example, `app.get()` to handle GET requests and `app.post` to handle POST requests. For a full list,
+see [app.METHOD](/en/5x/api#app.METHOD). You can also use [app.all()](/en/5x/api#app.all) to handle all HTTP methods and [app.use()](/en/5x/api#app.use) to
+specify middleware as the callback function (See [Using middleware](/en/guide/using-middleware) for details).
+
+These routing methods specify a callback function (sometimes called "handler functions") called when the application receives a request to the specified route (endpoint) and HTTP method. In other words, the application "listens" for requests that match the specified route(s) and method(s), and when it detects a match, it calls the specified callback function.
+
+In fact, the routing methods can have more than one callback function as arguments.
+With multiple callback functions, it is important to provide `next` as an argument to the callback function and then call `next()` within the body of the function to hand off control
+to the next callback.
+
+The following code is an example of a very basic route.
+
+```js
+const express = require('express');
+const app = express();
+
+// respond with "hello world" when a GET request is made to the homepage
+app.get('/', (req, res) => {
+ res.send('hello world');
+});
+```
+
+Route methods
+
+A route method is derived from one of the HTTP methods, and is attached to an instance of the `express` class.
+
+The following code is an example of routes that are defined for the `GET` and the `POST` methods to the root of the app.
+
+```js
+// GET method route
+app.get('/', (req, res) => {
+ res.send('GET request to the homepage');
+});
+
+// POST method route
+app.post('/', (req, res) => {
+ res.send('POST request to the homepage');
+});
+```
+
+Express supports methods that correspond to all HTTP request methods: `get`, `post`, and so on.
+For a full list, see [app.METHOD](/en/5x/api#app.METHOD).
+
+There is a special routing method, `app.all()`, used to load middleware functions at a path for _all_ HTTP request methods. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods).
+
+```js
+app.all('/secret', (req, res, next) => {
+ console.log('Accessing the secret section ...');
+ next(); // pass control to the next handler
+});
+```
+
+Route paths
+
+Route paths, in combination with a request method, define the endpoints at which requests can be made. Route paths can be strings, string patterns, or regular expressions.
+
+{% capture caution-character %} In express 5, the characters `?`, `+`, `*`, `[]`, and `()` are handled differently than in version 4, please review the [migration guide](/en/guide/migrating-5#path-syntax) for more information.{% endcapture %}
+
+{% include admonitions/caution.html content=caution-character %}
+
+{% capture note-dollar-character %}In express 4, regular expression characters such as `$` need to be escaped with a `\`.
+{% endcapture %}
+
+{% include admonitions/caution.html content=note-dollar-character %}
+
+{% capture note-path-to-regexp %}
+
+Express uses [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) for matching the route paths; see the path-to-regexp documentation for all the possibilities in defining route paths. [Express Playground Router](https://bjohansebas.github.io/playground-router/) is a handy tool for testing basic Express routes, although it does not support pattern matching.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=note-path-to-regexp %}
+
+{% capture query-string-note %}
+
+Query strings are not part of the route path.
+
+{% endcapture %}
+
+{% include admonitions/warning.html content=query-string-note %}
+
+### Route paths based on strings
+
+This route path will match requests to the root route, `/`.
+
+```js
+app.get('/', (req, res) => {
+ res.send('root');
+});
+```
+
+This route path will match requests to `/about`.
+
+```js
+app.get('/about', (req, res) => {
+ res.send('about');
+});
+```
+
+This route path will match requests to `/random.text`.
+
+```js
+app.get('/random.text', (req, res) => {
+ res.send('random.text');
+});
+```
+
+### Route paths based on string patterns
+
+{% capture caution-string-patterns %} The string patterns in Express 5 no longer work. Please refer to the [migration guide](/en/guide/migrating-5#path-syntax) for more information.{% endcapture %}
+
+{% include admonitions/caution.html content=caution-string-patterns %}
+
+This route path will match `acd` and `abcd`.
+
+```js
+app.get('/ab?cd', (req, res) => {
+ res.send('ab?cd');
+});
+```
+
+This route path will match `abcd`, `abbcd`, `abbbcd`, and so on.
+
+```js
+app.get('/ab+cd', (req, res) => {
+ res.send('ab+cd');
+});
+```
+
+This route path will match `abcd`, `abxcd`, `abRANDOMcd`, `ab123cd`, and so on.
+
+```js
+app.get('/ab*cd', (req, res) => {
+ res.send('ab*cd');
+});
+```
+
+This route path will match `/abe` and `/abcde`.
+
+```js
+app.get('/ab(cd)?e', (req, res) => {
+ res.send('ab(cd)?e');
+});
+```
+
+### Route paths based on regular expressions
+
+This route path will match anything with an "a" in it.
+
+```js
+app.get(/a/, (req, res) => {
+ res.send('/a/');
+});
+```
+
+This route path will match `butterfly` and `dragonfly`, but not `butterflyman`, `dragonflyman`, and so on.
+
+```js
+app.get(/.*fly$/, (req, res) => {
+ res.send('/.*fly$/');
+});
+```
+
+Route parameters
+
+Route parameters are named URL segments that are used to capture the values specified at their position in the URL. The captured values are populated in the `req.params` object, with the name of the route parameter specified in the path as their respective keys.
+
+```
+Route path: /users/:userId/books/:bookId
+Request URL: http://localhost:3000/users/34/books/8989
+req.params: { "userId": "34", "bookId": "8989" }
+```
+
+To define routes with route parameters, simply specify the route parameters in the path of the route as shown below.
+
+```js
+app.get('/users/:userId/books/:bookId', (req, res) => {
+ res.send(req.params);
+});
+```
+
+
+The name of route parameters must be made up of "word characters" ([A-Za-z0-9_]).
+
+
+Since the hyphen (`-`) and the dot (`.`) are interpreted literally, they can be used along with route parameters for useful purposes.
+
+```
+Route path: /flights/:from-:to
+Request URL: http://localhost:3000/flights/LAX-SFO
+req.params: { "from": "LAX", "to": "SFO" }
+```
+
+```
+Route path: /plantae/:genus.:species
+Request URL: http://localhost:3000/plantae/Prunus.persica
+req.params: { "genus": "Prunus", "species": "persica" }
+```
+
+{% capture warning-regexp %}
+In express 5, Regexp characters are not supported in route paths, for more information please refer to the [migration guide](/en/guide/migrating-5#path-syntax).{% endcapture %}
+
+{% include admonitions/caution.html content=warning-regexp %}
+
+To have more control over the exact string that can be matched by a route parameter, you can append a regular expression in parentheses (`()`):
+
+```
+Route path: /user/:userId(\d+)
+Request URL: http://localhost:3000/user/42
+req.params: {"userId": "42"}
+```
+
+{% capture escape-advisory %}
+
+Because the regular expression is usually part of a literal string, be sure to escape any `\` characters with an additional backslash, for example `\\d+`.
+
+{% endcapture %}
+
+{% include admonitions/warning.html content=escape-advisory %}
+
+{% capture warning-version %}
+
+In Express 4.x, the `*` character in regular expressions is not interpreted in the usual way . As a workaround, use `{0,}` instead of `*`. This will likely be fixed in Express 5.
+
+{% endcapture %}
+
+{% include admonitions/warning.html content=warning-version %}
+
+Route handlers
+
+You can provide multiple callback functions that behave like [middleware](/en/guide/using-middleware) to handle a request. The only exception is that these callbacks might invoke `next('route')` to bypass the remaining route callbacks. You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there's no reason to proceed with the current route.
+
+```js
+app.get('/user/:id', (req, res, next) => {
+ if (req.params.id === '0') {
+ return next('route');
+ }
+ res.send(`User ${req.params.id}`);
+});
+
+app.get('/user/:id', (req, res) => {
+ res.send('Special handler for user ID 0');
+});
+```
+
+In this example:
+
+- `GET /user/5` → handled by first route → sends "User 5"
+- `GET /user/0` → first route calls `next('route')`, skipping to the next matching `/user/:id` route
+
+Route handlers can be in the form of a function, an array of functions, or combinations of both, as shown in the following examples.
+
+A single callback function can handle a route. For example:
+
+```js
+app.get('/example/a', (req, res) => {
+ res.send('Hello from A!');
+});
+```
+
+More than one callback function can handle a route (make sure you specify the `next` object). For example:
+
+```js
+app.get(
+ '/example/b',
+ (req, res, next) => {
+ console.log('the response will be sent by the next function ...');
+ next();
+ },
+ (req, res) => {
+ res.send('Hello from B!');
+ }
+);
+```
+
+An array of callback functions can handle a route. For example:
+
+```js
+const cb0 = function (req, res, next) {
+ console.log('CB0');
+ next();
+};
+
+const cb1 = function (req, res, next) {
+ console.log('CB1');
+ next();
+};
+
+const cb2 = function (req, res) {
+ res.send('Hello from C!');
+};
+
+app.get('/example/c', [cb0, cb1, cb2]);
+```
+
+A combination of independent functions and arrays of functions can handle a route. For example:
+
+```js
+const cb0 = function (req, res, next) {
+ console.log('CB0');
+ next();
+};
+
+const cb1 = function (req, res, next) {
+ console.log('CB1');
+ next();
+};
+
+app.get(
+ '/example/d',
+ [cb0, cb1],
+ (req, res, next) => {
+ console.log('the response will be sent by the next function ...');
+ next();
+ },
+ (req, res) => {
+ res.send('Hello from D!');
+ }
+);
+```
+
+Response methods
+
+The methods on the response object (`res`) in the following table can send a response to the client, and terminate the request-response cycle. If none of these methods are called from a route handler, the client request will be left hanging.
+
+| Method | Description |
+| --------------------------------------------- | ------------------------------------------------------------------------------------- |
+| [res.download()](/en/5x/api#res.download) | Prompt a file to be downloaded. |
+| [res.end()](/en/5x/api#res.end) | End the response process. |
+| [res.json()](/en/5x/api#res.json) | Send a JSON response. |
+| [res.jsonp()](/en/5x/api#res.jsonp) | Send a JSON response with JSONP support. |
+| [res.redirect()](/en/5x/api#res.redirect) | Redirect a request. |
+| [res.render()](/en/5x/api#res.render) | Render a view template. |
+| [res.send()](/en/5x/api#res.send) | Send a response of various types. |
+| [res.sendFile()](/en/5x/api#res.sendFile) | Send a file as an octet stream. |
+| [res.sendStatus()](/en/5x/api#res.sendStatus) | Set the response status code and send its string representation as the response body. |
+
+app.route()
+
+You can create chainable route handlers for a route path by using `app.route()`.
+Because the path is specified at a single location, creating modular routes is helpful, as is reducing redundancy and typos. For more information about routes, see: [Router() documentation](/en/5x/api#router).
+
+Here is an example of chained route handlers that are defined by using `app.route()`.
+
+```js
+app
+ .route('/book')
+ .get((req, res) => {
+ res.send('Get a random book');
+ })
+ .post((req, res) => {
+ res.send('Add a book');
+ })
+ .put((req, res) => {
+ res.send('Update the book');
+ });
+```
+
+express.Router
+
+Use the `express.Router` class to create modular, mountable route handlers. A `Router` instance is a complete middleware and routing system; for this reason, it is often referred to as a "mini-app".
+
+The following example creates a router as a module, loads a middleware function in it, defines some routes, and mounts the router module on a path in the main app.
+
+Create a router file named `birds.js` in the app directory, with the following content:
+
+```js
+const express = require('express');
+const router = express.Router();
+
+// middleware that is specific to this router
+const timeLog = (req, res, next) => {
+ console.log('Time: ', Date.now());
+ next();
+};
+router.use(timeLog);
+
+// define the home page route
+router.get('/', (req, res) => {
+ res.send('Birds home page');
+});
+// define the about route
+router.get('/about', (req, res) => {
+ res.send('About birds');
+});
+
+module.exports = router;
+```
+
+Then, load the router module in the app:
+
+```js
+const birds = require('./birds');
+
+// ...
+
+app.use('/birds', birds);
+```
+
+The app will now be able to handle requests to `/birds` and `/birds/about`, as well as call the `timeLog` middleware function that is specific to the route.
+
+But if the parent route `/birds` has path parameters, it will not be accessible by default from the sub-routes. To make it accessible, you will need to pass the `mergeParams` option to the Router constructor [reference](/en/5x/api#app.use).
+
+```js
+const router = express.Router({ mergeParams: true });
+```
diff --git a/astro/src/content/docs/en/4x/guide/using-middleware.md b/astro/src/content/docs/en/4x/guide/using-middleware.md
new file mode 100644
index 0000000000..f5e67a0b7d
--- /dev/null
+++ b/astro/src/content/docs/en/4x/guide/using-middleware.md
@@ -0,0 +1,295 @@
+---
+title: Using Express middleware
+description: Learn how to use middleware in Express.js applications, including application-level and router-level middleware, error handling, and integrating third-party middleware.
+---
+
+# Using middleware
+
+Express is a routing and middleware web framework that has minimal functionality of its own: An Express application is essentially a series of middleware function calls.
+
+_Middleware_ functions are functions that have access to the [request object](/en/5x/api#req) (`req`), the [response object](/en/5x/api#res) (`res`), and the next middleware function in the application's request-response cycle. The next middleware function is commonly denoted by a variable named `next`.
+
+Middleware functions can perform the following tasks:
+
+- Execute any code.
+- Make changes to the request and the response objects.
+- End the request-response cycle.
+- Call the next middleware function in the stack.
+
+If the current middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Otherwise, the request will be left hanging.
+
+An Express application can use the following types of middleware:
+
+- [Application-level middleware](#middleware.application)
+- [Router-level middleware](#middleware.router)
+- [Error-handling middleware](#middleware.error-handling)
+- [Built-in middleware](#middleware.built-in)
+- [Third-party middleware](#middleware.third-party)
+
+You can load application-level and router-level middleware with an optional mount path.
+You can also load a series of middleware functions together, which creates a sub-stack of the middleware system at a mount point.
+
+Application-level middleware
+
+Bind application-level middleware to an instance of the [app object](/en/5x/api#app) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the HTTP method of the request that the middleware function handles (such as GET, PUT, or POST) in lowercase.
+
+This example shows a middleware function with no mount path. The function is executed every time the app receives a request.
+
+```js
+const express = require('express');
+const app = express();
+
+app.use((req, res, next) => {
+ console.log('Time:', Date.now());
+ next();
+});
+```
+
+This example shows a middleware function mounted on the `/user/:id` path. The function is executed for any type of
+HTTP request on the `/user/:id` path.
+
+```js
+app.use('/user/:id', (req, res, next) => {
+ console.log('Request Type:', req.method);
+ next();
+});
+```
+
+This example shows a route and its handler function (middleware system). The function handles GET requests to the `/user/:id` path.
+
+```js
+app.get('/user/:id', (req, res, next) => {
+ res.send('USER');
+});
+```
+
+Here is an example of loading a series of middleware functions at a mount point, with a mount path.
+It illustrates a middleware sub-stack that prints request info for any type of HTTP request to the `/user/:id` path.
+
+```js
+app.use(
+ '/user/:id',
+ (req, res, next) => {
+ console.log('Request URL:', req.originalUrl);
+ next();
+ },
+ (req, res, next) => {
+ console.log('Request Type:', req.method);
+ next();
+ }
+);
+```
+
+Route handlers enable you to define multiple routes for a path. The example below defines two routes for GET requests to the `/user/:id` path. The second route will not cause any problems, but it will never get called because the first route ends the request-response cycle.
+
+This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path.
+
+```js
+app.get(
+ '/user/:id',
+ (req, res, next) => {
+ console.log('ID:', req.params.id);
+ next();
+ },
+ (req, res, next) => {
+ res.send('User Info');
+ }
+);
+
+// handler for the /user/:id path, which prints the user ID
+app.get('/user/:id', (req, res, next) => {
+ res.send(req.params.id);
+});
+```
+
+To skip the rest of the middleware functions from a router middleware stack, call `next('route')` to pass control to the next route.
+
+{% capture next-function %}
+
+`next('route')` will work only in middleware functions that were loaded by using the `app.METHOD()` or `router.METHOD()` functions.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=next-function %}
+
+This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path.
+
+```js
+app.get(
+ '/user/:id',
+ (req, res, next) => {
+ // if the user ID is 0, skip to the next route
+ if (req.params.id === '0') next('route');
+ // otherwise pass the control to the next middleware function in this stack
+ else next();
+ },
+ (req, res, next) => {
+ // send a regular response
+ res.send('regular');
+ }
+);
+
+// handler for the /user/:id path, which sends a special response
+app.get('/user/:id', (req, res, next) => {
+ res.send('special');
+});
+```
+
+Middleware can also be declared in an array for reusability.
+
+This example shows an array with a middleware sub-stack that handles GET requests to the `/user/:id` path
+
+```js
+function logOriginalUrl(req, res, next) {
+ console.log('Request URL:', req.originalUrl);
+ next();
+}
+
+function logMethod(req, res, next) {
+ console.log('Request Type:', req.method);
+ next();
+}
+
+const logStuff = [logOriginalUrl, logMethod];
+app.get('/user/:id', logStuff, (req, res, next) => {
+ res.send('User Info');
+});
+```
+
+Router-level middleware
+
+Router-level middleware works in the same way as application-level middleware, except it is bound to an instance of `express.Router()`.
+
+```js
+const router = express.Router();
+```
+
+Load router-level middleware by using the `router.use()` and `router.METHOD()` functions.
+
+The following example code replicates the middleware system that is shown above for application-level middleware, by using router-level middleware:
+
+```js
+const express = require('express');
+const app = express();
+const router = express.Router();
+
+// a middleware function with no mount path. This code is executed for every request to the router
+router.use((req, res, next) => {
+ console.log('Time:', Date.now());
+ next();
+});
+
+// a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path
+router.use(
+ '/user/:id',
+ (req, res, next) => {
+ console.log('Request URL:', req.originalUrl);
+ next();
+ },
+ (req, res, next) => {
+ console.log('Request Type:', req.method);
+ next();
+ }
+);
+
+// a middleware sub-stack that handles GET requests to the /user/:id path
+router.get(
+ '/user/:id',
+ (req, res, next) => {
+ // if the user ID is 0, skip to the next router
+ if (req.params.id === '0') next('route');
+ // otherwise pass control to the next middleware function in this stack
+ else next();
+ },
+ (req, res, next) => {
+ // render a regular page
+ res.render('regular');
+ }
+);
+
+// handler for the /user/:id path, which renders a special page
+router.get('/user/:id', (req, res, next) => {
+ console.log(req.params.id);
+ res.render('special');
+});
+
+// mount the router on the app
+app.use('/', router);
+```
+
+To skip the rest of the router's middleware functions, call `next('router')`
+to pass control back out of the router instance.
+
+This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path.
+
+```js
+const express = require('express');
+const app = express();
+const router = express.Router();
+
+// predicate the router with a check and bail out when needed
+router.use((req, res, next) => {
+ if (!req.headers['x-auth']) return next('router');
+ next();
+});
+
+router.get('/user/:id', (req, res) => {
+ res.send('hello, user!');
+});
+
+// use the router and 401 anything falling through
+app.use('/admin', router, (req, res) => {
+ res.sendStatus(401);
+});
+```
+
+Error-handling middleware
+
+
+Error-handling middleware always takes _four_ arguments. You must provide four arguments to identify it as an error-handling middleware function. Even if you don't need to use the `next` object, you must specify it to maintain the signature. Otherwise, the `next` object will be interpreted as regular middleware and will fail to handle errors.
+
+
+Define error-handling middleware functions in the same way as other middleware functions, except with four arguments instead of three, specifically with the signature `(err, req, res, next)`:
+
+```js
+app.use((err, req, res, next) => {
+ console.error(err.stack);
+ res.status(500).send('Something broke!');
+});
+```
+
+For details about error-handling middleware, see: [Error handling](/en/guide/error-handling).
+
+Built-in middleware
+
+Starting with version 4.x, Express no longer depends on [Connect](https://github.com/senchalabs/connect). The middleware
+functions that were previously included with Express are now in separate modules; see [the list of middleware functions](https://github.com/senchalabs/connect#middleware).
+
+Express has the following built-in middleware functions:
+
+- [express.static](/en/5x/api#express.static) serves static assets such as HTML files, images, and so on.
+- [express.json](/en/5x/api#express.json) parses incoming requests with JSON payloads. **NOTE: Available with Express 4.16.0+**
+- [express.urlencoded](/en/5x/api#express.urlencoded) parses incoming requests with URL-encoded payloads. **NOTE: Available with Express 4.16.0+**
+
+Third-party middleware
+
+Use third-party middleware to add functionality to Express apps.
+
+Install the Node.js module for the required functionality, then load it in your app at the application level or at the router level.
+
+The following example illustrates installing and loading the cookie-parsing middleware function `cookie-parser`.
+
+```bash
+$ npm install cookie-parser
+```
+
+```js
+const express = require('express');
+const app = express();
+const cookieParser = require('cookie-parser');
+
+// load the cookie-parsing middleware
+app.use(cookieParser());
+```
+
+For a partial list of third-party middleware functions that are commonly used with Express, see: [Third-party middleware](../resources/middleware).
diff --git a/astro/src/content/docs/en/4x/guide/using-template-engines.md b/astro/src/content/docs/en/4x/guide/using-template-engines.md
new file mode 100755
index 0000000000..a3c0cc1a6f
--- /dev/null
+++ b/astro/src/content/docs/en/4x/guide/using-template-engines.md
@@ -0,0 +1,63 @@
+---
+title: Using template engines with Express
+description: Discover how to integrate and use template engines like Pug, Handlebars, and EJS with Express.js to render dynamic HTML pages efficiently.
+---
+
+# Using template engines with Express
+
+A _template engine_ enables you to use static template files in your application. At runtime, the template engine replaces
+variables in a template file with actual values, and transforms the template into an HTML file sent to the client.
+This approach makes it easier to design an HTML page.
+
+The [Express application generator](/en/starter/generator) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it also supports [Handlebars](https://www.npmjs.com/package/handlebars), and [EJS](https://www.npmjs.com/package/ejs), among others.
+
+To render template files, set the following [application setting properties](/en/4x/api#app.set), in the default `app.js` created by the generator:
+
+- `views`, the directory where the template files are located. Eg: `app.set('views', './views')`.
+ This defaults to the `views` directory in the application root directory.
+- `view engine`, the template engine to use. For example, to use the Pug template engine: `app.set('view engine', 'pug')`.
+
+Then install the corresponding template engine npm package; for example to install Pug:
+
+```bash
+$ npm install pug --save
+```
+
+
+Express-compliant template engines such as Pug export a function named `__express(filePath, options, callback)`,
+which `res.render()` calls to render the template code.
+
+Some template engines do not follow this convention. The [@ladjs/consolidate](https://www.npmjs.com/package/@ladjs/consolidate)
+library follows this convention by mapping all of the popular Node.js template engines, and therefore works seamlessly within Express.
+
+
+
+After the view engine is set, you don't have to specify the engine or load the template engine module in your app;
+Express loads the module internally, for example:
+
+```js
+app.set('view engine', 'pug');
+```
+
+Then, create a Pug template file named `index.pug` in the `views` directory, with the following content:
+
+```pug
+html
+ head
+ title= title
+ body
+ h1= message
+```
+
+Create a route to render the `index.pug` file. If the `view engine` property is not set,
+you must specify the extension of the `view` file. Otherwise, you can omit it.
+
+```js
+app.get('/', (req, res) => {
+ res.render('index', { title: 'Hey', message: 'Hello there!' });
+});
+```
+
+When you make a request to the home page, the `index.pug` file will be rendered as HTML.
+
+The view engine cache does not cache the contents of the template's output, only the underlying template itself. The view is still re-rendered with every request even when the cache is on.
diff --git a/astro/src/content/docs/en/4x/guide/writing-middleware.md b/astro/src/content/docs/en/4x/guide/writing-middleware.md
new file mode 100755
index 0000000000..b53215ad49
--- /dev/null
+++ b/astro/src/content/docs/en/4x/guide/writing-middleware.md
@@ -0,0 +1,218 @@
+---
+title: Writing middleware for use in Express apps
+description: Learn how to write custom middleware functions for Express.js applications, including examples and best practices for enhancing request and response handling.
+---
+
+# Writing middleware for use in Express apps
+
+Overview
+
+_Middleware_ functions are functions that have access to the [request object](/en/5x/api#req) (`req`), the [response object](/en/5x/api#res) (`res`), and the `next` function in the application's request-response cycle. The `next` function is a function in the Express router which, when invoked, executes the middleware succeeding the current middleware.
+
+Middleware functions can perform the following tasks:
+
+- Execute any code.
+- Make changes to the request and the response objects.
+- End the request-response cycle.
+- Call the next middleware in the stack.
+
+If the current middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Otherwise, the request will be left hanging.
+
+The following figure shows the elements of a middleware function call:
+
+
+
+Starting with Express 5, middleware functions that return a Promise will call `next(value)` when they reject or throw an error. `next` will be called with either the rejected value or the thrown Error.
+
+Example
+
+Here is an example of a simple "Hello World" Express application.
+The remainder of this article will define and add three middleware functions to the application:
+one called `myLogger` that prints a simple log message, one called `requestTime` that
+displays the timestamp of the HTTP request, and one called `validateCookies` that validates incoming cookies.
+
+```js
+const express = require('express');
+const app = express();
+
+app.get('/', (req, res) => {
+ res.send('Hello World!');
+});
+
+app.listen(3000);
+```
+
+Middleware function myLogger
+Here is a simple example of a middleware function called "myLogger". This function just prints "LOGGED" when a request to the app passes through it. The middleware function is assigned to a variable named `myLogger`.
+
+```js
+const myLogger = function (req, res, next) {
+ console.log('LOGGED');
+ next();
+};
+```
+
+
+Notice the call above to `next()`. Calling this function invokes the next middleware function in the app.
+The `next()` function is not a part of the Node.js or Express API, but is the third argument that is passed to the middleware function. The `next()` function could be named anything, but by convention it is always named "next".
+To avoid confusion, always use this convention.
+
+
+To load the middleware function, call `app.use()`, specifying the middleware function.
+For example, the following code loads the `myLogger` middleware function before the route to the root path (/).
+
+```js
+const express = require('express');
+const app = express();
+
+const myLogger = function (req, res, next) {
+ console.log('LOGGED');
+ next();
+};
+
+app.use(myLogger);
+
+app.get('/', (req, res) => {
+ res.send('Hello World!');
+});
+
+app.listen(3000);
+```
+
+Every time the app receives a request, it prints the message "LOGGED" to the terminal.
+
+The order of middleware loading is important: middleware functions that are loaded first are also executed first.
+
+If `myLogger` is loaded after the route to the root path, the request never reaches it and the app doesn't print "LOGGED", because the route handler of the root path terminates the request-response cycle.
+
+The middleware function `myLogger` simply prints a message, then passes on the request to the next middleware function in the stack by calling the `next()` function.
+
+Middleware function requestTime
+
+Next, we'll create a middleware function called "requestTime" and add a property called `requestTime`
+to the request object.
+
+```js
+const requestTime = function (req, res, next) {
+ req.requestTime = Date.now();
+ next();
+};
+```
+
+The app now uses the `requestTime` middleware function. Also, the callback function of the root path route uses the property that the middleware function adds to `req` (the request object).
+
+```js
+const express = require('express');
+const app = express();
+
+const requestTime = function (req, res, next) {
+ req.requestTime = Date.now();
+ next();
+};
+
+app.use(requestTime);
+
+app.get('/', (req, res) => {
+ let responseText = 'Hello World! ';
+ responseText += `Requested at: ${req.requestTime} `;
+ res.send(responseText);
+});
+
+app.listen(3000);
+```
+
+When you make a request to the root of the app, the app now displays the timestamp of your request in the browser.
+
+Middleware function validateCookies
+
+Finally, we'll create a middleware function that validates incoming cookies and sends a 400 response if cookies are invalid.
+
+Here's an example function that validates cookies with an external async service.
+
+```js
+async function cookieValidator(cookies) {
+ try {
+ await externallyValidateCookie(cookies.testCookie);
+ } catch {
+ throw new Error('Invalid cookies');
+ }
+}
+```
+
+Here, we use the [`cookie-parser`](/en/resources/middleware/cookie-parser) middleware to parse incoming cookies off the `req` object and pass them to our `cookieValidator` function. The `validateCookies` middleware returns a Promise that upon rejection will automatically trigger our error handler.
+
+```js
+const express = require('express');
+const cookieParser = require('cookie-parser');
+const cookieValidator = require('./cookieValidator');
+
+const app = express();
+
+async function validateCookies(req, res, next) {
+ await cookieValidator(req.cookies);
+ next();
+}
+
+app.use(cookieParser());
+
+app.use(validateCookies);
+
+// error handler
+app.use((err, req, res, next) => {
+ res.status(400).send(err.message);
+});
+
+app.listen(3000);
+```
+
+
+Note how `next()` is called after `await cookieValidator(req.cookies)`. This ensures that if `cookieValidator` resolves, the next middleware in the stack will get called. If you pass anything to the `next()` function (except the string `'route'` or `'router'`), Express regards the current request as being an error and will skip any remaining non-error handling routing and middleware functions.
+
+
+Because you have access to the request object, the response object, the next middleware function in the stack, and the whole Node.js API, the possibilities with middleware functions are endless.
+
+For more information about Express middleware, see: [Using Express middleware](/en/guide/using-middleware).
+
+Configurable middleware
+
+If you need your middleware to be configurable, export a function which accepts an options object or other parameters, which, then returns the middleware implementation based on the input parameters.
+
+File: `my-middleware.js`
+
+```js
+module.exports = function (options) {
+ return function (req, res, next) {
+ // Implement the middleware function based on the options object
+ next();
+ };
+};
+```
+
+The middleware can now be used as shown below.
+
+```js
+const mw = require('./my-middleware.js');
+
+app.use(mw({ option1: '1', option2: '2' }));
+```
+
+Refer to [cookie-session](https://github.com/expressjs/cookie-session) and [compression](https://github.com/expressjs/compression) for examples of configurable middleware.
diff --git a/astro/src/content/docs/en/4x/starter/basic-routing.md b/astro/src/content/docs/en/4x/starter/basic-routing.md
new file mode 100755
index 0000000000..3bc26bc546
--- /dev/null
+++ b/astro/src/content/docs/en/4x/starter/basic-routing.md
@@ -0,0 +1,63 @@
+---
+title: Express basic routing
+description: Learn the fundamentals of routing in Express.js applications, including how to define routes, handle HTTP methods, and create route handlers for your web server.
+---
+
+# Basic routing
+
+_Routing_ refers to determining how an application responds to a client request to a particular endpoint, which is a URI (or path) and a specific HTTP request method (GET, POST, and so on).
+
+Each route can have one or more handler functions, which are executed when the route is matched.
+
+Route definition takes the following structure:
+
+```js
+app.METHOD(PATH, HANDLER);
+```
+
+Where:
+
+- `app` is an instance of `express`.
+- `METHOD` is an [HTTP request method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods), in lowercase.
+- `PATH` is a path on the server.
+- `HANDLER` is the function executed when the route is matched.
+
+
+This tutorial assumes that an instance of `express` named `app` is created and the server is running. If you are not familiar with creating an app and starting it, see the [Hello world example](/en/starter/hello-world).
+
+
+The following examples illustrate defining simple routes.
+
+Respond with `Hello World!` on the homepage:
+
+```js
+app.get('/', (req, res) => {
+ res.send('Hello World!');
+});
+```
+
+Respond to a POST request on the root route (`/`), the application's home page:
+
+```js
+app.post('/', (req, res) => {
+ res.send('Got a POST request');
+});
+```
+
+Respond to a PUT request to the `/user` route:
+
+```js
+app.put('/user', (req, res) => {
+ res.send('Got a PUT request at /user');
+});
+```
+
+Respond to a DELETE request to the `/user` route:
+
+```js
+app.delete('/user', (req, res) => {
+ res.send('Got a DELETE request at /user');
+});
+```
+
+For more details about routing, see the [routing guide](/en/guide/routing).
diff --git a/astro/src/content/docs/en/4x/starter/examples.md b/astro/src/content/docs/en/4x/starter/examples.md
new file mode 100755
index 0000000000..a25a6d9834
--- /dev/null
+++ b/astro/src/content/docs/en/4x/starter/examples.md
@@ -0,0 +1,16 @@
+---
+title: Express examples
+description: Explore a collection of Express.js application examples covering various use cases, integrations, and advanced configurations to help you learn and build your projects.
+---
+
+{% capture examples %}{% include readmes/express-master/examples.md %}{% endcapture %}
+{{ examples | replace: "](.", "](https://github.com/expressjs/express/tree/master/examples" }}
+
+## Additional examples
+
+These are some additional examples with more extensive integrations.
+
+{% include community-caveat.html %}
+
+- [prisma-fullstack](https://github.com/prisma/prisma-examples/tree/latest/pulse/fullstack-simple-chat) - Fullstack app with Express and Next.js using [Prisma](https://www.npmjs.com/package/prisma) as an ORM
+- [prisma-rest-api-ts](https://github.com/prisma/prisma-examples/tree/latest/orm/express) - REST API with Express in TypeScript using [Prisma](https://www.npmjs.com/package/prisma) as an ORM
diff --git a/astro/src/content/docs/en/4x/starter/faq.md b/astro/src/content/docs/en/4x/starter/faq.md
new file mode 100755
index 0000000000..7c82d80c50
--- /dev/null
+++ b/astro/src/content/docs/en/4x/starter/faq.md
@@ -0,0 +1,92 @@
+---
+title: Express FAQ
+description: Find answers to frequently asked questions about Express.js, including topics on application structure, models, authentication, template engines, error handling, and more.
+---
+
+# FAQ
+
+## How should I structure my application?
+
+There is no definitive answer to this question. The answer depends
+on the scale of your application and the team that is involved. To be as
+flexible as possible, Express makes no assumptions in terms of structure.
+
+Routes and other application-specific logic can live in as many files
+as you wish, in any directory structure you prefer. View the following
+examples for inspiration:
+
+- [Route listings](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-L47)
+- [Route map](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66)
+- [MVC style controllers](https://github.com/expressjs/express/tree/master/examples/mvc)
+
+Also, there are third-party extensions for Express, which simplify some of these patterns:
+
+- [Resourceful routing](https://github.com/expressjs/express-resource)
+
+## How do I define models?
+
+Express has no notion of a database. This concept is
+left up to third-party Node modules, allowing you to
+interface with nearly any database.
+
+See [LoopBack](http://loopback.io) for an Express-based framework that is centered around models.
+
+## How can I authenticate users?
+
+Authentication is another opinionated area that Express does not
+venture into. You may use any authentication scheme you wish.
+For a simple username / password scheme, see [this example](https://github.com/expressjs/express/tree/master/examples/auth).
+
+## Which template engines does Express support?
+
+Express supports any template engine that conforms with the `(path, locals, callback)` signature.
+To normalize template engine interfaces and caching, see the
+[consolidate.js](https://github.com/visionmedia/consolidate.js)
+project for support. Unlisted template engines might still support the Express signature.
+
+For more information, see [Using template engines with Express](/en/guide/using-template-engines).
+
+## How do I handle 404 responses?
+
+In Express, 404 responses are not the result of an error, so
+the error-handler middleware will not capture them. This behavior is
+because a 404 response simply indicates the absence of additional work to do;
+in other words, Express has executed all middleware functions and routes,
+and found that none of them responded. All you need to
+do is add a middleware function at the very bottom of the stack (below all other functions)
+to handle a 404 response:
+
+```js
+app.use((req, res, next) => {
+ res.status(404).send("Sorry can't find that!");
+});
+```
+
+Add routes dynamically at runtime on an instance of `express.Router()`
+so the routes are not superseded by a middleware function.
+
+## How do I setup an error handler?
+
+You define error-handling middleware in the same way as other middleware,
+except with four arguments instead of three; specifically with the signature `(err, req, res, next)`:
+
+```js
+app.use((err, req, res, next) => {
+ console.error(err.stack);
+ res.status(500).send('Something broke!');
+});
+```
+
+For more information, see [Error handling](/en/guide/error-handling).
+
+## How do I render plain HTML?
+
+You don't! There's no need to "render" HTML with the `res.render()` function.
+If you have a specific file, use the `res.sendFile()` function.
+If you are serving many assets from a directory, use the `express.static()`
+middleware function.
+
+## What version of Node.js does Express require?
+
+- [Express 4.x](/en/4x/api) requires Node.js 0.10 or higher.
+- [Express 5.x](/en/5x/api) requires Node.js 18 or higher.
diff --git a/astro/src/content/docs/en/4x/starter/generator.md b/astro/src/content/docs/en/4x/starter/generator.md
new file mode 100755
index 0000000000..4ee5058a18
--- /dev/null
+++ b/astro/src/content/docs/en/4x/starter/generator.md
@@ -0,0 +1,122 @@
+---
+title: Express application generator
+description: Learn how to use the Express application generator tool to quickly create a skeleton for your Express.js applications, streamlining setup and configuration.
+---
+
+# Express application generator
+
+Use the application generator tool, `express-generator`, to quickly create an application skeleton.
+
+You can run the application generator with the `npx` command (available in Node.js 8.2.0).
+
+```bash
+$ npx express-generator
+```
+
+For earlier Node versions, install the application generator as a global npm package and then launch it:
+
+```bash
+$ npm install -g express-generator
+$ express
+```
+
+Display the command options with the `-h` option:
+
+```bash
+$ express -h
+
+ Usage: express [options] [dir]
+
+ Options:
+
+ -h, --help output usage information
+ --version output the version number
+ -e, --ejs add ejs engine support
+ --hbs add handlebars engine support
+ --pug add pug engine support
+ -H, --hogan add hogan.js engine support
+ --no-view generate without view engine
+ -v, --view add view support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
+ -c, --css add stylesheet support (less|stylus|compass|sass) (defaults to plain css)
+ --git add .gitignore
+ -f, --force force on non-empty directory
+```
+
+For example, the following creates an Express app named _myapp_. The app will be created in a folder named _myapp_ in the current working directory and the view engine will be set to Pug :
+
+```bash
+$ express --view=pug myapp
+
+ create : myapp
+ create : myapp/package.json
+ create : myapp/app.js
+ create : myapp/public
+ create : myapp/public/javascripts
+ create : myapp/public/images
+ create : myapp/routes
+ create : myapp/routes/index.js
+ create : myapp/routes/users.js
+ create : myapp/public/stylesheets
+ create : myapp/public/stylesheets/style.css
+ create : myapp/views
+ create : myapp/views/index.pug
+ create : myapp/views/layout.pug
+ create : myapp/views/error.pug
+ create : myapp/bin
+ create : myapp/bin/www
+```
+
+Then install dependencies:
+
+```bash
+$ cd myapp
+$ npm install
+```
+
+On MacOS or Linux, run the app with this command:
+
+```bash
+$ DEBUG=myapp:* npm start
+```
+
+On Windows Command Prompt, use this command:
+
+```bash
+> set DEBUG=myapp:* & npm start
+```
+
+On Windows PowerShell, use this command:
+
+```bash
+PS> $env:DEBUG='myapp:*'; npm start
+```
+
+Then, load `http://localhost:3000/` in your browser to access the app.
+
+The generated app has the following directory structure:
+
+```bash
+.
+├── app.js
+├── bin
+│ └── www
+├── package.json
+├── public
+│ ├── images
+│ ├── javascripts
+│ └── stylesheets
+│ └── style.css
+├── routes
+│ ├── index.js
+│ └── users.js
+└── views
+ ├── error.pug
+ ├── index.pug
+ └── layout.pug
+
+7 directories, 9 files
+```
+
+
+The app structure created by the generator is just one of many ways to structure Express apps. Feel free to use this structure or modify it to best suit your needs.
+
diff --git a/astro/src/content/docs/en/4x/starter/hello-world.md b/astro/src/content/docs/en/4x/starter/hello-world.md
new file mode 100755
index 0000000000..97da56d686
--- /dev/null
+++ b/astro/src/content/docs/en/4x/starter/hello-world.md
@@ -0,0 +1,46 @@
+---
+title: Express "Hello World" example
+description: Get started with Express.js by building a simple 'Hello World' application, demonstrating the basic setup and server creation for beginners.
+---
+
+# Hello world example
+
+
+Embedded below is essentially the simplest Express app you can create. It is a single file app — _not_ what you'd get if you use the [Express generator](/en/starter/generator), which creates the scaffolding for a full app with numerous JavaScript files, Jade templates, and sub-directories for various purposes.
+
+
+```js
+const express = require('express');
+const app = express();
+const port = 3000;
+
+app.get('/', (req, res) => {
+ res.send('Hello World!');
+});
+
+app.listen(port, () => {
+ console.log(`Example app listening on port ${port}`);
+});
+```
+
+This app starts a server and listens on port 3000 for connections. The app responds with "Hello World!" for requests
+to the root URL (`/`) or _route_. For every other path, it will respond with a **404 Not Found**.
+
+### Running Locally
+
+First create a directory named `myapp`, change to it and run `npm init`. Then, install `express` as a dependency, as per the [installation guide](/en/starter/installing).
+
+In the `myapp` directory, create a file named `app.js` and copy the code from the example above.
+
+
+The `req` (request) and `res` (response) are the exact same objects that Node provides, so you can invoke
+`req.pipe()`, `req.on('data', callback)`, and anything else you would do without Express involved.
+
+
+Run the app with the following command:
+
+```bash
+$ node app.js
+```
+
+Then, load `http://localhost:3000/` in a browser to see the output.
diff --git a/astro/src/content/docs/en/4x/starter/installing.md b/astro/src/content/docs/en/4x/starter/installing.md
new file mode 100755
index 0000000000..74b1d3ef6f
--- /dev/null
+++ b/astro/src/content/docs/en/4x/starter/installing.md
@@ -0,0 +1,48 @@
+---
+title: Installing Express
+description: Learn how to install Express.js in your Node.js environment, including setting up your project directory and managing dependencies with npm.
+---
+
+# Installing
+
+Assuming you've already installed [Node.js](https://nodejs.org/), create a directory to hold your application, and make that your working directory.
+
+- [Express 4.x](/en/4x/api) requires Node.js 0.10 or higher.
+- [Express 5.x](/en/5x/api) requires Node.js 18 or higher.
+
+```bash
+$ mkdir myapp
+$ cd myapp
+```
+
+Use the `npm init` command to create a `package.json` file for your application.
+For more information on how `package.json` works, see [Specifics of npm's package.json handling](https://docs.npmjs.com/files/package.json).
+
+```bash
+$ npm init
+```
+
+This command prompts you for a number of things, such as the name and version of your application.
+For now, you can simply hit RETURN to accept the defaults for most of them, with the following exception:
+
+```
+entry point: (index.js)
+```
+
+Enter `app.js`, or whatever you want the name of the main file to be. If you want it to be `index.js`, hit RETURN to accept the suggested default file name.
+
+Now, install Express in the `myapp` directory and save it in the dependencies list. For example:
+
+```bash
+$ npm install express
+```
+
+To install Express temporarily and not add it to the dependencies list:
+
+```bash
+$ npm install express --no-save
+```
+
+
+By default with version npm 5.0+, `npm install` adds the module to the `dependencies` list in the `package.json` file; with earlier versions of npm, you must specify the `--save` option explicitly. Then, afterwards, running `npm install` in the app directory will automatically install modules in the dependencies list.
+
diff --git a/astro/src/content/docs/en/4x/starter/static-files.md b/astro/src/content/docs/en/4x/starter/static-files.md
new file mode 100755
index 0000000000..652de2690e
--- /dev/null
+++ b/astro/src/content/docs/en/4x/starter/static-files.md
@@ -0,0 +1,76 @@
+---
+title: Serving static files in Express
+description: Understand how to serve static files like images, CSS, and JavaScript in Express.js applications using the built-in 'static' middleware.
+---
+
+# Serving static files in Express
+
+To serve static files such as images, CSS files, and JavaScript files, use the `express.static` built-in middleware function in Express.
+
+The function signature is:
+
+```js
+express.static(root, [options]);
+```
+
+The `root` argument specifies the root directory from which to serve static assets.
+For more information on the `options` argument, see [express.static](/en/5x/api#express.static).
+
+For example, use the following code to serve images, CSS files, and JavaScript files in a directory named `public`:
+
+```js
+app.use(express.static('public'));
+```
+
+Now, you can load the files that are in the `public` directory:
+
+```text
+http://localhost:3000/images/kitten.jpg
+http://localhost:3000/css/style.css
+http://localhost:3000/js/app.js
+http://localhost:3000/images/bg.png
+http://localhost:3000/hello.html
+```
+
+
+Express looks up the files relative to the static directory, so the name of the static directory is not part of the URL.
+
+
+To use multiple static assets directories, call the `express.static` middleware function multiple times:
+
+```js
+app.use(express.static('public'));
+app.use(express.static('files'));
+```
+
+Express looks up the files in the order in which you set the static directories with the `express.static` middleware function.
+
+{% capture alert_content %}
+For best results, [use a reverse proxy](/en/advanced/best-practice-performance#use-a-reverse-proxy) cache to improve performance of serving static assets.
+{% endcapture %}
+{% include admonitions/note.html content=alert_content %}
+
+To create a virtual path prefix (where the path does not actually exist in the file system) for files that are served by the `express.static` function, [specify a mount path](/en/5x/api#app.use) for the static directory, as shown below:
+
+```js
+app.use('/static', express.static('public'));
+```
+
+Now, you can load the files that are in the `public` directory from the `/static` path prefix.
+
+```text
+http://localhost:3000/static/images/kitten.jpg
+http://localhost:3000/static/css/style.css
+http://localhost:3000/static/js/app.js
+http://localhost:3000/static/images/bg.png
+http://localhost:3000/static/hello.html
+```
+
+However, the path that you provide to the `express.static` function is relative to the directory from where you launch your `node` process. If you run the express app from another directory, it's safer to use the absolute path of the directory that you want to serve:
+
+```js
+const path = require('path');
+app.use('/static', express.static(path.join(__dirname, 'public')));
+```
+
+For more details about the `serve-static` function and its options, see [serve-static](/en/resources/middleware/serve-static).
diff --git a/astro/src/content/docs/en/5x/advanced/best-practice-performance.md b/astro/src/content/docs/en/5x/advanced/best-practice-performance.md
new file mode 100644
index 0000000000..74ee1b634e
--- /dev/null
+++ b/astro/src/content/docs/en/5x/advanced/best-practice-performance.md
@@ -0,0 +1,307 @@
+---
+title: Performance Best Practices Using Express in Production
+description: Discover performance and reliability best practices for Express apps in production, covering code optimizations and environment setups for optimal performance.
+---
+
+# Production best practices: performance and reliability
+
+This article discusses performance and reliability best practices for Express applications deployed to production.
+
+This topic clearly falls into the "devops" world, spanning both traditional development and operations. Accordingly, the information is divided into two parts:
+
+- Things to do in your code (the dev part):
+ - [Use gzip compression](#use-gzip-compression)
+ - [Don't use synchronous functions](#dont-use-synchronous-functions)
+ - [Do logging correctly](#do-logging-correctly)
+ - [Handle exceptions properly](#handle-exceptions-properly)
+- Things to do in your environment / setup (the ops part):
+ - [Set NODE_ENV to "production"](#set-node_env-to-production)
+ - [Ensure your app automatically restarts](#ensure-your-app-automatically-restarts)
+ - [Run your app in a cluster](#run-your-app-in-a-cluster)
+ - [Cache request results](#cache-request-results)
+ - [Use a load balancer](#use-a-load-balancer)
+ - [Use a reverse proxy](#use-a-reverse-proxy)
+
+## Things to do in your code {#in-code}
+
+Here are some things you can do in your code to improve your application's performance:
+
+- [Use gzip compression](#use-gzip-compression)
+- [Don't use synchronous functions](#dont-use-synchronous-functions)
+- [Do logging correctly](#do-logging-correctly)
+- [Handle exceptions properly](#handle-exceptions-properly)
+
+### Use gzip compression
+
+Gzip compressing can greatly decrease the size of the response body and hence increase the speed of a web app. Use the [compression](https://www.npmjs.com/package/compression) middleware for gzip compression in your Express app. For example:
+
+```js
+const compression = require('compression');
+const express = require('express');
+const app = express();
+
+app.use(compression());
+```
+
+For a high-traffic website in production, the best way to put compression in place is to implement it at a reverse proxy level (see [Use a reverse proxy](#use-a-reverse-proxy)). In that case, you do not need to use compression middleware. For details on enabling gzip compression in Nginx, see [Module ngx_http_gzip_module](http://nginx.org/en/docs/http/ngx_http_gzip_module) in the Nginx documentation.
+
+### Don't use synchronous functions
+
+Synchronous functions and methods tie up the executing process until they return. A single call to a synchronous function might return in a few microseconds or milliseconds, however in high-traffic websites, these calls add up and reduce the performance of the app. Avoid their use in production.
+
+Although Node and many modules provide synchronous and asynchronous versions of their functions, always use the asynchronous version in production. The only time when a synchronous function can be justified is upon initial startup.
+
+You can use the `--trace-sync-io` command-line flag to print a warning and a stack trace whenever your application uses a synchronous API. Of course, you wouldn't want to use this in production, but rather to ensure that your code is ready for production. See the [node command-line options documentation](https://nodejs.org/api/cli#cli_trace_sync_io) for more information.
+
+### Do logging correctly
+
+In general, there are two reasons for logging from your app: For debugging and for logging app activity (essentially, everything else). Using `console.log()` or `console.error()` to print log messages to the terminal is common practice in development. But [these functions are synchronous](https://nodejs.org/api/console#console) when the destination is a terminal or a file, so they are not suitable for production, unless you pipe the output to another program.
+
+#### For debugging
+
+If you're logging for purposes of debugging, then instead of using `console.log()`, use a special debugging module like [debug](https://www.npmjs.com/package/debug). This module enables you to use the DEBUG environment variable to control what debug messages are sent to `console.error()`, if any. To keep your app purely asynchronous, you'd still want to pipe `console.error()` to another program. But then, you're not really going to debug in production, are you?
+
+#### For app activity
+
+If you're logging app activity (for example, tracking traffic or API calls), instead of using `console.log()`, use a logging library like [Pino](https://www.npmjs.com/package/pino), which is the fastest and most efficient option available.
+
+### Handle exceptions properly
+
+Node apps crash when they encounter an uncaught exception. Not handling exceptions and taking appropriate actions will make your Express app crash and go offline. If you follow the advice in [Ensure your app automatically restarts](#ensure-your-app-automatically-restarts) below, then your app will recover from a crash. Fortunately, Express apps typically have a short startup time. Nevertheless, you want to avoid crashing in the first place, and to do that, you need to handle exceptions properly.
+
+To ensure you handle all exceptions, use the following techniques:
+
+- [Use try-catch](#use-try-catch)
+- [Use promises](#use-promises)
+
+Before diving into these topics, you should have a basic understanding of Node/Express error handling: using error-first callbacks, and propagating errors in middleware. Node uses an "error-first callback" convention for returning errors from asynchronous functions, where the first parameter to the callback function is the error object, followed by result data in succeeding parameters. To indicate no error, pass null as the first parameter. The callback function must correspondingly follow the error-first callback convention to meaningfully handle the error. And in Express, the best practice is to use the next() function to propagate errors through the middleware chain.
+
+For more on the fundamentals of error handling, see:
+
+- [Error Handling in Node.js](https://www.tritondatacenter.com/node-js/production/design/errors)
+
+#### Use try-catch
+
+Try-catch is a JavaScript language construct that you can use to catch exceptions in synchronous code. Use try-catch, for example, to handle JSON parsing errors as shown below.
+
+Here is an example of using try-catch to handle a potential process-crashing exception.
+This middleware function accepts a query field parameter named "params" that is a JSON object.
+
+```js
+app.get('/search', (req, res) => {
+ // Simulating async operation
+ setImmediate(() => {
+ const jsonStr = req.query.params;
+ try {
+ const jsonObj = JSON.parse(jsonStr);
+ res.send('Success');
+ } catch (e) {
+ res.status(400).send('Invalid JSON string');
+ }
+ });
+});
+```
+
+However, try-catch works only for synchronous code. Because the Node platform is primarily asynchronous (particularly in a production environment), try-catch won't catch a lot of exceptions.
+
+#### Use promises
+
+When an error is thrown in an `async` function or a rejected promise is awaited inside an `async` function, those errors will be passed to the error handler as if calling `next(err)`
+
+```js
+app.get('/', async (req, res, next) => {
+ const data = await userData(); // If this promise fails, it will automatically call `next(err)` to handle the error.
+
+ res.send(data);
+});
+
+app.use((err, req, res, next) => {
+ res.status(err.status ?? 500).send({ error: err.message });
+});
+```
+
+Also, you can use asynchronous functions for your middleware, and the router will handle errors if the promise fails, for example:
+
+```js
+app.use(async (req, res, next) => {
+ req.locals.user = await getUser(req);
+
+ next(); // This will be called if the promise does not throw an error.
+});
+```
+
+Best practice is to handle errors as close to the site as possible. So while this is now handled in the router, it’s best to catch the error in the middleware and handle it without relying on separate error-handling middleware.
+
+#### What not to do
+
+One thing you should _not_ do is to listen for the `uncaughtException` event, emitted when an exception bubbles all the way back to the event loop. Adding an event listener for `uncaughtException` will change the default behavior of the process that is encountering an exception; the process will continue to run despite the exception. This might sound like a good way of preventing your app from crashing, but continuing to run the app after an uncaught exception is a dangerous practice and is not recommended, because the state of the process becomes unreliable and unpredictable.
+
+Additionally, using `uncaughtException` is officially recognized as [crude](https://nodejs.org/api/process#process_event_uncaughtexception). So listening for `uncaughtException` is just a bad idea. This is why we recommend things like multiple processes and supervisors: crashing and restarting is often the most reliable way to recover from an error.
+
+We also don't recommend using [domains](https://nodejs.org/api/domain). It generally doesn't solve the problem and is a deprecated module.
+
+## Things to do in your environment / setup {#in-environment}
+
+Here are some things you can do in your system environment to improve your app's performance:
+
+- [Set NODE_ENV to "production"](#set-node_env-to-production)
+- [Ensure your app automatically restarts](#ensure-your-app-automatically-restarts)
+- [Run your app in a cluster](#run-your-app-in-a-cluster)
+- [Cache request results](#cache-request-results)
+- [Use a load balancer](#use-a-load-balancer)
+- [Use a reverse proxy](#use-a-reverse-proxy)
+
+### Set NODE_ENV to "production"
+
+The NODE_ENV environment variable specifies the environment in which an application is running (usually, development or production). One of the simplest things you can do to improve performance is to set NODE_ENV to `production`.
+
+Setting NODE_ENV to "production" makes Express:
+
+- Cache view templates.
+- Cache CSS files generated from CSS extensions.
+- Generate less verbose error messages.
+
+[Tests indicate](https://www.dynatrace.com/news/blog/the-drastic-effects-of-omitting-node-env-in-your-express-js-applications/) that just doing this can improve app performance by a factor of three!
+
+If you need to write environment-specific code, you can check the value of NODE_ENV with `process.env.NODE_ENV`. Be aware that checking the value of any environment variable incurs a performance penalty, and so should be done sparingly.
+
+In development, you typically set environment variables in your interactive shell, for example by using `export` or your `.bash_profile` file. But in general, you shouldn't do that on a production server; instead, use your OS's init system (systemd). The next section provides more details about using your init system in general, but setting `NODE_ENV` is so important for performance (and easy to do), that it's highlighted here.
+
+With systemd, use the `Environment` directive in your unit file. For example:
+
+```sh
+# /etc/systemd/system/myservice.service
+Environment=NODE_ENV=production
+```
+
+For more information, see [Using Environment Variables In systemd Units](https://www.flatcar.org/docs/latest/setup/systemd/environment-variables/).
+
+### Ensure your app automatically restarts
+
+In production, you don't want your application to be offline, ever. This means you need to make sure it restarts both if the app crashes and if the server itself crashes. Although you hope that neither of those events occurs, realistically you must account for both eventualities by:
+
+- Using a process manager to restart the app (and Node) when it crashes.
+- Using the init system provided by your OS to restart the process manager when the OS crashes. It's also possible to use the init system without a process manager.
+
+Node applications crash if they encounter an uncaught exception. The foremost thing you need to do is to ensure your app is well-tested and handles all exceptions (see [handle exceptions properly](#handle-exceptions-properly) for details). But as a fail-safe, put a mechanism in place to ensure that if and when your app crashes, it will automatically restart.
+
+#### Use a process manager
+
+In development, you started your app simply from the command line with `node server.js` or something similar. But doing this in production is a recipe for disaster. If the app crashes, it will be offline until you restart it. To ensure your app restarts if it crashes, use a process manager. A process manager is a "container" for applications that facilitates deployment, provides high availability, and enables you to manage the application at runtime.
+
+In addition to restarting your app when it crashes, a process manager can enable you to:
+
+- Gain insights into runtime performance and resource consumption.
+- Modify settings dynamically to improve performance.
+- Control clustering (pm2).
+
+Historically, it was popular to use a Node.js process manager like [PM2](https://github.com/Unitech/pm2). See their documentation if you wish to do this. However, we recommend using your init system for process management.
+
+#### Use an init system
+
+The next layer of reliability is to ensure that your app restarts when the server restarts. Systems can still go down for a variety of reasons. To ensure that your app restarts if the server crashes, use the init system built into your OS. The main init system in use today is [systemd](https://wiki.debian.org/systemd).
+
+There are two ways to use init systems with your Express app:
+
+- Run your app in a process manager, and install the process manager as a service with the init system. The process manager will restart your app when the app crashes, and the init system will restart the process manager when the OS restarts. This is the recommended approach.
+- Run your app (and Node) directly with the init system. This is somewhat simpler, but you don't get the additional advantages of using a process manager.
+
+##### Systemd
+
+Systemd is a Linux system and service manager. Most major Linux distributions have adopted systemd as their default init system.
+
+A systemd service configuration file is called a _unit file_, with a filename ending in `.service`. Here's an example unit file to manage a Node app directly. Replace the values enclosed in `` for your system and app:
+
+```sh
+[Unit]
+Description=
+
+[Service]
+Type=simple
+ExecStart=/usr/local/bin/node
+WorkingDirectory=
+
+User=nobody
+Group=nogroup
+
+# Environment variables:
+Environment=NODE_ENV=production
+
+# Allow many incoming connections
+LimitNOFILE=infinity
+
+# Allow core dumps for debugging
+LimitCORE=infinity
+
+StandardInput=null
+StandardOutput=syslog
+StandardError=syslog
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
+```
+
+For more information on systemd, see the [systemd reference (man page)](http://www.freedesktop.org/software/systemd/man/systemd.unit).
+
+### Run your app in a cluster
+
+In a multi-core system, you can increase the performance of a Node app by many times by launching a cluster of processes. A cluster runs multiple instances of the app, ideally one instance on each CPU core, thereby distributing the load and tasks among the instances.
+
+
+
+IMPORTANT: Since the app instances run as separate processes, they do not share the same memory space. That is, objects are local to each instance of the app. Therefore, you cannot maintain state in the application code. However, you can use an in-memory datastore like [Redis](http://redis.io/) to store session-related data and state. This caveat applies to essentially all forms of horizontal scaling, whether clustering with multiple processes or multiple physical servers.
+
+In clustered apps, worker processes can crash individually without affecting the rest of the processes. Apart from performance advantages, failure isolation is another reason to run a cluster of app processes. Whenever a worker process crashes, always make sure to log the event and spawn a new process using cluster.fork().
+
+#### Using Node's cluster module
+
+Clustering is made possible with Node's [cluster module](https://nodejs.org/api/cluster). This enables a master process to spawn worker processes and distribute incoming connections among the workers.
+
+#### Using PM2
+
+If you deploy your application with PM2, then you can take advantage of clustering _without_ modifying your application code. You should ensure your [application is stateless](https://pm2.keymetrics.io/docs/usage/specifics/#stateless-apps) first, meaning no local data is stored in the process (such as sessions, websocket connections and the like).
+
+When running an application with PM2, you can enable **cluster mode** to run it in a cluster with a number of instances of your choosing, such as the matching the number of available CPUs on the machine. You can manually change the number of processes in the cluster using the `pm2` command line tool without stopping the app.
+
+To enable cluster mode, start your application like so:
+
+```bash
+# Start 4 worker processes
+$ pm2 start npm --name my-app -i 4 -- start
+# Auto-detect number of available CPUs and start that many worker processes
+$ pm2 start npm --name my-app -i max -- start
+```
+
+This can also be configured within a PM2 process file (`ecosystem.config.js` or similar) by setting `exec_mode` to `cluster` and `instances` to the number of workers to start.
+
+Once running, the application can be scaled like so:
+
+```bash
+# Add 3 more workers
+$ pm2 scale my-app +3
+# Scale to a specific number of workers
+$ pm2 scale my-app 2
+```
+
+For more information on clustering with PM2, see [Cluster Mode](https://pm2.keymetrics.io/docs/usage/cluster-mode/) in the PM2 documentation.
+
+### Cache request results
+
+Another strategy to improve the performance in production is to cache the result of requests, so that your app does not repeat the operation to serve the same request repeatedly.
+
+Use a caching server like [Varnish](https://www.varnish-cache.org/) or [Nginx](https://blog.nginx.org/blog/nginx-caching-guide) (see also [Nginx Caching](https://serversforhackers.com/nginx-caching/)) to greatly improve the speed and performance of your app.
+
+### Use a load balancer
+
+No matter how optimized an app is, a single instance can handle only a limited amount of load and traffic. One way to scale an app is to run multiple instances of it and distribute the traffic via a load balancer. Setting up a load balancer can improve your app's performance and speed, and enable it to scale more than is possible with a single instance.
+
+A load balancer is usually a reverse proxy that orchestrates traffic to and from multiple application instances and servers. You can easily set up a load balancer for your app by using [Nginx](https://nginx.org/en/docs/http/load_balancing) or [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts).
+
+With load balancing, you might have to ensure that requests that are associated with a particular session ID connect to the process that originated them. This is known as _session affinity_, or _sticky sessions_, and may be addressed by the suggestion above to use a data store such as Redis for session data (depending on your application). For a discussion, see [Using multiple nodes](https://socket.io/docs/v4/using-multiple-nodes/).
+
+### Use a reverse proxy
+
+A reverse proxy sits in front of a web app and performs supporting operations on the requests, apart from directing requests to the app. It can handle error pages, compression, caching, serving files, and load balancing among other things.
+
+Handing over tasks that do not require knowledge of application state to a reverse proxy frees up Express to perform specialized application tasks. For this reason, it is recommended to run Express behind a reverse proxy like [Nginx](https://www.nginx.org/) or [HAProxy](https://www.haproxy.org/) in production.
diff --git a/astro/src/content/docs/en/5x/advanced/best-practice-security.md b/astro/src/content/docs/en/5x/advanced/best-practice-security.md
new file mode 100644
index 0000000000..1341252dad
--- /dev/null
+++ b/astro/src/content/docs/en/5x/advanced/best-practice-security.md
@@ -0,0 +1,283 @@
+---
+title: Security Best Practices for Express in Production
+description: Discover crucial security best practices for Express apps in production, including using TLS, input validation, secure cookies, and preventing vulnerabilities.
+---
+
+# Production Best Practices: Security
+
+## Overview
+
+The term _"production"_ refers to the stage in the software lifecycle when an application or API is generally available to its end-users or consumers. In contrast, in the _"development"_ stage, you're still actively writing and testing code, and the application is not open to external access. The corresponding system environments are known as _production_ and _development_ environments, respectively.
+
+Development and production environments are usually set up differently and have vastly different requirements. What's fine in development may not be acceptable in production. For example, in a development environment you may want verbose logging of errors for debugging, while the same behavior can become a security concern in a production environment. And in development, you don't need to worry about scalability, reliability, and performance, while those concerns become critical in production.
+
+{% capture security-note %}
+
+If you believe you have discovered a security vulnerability in Express, please see
+[Security Policies and Procedures](/en/resources/contributing#security-policies-and-procedures).
+
+{% endcapture %}
+
+{% include admonitions/note.html content=security-note %}
+
+Security best practices for Express applications in production include:
+
+- [Production Best Practices: Security](#production-best-practices-security)
+ - [Overview](#overview)
+ - [Don't use deprecated or vulnerable versions of Express](#dont-use-deprecated-or-vulnerable-versions-of-express)
+ - [Use TLS](#use-tls)
+ - [Do not trust user input](#do-not-trust-user-input)
+ - [Prevent open redirects](#prevent-open-redirects)
+ - [Use Helmet](#use-helmet)
+ - [Reduce fingerprinting](#reduce-fingerprinting)
+ - [Use cookies securely](#use-cookies-securely)
+ - [Don't use the default session cookie name](#dont-use-the-default-session-cookie-name)
+ - [Set cookie security options](#set-cookie-security-options)
+ - [Prevent brute-force attacks against authorization](#prevent-brute-force-attacks-against-authorization)
+ - [Ensure your dependencies are secure](#ensure-your-dependencies-are-secure)
+ - [Avoid other known vulnerabilities](#avoid-other-known-vulnerabilities)
+ - [Additional considerations](#additional-considerations)
+
+## Don't use deprecated or vulnerable versions of Express
+
+Express 2.x and 3.x are no longer maintained. Security and performance issues in these versions won't be fixed. Do not use them! If you haven't moved to version 4, follow the [migration guide](/en/guide/migrating-4) or consider [Commercial Support Options](/en/support#commercial-support-options).
+
+Also ensure you are not using any of the vulnerable Express versions listed on the [Security updates page](/en/advanced/security-updates). If you are, update to one of the stable releases, preferably the latest.
+
+## Use TLS
+
+If your app deals with or transmits sensitive data, use [Transport Layer Security](https://en.wikipedia.org/wiki/Transport_Layer_Security) (TLS) to secure the connection and the data. This technology encrypts data before it is sent from the client to the server, thus preventing some common (and easy) hacks. Although Ajax and POST requests might not be visibly obvious and seem "hidden" in browsers, their network traffic is vulnerable to [packet sniffing](https://en.wikipedia.org/wiki/Packet_analyzer) and [man-in-the-middle attacks](https://en.wikipedia.org/wiki/Man-in-the-middle_attack).
+
+You may be familiar with Secure Socket Layer (SSL) encryption. [TLS is simply the next progression of SSL](). In other words, if you were using SSL before, consider upgrading to TLS. In general, we recommend Nginx to handle TLS. For a good reference to configure TLS on Nginx (and other servers), see [Recommended Server Configurations (Mozilla Wiki)](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations).
+
+Also, a handy tool to get a free TLS certificate is [Let's Encrypt](https://letsencrypt.org/about/), a free, automated, and open certificate authority (CA) provided by the [Internet Security Research Group (ISRG)](https://www.abetterinternet.org/).
+
+## Do not trust user input
+
+For web applications, one of the most critical security requirements is proper user input validation and handling. This comes in many forms and we will not cover all of them here.
+Ultimately, the responsibility for validating and correctly handling the types of user input your application accepts is yours.
+
+### Prevent open redirects
+
+An example of potentially dangerous user input is an _open redirect_, where an application accepts a URL as user input (often in the URL query, for example `?url=https://example.com`) and uses `res.redirect` to set the `location` header and
+return a 3xx status.
+
+An application must validate that it supports redirecting to the incoming URL to avoid sending users to malicious links such as phishing websites, among other risks.
+
+Here is an example of checking URLs before using `res.redirect` or `res.location`:
+
+```js
+app.use((req, res) => {
+ try {
+ if (new Url(req.query.url).host !== 'example.com') {
+ return res.status(400).end(`Unsupported redirect to host: ${req.query.url}`);
+ }
+ } catch (e) {
+ return res.status(400).end(`Invalid url: ${req.query.url}`);
+ }
+ res.redirect(req.query.url);
+});
+```
+
+## Use Helmet
+
+[Helmet][helmet] can help protect your app from some well-known web vulnerabilities by setting HTTP headers appropriately.
+
+Helmet is a middleware function that sets security-related HTTP response headers. Helmet sets the following headers by default:
+
+- `Content-Security-Policy`: A powerful allow-list of what can happen on your page which mitigates many attacks
+- `Cross-Origin-Opener-Policy`: Helps process-isolate your page
+- `Cross-Origin-Resource-Policy`: Blocks others from loading your resources cross-origin
+- `Origin-Agent-Cluster`: Changes process isolation to be origin-based
+- `Referrer-Policy`: Controls the [`Referer`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) header
+- `Strict-Transport-Security`: Tells browsers to prefer HTTPS
+- `X-Content-Type-Options`: Avoids [MIME sniffing](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing)
+- `X-DNS-Prefetch-Control`: Controls DNS prefetching
+- `X-Download-Options`: Forces downloads to be saved (Internet Explorer only)
+- `X-Frame-Options`: Legacy header that mitigates [Clickjacking](https://en.wikipedia.org/wiki/Clickjacking) attacks
+- `X-Permitted-Cross-Domain-Policies`: Controls cross-domain behavior for Adobe products, like Acrobat
+- `X-Powered-By`: Info about the web server. Removed because it could be used in simple attacks
+- `X-XSS-Protection`: Legacy header that tries to mitigate [XSS attacks](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting), but makes things worse, so Helmet disables it
+
+Each header can be configured or disabled. To read more about it please go to [its documentation website][helmet].
+
+Install Helmet like any other module:
+
+```bash
+$ npm install helmet
+```
+
+Then to use it in your code:
+
+```js
+// ...
+
+const helmet = require('helmet');
+app.use(helmet());
+
+// ...
+```
+
+## Reduce fingerprinting
+
+It can help to provide an extra layer of security to reduce the ability of attackers to determine
+the software that a server uses, known as "fingerprinting." Though not a security issue itself,
+reducing the ability to fingerprint an application improves its overall security posture.
+Server software can be fingerprinted by quirks in how it responds to specific requests, for example in
+the HTTP response headers.
+
+By default, Express sends the `X-Powered-By` response header that you can
+disable using the `app.disable()` method:
+
+```js
+app.disable('x-powered-by');
+```
+
+{% capture powered-advisory %}
+
+Disabling the `X-Powered-By header` does not prevent
+a sophisticated attacker from determining that an app is running Express. It may
+discourage a casual exploit, but there are other ways to determine an app is running
+Express.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=powered-advisory %}
+
+Express also sends its own formatted "404 Not Found" messages and formatter error
+response messages. These can be changed by
+[adding your own not found handler](/en/starter/faq#how-do-i-handle-404-responses)
+and
+[writing your own error handler](/en/guide/error-handling#writing-error-handlers):
+
+```js
+// last app.use calls right before app.listen():
+
+// custom 404
+app.use((req, res, next) => {
+ res.status(404).send("Sorry can't find that!");
+});
+
+// custom error handler
+app.use((err, req, res, next) => {
+ console.error(err.stack);
+ res.status(500).send('Something broke!');
+});
+```
+
+## Use cookies securely
+
+To ensure cookies don't open your app to exploits, don't use the default session cookie name and set cookie security options appropriately.
+
+There are two main middleware cookie session modules:
+
+- [express-session](https://www.npmjs.com/package/express-session) that replaces `express.session` middleware built-in to Express 3.x.
+- [cookie-session](https://www.npmjs.com/package/cookie-session) that replaces `express.cookieSession` middleware built-in to Express 3.x.
+
+The main difference between these two modules is how they save cookie session data. The [express-session](https://www.npmjs.com/package/express-session) middleware stores session data on the server; it only saves the session ID in the cookie itself, not session data. By default, it uses in-memory storage and is not designed for a production environment. In production, you'll need to set up a scalable session-store; see the list of [compatible session stores](https://github.com/expressjs/session#compatible-session-stores).
+
+In contrast, [cookie-session](https://www.npmjs.com/package/cookie-session) middleware implements cookie-backed storage: it serializes the entire session to the cookie, rather than just a session key. Only use it when session data is relatively small and easily encoded as primitive values (rather than objects). Although browsers are supposed to support at least 4096 bytes per cookie, to ensure you don't exceed the limit, don't exceed a size of 4093 bytes per domain. Also, be aware that the cookie data will be visible to the client, so if there is any reason to keep it secure or obscure, then `express-session` may be a better choice.
+
+### Don't use the default session cookie name
+
+Using the default session cookie name can open your app to attacks. The security issue posed is similar to `X-Powered-By`: a potential attacker can use it to fingerprint the server and target attacks accordingly.
+
+To avoid this problem, use generic cookie names; for example using [express-session](https://www.npmjs.com/package/express-session) middleware:
+
+```js
+const session = require('express-session');
+app.set('trust proxy', 1); // trust first proxy
+app.use(
+ session({
+ secret: 's3Cur3',
+ name: 'sessionId',
+ })
+);
+```
+
+### Set cookie security options
+
+Set the following cookie options to enhance security:
+
+- `secure` - Ensures the browser only sends the cookie over HTTPS.
+- `httpOnly` - Ensures the cookie is sent only over HTTP(S), not client JavaScript, helping to protect against cross-site scripting attacks.
+- `domain` - indicates the domain of the cookie; use it to compare against the domain of the server in which the URL is being requested. If they match, then check the path attribute next.
+- `path` - indicates the path of the cookie; use it to compare against the request path. If this and domain match, then send the cookie in the request.
+- `expires` - use to set expiration date for persistent cookies.
+
+Here is an example using [cookie-session](https://www.npmjs.com/package/cookie-session) middleware:
+
+```js
+const session = require('cookie-session');
+const express = require('express');
+const app = express();
+
+const expiryDate = new Date(Date.now() + 60 * 60 * 1000); // 1 hour
+app.use(
+ session({
+ name: 'session',
+ keys: ['key1', 'key2'],
+ cookie: {
+ secure: true,
+ httpOnly: true,
+ domain: 'example.com',
+ path: 'foo/bar',
+ expires: expiryDate,
+ },
+ })
+);
+```
+
+## Prevent brute-force attacks against authorization
+
+Make sure login endpoints are protected to make private data more secure.
+
+A simple and powerful technique is to block authorization attempts using two metrics:
+
+1. The number of consecutive failed attempts by the same user name and IP address.
+1. The number of failed attempts from an IP address over some long period of time. For example, block an IP address if it makes 100 failed attempts in one day.
+
+[rate-limiter-flexible](https://github.com/animir/node-rate-limiter-flexible) package provides tools to make this technique easy and fast. You can find [an example of brute-force protection in the documentation](https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#login-endpoint-protection)
+
+## Ensure your dependencies are secure
+
+Using npm to manage your application's dependencies is powerful and convenient. But the packages that you use may contain critical security vulnerabilities that could also affect your application. The security of your app is only as strong as the "weakest link" in your dependencies.
+
+Since npm@6, npm automatically reviews every install request. Also, you can use `npm audit` to analyze your dependency tree.
+
+```bash
+$ npm audit
+```
+
+If you want to stay more secure, consider [Snyk](https://snyk.io/).
+
+Snyk offers both a [command-line tool](https://www.npmjs.com/package/snyk) and a [Github integration](https://snyk.io/docs/github) that checks your application against [Snyk's open source vulnerability database](https://snyk.io/vuln/) for any known vulnerabilities in your dependencies. Install the CLI as follows:
+
+```bash
+$ npm install -g snyk
+$ cd your-app
+```
+
+Use this command to test your application for vulnerabilities:
+
+```bash
+$ snyk test
+```
+
+### Avoid other known vulnerabilities
+
+Keep an eye out for [Node Security Project](https://npmjs.com/advisories) or [Snyk](https://snyk.io/vuln/) advisories that may affect Express or other modules that your app uses. In general, these databases are excellent resources for knowledge and tools about Node security.
+
+Finally, Express apps—like any other web apps—can be vulnerable to a variety of web-based attacks. Familiarize yourself with known [web vulnerabilities](https://www.owasp.org/www-project-top-ten/) and take precautions to avoid them.
+
+## Additional considerations
+
+Here are some further recommendations from the excellent [Node.js Security Checklist](https://blog.risingstack.com/node-js-security-checklist/). Refer to that blog post for all the details on these recommendations:
+
+- Always filter and sanitize user input to protect against cross-site scripting (XSS) and command injection attacks.
+- Defend against SQL injection attacks by using parameterized queries or prepared statements.
+- Use the open-source [sqlmap](http://sqlmap.org/) tool to detect SQL injection vulnerabilities in your app.
+- Use the [nmap](https://nmap.org/) and [sslyze](https://github.com/nabla-c0d3/sslyze) tools to test the configuration of your SSL ciphers, keys, and renegotiation as well as the validity of your certificate.
+- Use [safe-regex](https://www.npmjs.com/package/safe-regex) to ensure your regular expressions are not susceptible to [regular expression denial of service](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS) attacks.
+
+[helmet]: https://helmetjs.github.io/
diff --git a/astro/src/content/docs/en/5x/advanced/developing-template-engines.md b/astro/src/content/docs/en/5x/advanced/developing-template-engines.md
new file mode 100755
index 0000000000..80e28ba8c9
--- /dev/null
+++ b/astro/src/content/docs/en/5x/advanced/developing-template-engines.md
@@ -0,0 +1,45 @@
+---
+title: Developing template engines for Express
+description: Learn how to develop custom template engines for Express.js using app.engine(), with examples on creating and integrating your own template rendering logic.
+---
+
+# Developing template engines for Express
+
+Use the `app.engine(ext, callback)` method to create your own template engine. `ext` refers to the file extension, and `callback` is the template engine function, which accepts the following items as parameters: the location of the file, the options object, and the callback function.
+
+The following code is an example of implementing a very simple template engine for rendering `.ntl` files.
+
+```js
+const fs = require('fs'); // this engine requires the fs module
+app.engine('ntl', (filePath, options, callback) => {
+ // define the template engine
+ fs.readFile(filePath, (err, content) => {
+ if (err) return callback(err);
+ // this is an extremely simple template engine
+ const rendered = content
+ .toString()
+ .replace('#title#', `${options.title} `)
+ .replace('#message#', `${options.message} `);
+ return callback(null, rendered);
+ });
+});
+app.set('views', './views'); // specify the views directory
+app.set('view engine', 'ntl'); // register the template engine
+```
+
+Your app will now be able to render `.ntl` files. Create a file named `index.ntl` in the `views` directory with the following content.
+
+```pug
+#title#
+#message#
+```
+
+Then, create the following route in your app.
+
+```js
+app.get('/', (req, res) => {
+ res.render('index', { title: 'Hey', message: 'Hello there!' });
+});
+```
+
+When you make a request to the home page, `index.ntl` will be rendered as HTML.
diff --git a/astro/src/content/docs/en/5x/advanced/healthcheck-graceful-shutdown.md b/astro/src/content/docs/en/5x/advanced/healthcheck-graceful-shutdown.md
new file mode 100644
index 0000000000..1018345076
--- /dev/null
+++ b/astro/src/content/docs/en/5x/advanced/healthcheck-graceful-shutdown.md
@@ -0,0 +1,30 @@
+---
+title: Health Checks and Graceful Shutdown
+description: Learn how to implement health checks and graceful shutdown in Express apps to enhance reliability, manage deployments, and integrate with load balancers like Kubernetes.
+---
+
+# Health Checks and Graceful Shutdown
+
+## Graceful shutdown
+
+When you deploy a new version of your application, you must replace the previous version. The process manager you're using will first send a SIGTERM signal to the application to notify it that it will be killed. Once the application gets this signal, it should stop accepting new requests, finish all the ongoing requests, clean up the resources it used, including database connections and file locks then exit.
+
+### Example
+
+```js
+const server = app.listen(port);
+
+process.on('SIGTERM', () => {
+ debug('SIGTERM signal received: closing HTTP server');
+ server.close(() => {
+ debug('HTTP server closed');
+ });
+});
+```
+
+## Health checks
+
+A load balancer uses health checks to determine if an application instance is healthy and can accept requests. For example, [Kubernetes has two health checks](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/):
+
+- `liveness`, that determines when to restart a container.
+- `readiness`, that determines when a container is ready to start accepting traffic. When a pod is not ready, it is removed from the service load balancers.
diff --git a/astro/src/content/docs/en/5x/advanced/security-updates.md b/astro/src/content/docs/en/5x/advanced/security-updates.md
new file mode 100755
index 0000000000..72d02e161c
--- /dev/null
+++ b/astro/src/content/docs/en/5x/advanced/security-updates.md
@@ -0,0 +1,83 @@
+---
+title: Express security updates
+description: Review the latest security updates and patches for Express.js, including detailed vulnerability lists for different versions to help maintain a secure application.
+---
+
+# Security updates
+
+
+Node.js vulnerabilities directly affect Express. Therefore, [keep a watch on Node.js vulnerabilities](https://nodejs.org/en/blog/vulnerability/) and make sure you are using the latest stable version of Node.js.
+
+
+The list below enumerates the Express vulnerabilities that were fixed in the specified version update.
+
+{% capture security-policy %}
+If you believe you have discovered a security vulnerability in Express, please see
+[Security Policies and Procedures](/en/resources/contributing#security-policies-and-procedures).
+{% endcapture %}
+
+{% include admonitions/note.html content=security-policy %}
+
+## 4.x
+
+- 4.21.2
+ - The dependency `path-to-regexp` has been updated to address a [vulnerability](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-rhx6-c78j-4q9w).
+- 4.21.1
+ - The dependency `cookie` has been updated to address a [vulnerability](https://github.com/jshttp/cookie/security/advisories/GHSA-pxg6-pf52-xh8x), This may affect your application if you use `res.cookie`.
+- 4.20.0
+ - Fixed XSS vulnerability in `res.redirect` ([advisory](https://github.com/expressjs/express/security/advisories/GHSA-qw6h-vgh9-j6wx), [CVE-2024-43796](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-43796)).
+ - The dependency `serve-static` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-cm22-4g7w-348p).
+ - The dependency `send` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-m6fv-jmcg-4jfg).
+ - The dependency `path-to-regexp` has been updated to address a [vulnerability](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-9wv6-86v2-598j).
+ - The dependency `body-parser` has been updated to addres a [vulnerability](https://github.com/advisories/GHSA-qwcr-r2fm-qrc7), This may affect your application if you had url enconding activated.
+- 4.19.0, 4.19.1
+ - Fixed open redirect vulnerability in `res.location` and `res.redirect` ([advisory](https://github.com/expressjs/express/security/advisories/GHSA-rv95-896h-c2vc), [CVE-2024-29041](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-29041)).
+- 4.17.3
+ - The dependency `qs` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-hrpp-h998-j3pp). This may affect your application if the following APIs are used: `req.query`, `req.body`, `req.param`.
+- 4.16.0
+ - The dependency `forwarded` has been updated to address a [vulnerability](https://npmjs.com/advisories/527). This may affect your application if the following APIs are used: `req.host`, `req.hostname`, `req.ip`, `req.ips`, `req.protocol`.
+ - The dependency `mime` has been updated to address a [vulnerability](https://npmjs.com/advisories/535), but this issue does not impact Express.
+ - The dependency `send` has been updated to provide a protection against a [Node.js 8.5.0 vulnerability](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/). This only impacts running Express on the specific Node.js version 8.5.0.
+- 4.15.5
+ - The dependency `debug` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:debug:20170905), but this issue does not impact Express.
+ - The dependency `fresh` has been updated to address a [vulnerability](https://npmjs.com/advisories/526). This will affect your application if the following APIs are used: `express.static`, `req.fresh`, `res.json`, `res.jsonp`, `res.send`, `res.sendfile` `res.sendFile`, `res.sendStatus`.
+- 4.15.3
+ - The dependency `ms` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:ms:20170412). This may affect your application if untrusted string input is passed to the `maxAge` option in the following APIs: `express.static`, `res.sendfile`, and `res.sendFile`.
+- 4.15.2
+ - The dependency `qs` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:qs:20170213), but this issue does not impact Express. Updating to 4.15.2 is a good practice, but not required to address the vulnerability.
+- 4.11.1
+ - Fixed root path disclosure vulnerability in `express.static`, `res.sendfile`, and `res.sendFile`
+- 4.10.7
+ - Fixed open redirect vulnerability in `express.static` ([advisory](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)).
+- 4.8.8
+ - Fixed directory traversal vulnerabilities in `express.static` ([advisory](http://npmjs.com/advisories/32) , [CVE-2014-6394](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6394)).
+- 4.8.4
+ - Node.js 0.10 can leak `fd`s in certain situations that affect `express.static` and `res.sendfile`. Malicious requests could cause `fd`s to leak and eventually lead to `EMFILE` errors and server unresponsiveness.
+- 4.8.0
+ - Sparse arrays that have extremely high indexes in the query string could cause the process to run out of memory and crash the server.
+ - Extremely nested query string objects could cause the process to block and make the server unresponsive temporarily.
+
+## 3.x
+
+
+ **Express 3.x IS END-OF-LIFE AND NO LONGER MAINTAINED**
+
+Known and unknown security and performance issues in 3.x have not been addressed since the last update (1 August, 2015). It is highly recommended to use the latest version of Express.
+
+If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/en/support#commercial-support-options).
+
+
+
+- 3.19.1
+ - Fixed root path disclosure vulnerability in `express.static`, `res.sendfile`, and `res.sendFile`
+- 3.19.0
+ - Fixed open redirect vulnerability in `express.static` ([advisory](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)).
+- 3.16.10
+ - Fixed directory traversal vulnerabilities in `express.static`.
+- 3.16.6
+ - Node.js 0.10 can leak `fd`s in certain situations that affect `express.static` and `res.sendfile`. Malicious requests could cause `fd`s to leak and eventually lead to `EMFILE` errors and server unresponsiveness.
+- 3.16.0
+ - Sparse arrays that have extremely high indexes in query string could cause the process to run out of memory and crash the server.
+ - Extremely nested query string objects could cause the process to block and make the server unresponsive temporarily.
+- 3.3.0
+ - The 404 response of an unsupported method override attempt was susceptible to cross-site scripting attacks.
diff --git a/astro/src/content/docs/en/5x/api.md b/astro/src/content/docs/en/5x/api.md
new file mode 100644
index 0000000000..d0c66d19c3
--- /dev/null
+++ b/astro/src/content/docs/en/5x/api.md
@@ -0,0 +1,8 @@
+---
+title: 5x API Reference
+description: API Reference for version 5.x
+---
+
+# 5.x API
+
+Some content here...
diff --git a/astro/src/content/docs/en/5x/guide/behind-proxies.md b/astro/src/content/docs/en/5x/guide/behind-proxies.md
new file mode 100755
index 0000000000..7c217b3e2a
--- /dev/null
+++ b/astro/src/content/docs/en/5x/guide/behind-proxies.md
@@ -0,0 +1,92 @@
+---
+title: Express behind proxies
+description: Learn how to configure Express.js applications to work correctly behind reverse proxies, including using the trust proxy setting to handle client IP addresses.
+---
+
+# Express behind proxies
+
+When running an Express app behind a reverse proxy, some of the Express APIs may return different values than expected. In order to adjust for this, the `trust proxy` application setting may be used to expose information provided by the reverse proxy in the Express APIs. The most common issue is express APIs that expose the client's IP address may instead show an internal IP address of the reverse proxy.
+
+
+When configuring the `trust proxy` setting, it is important to understand the exact setup of the reverse proxy. Since this setting will trust values provided in the request, it is important that the combination of the setting in Express matches how the reverse proxy operates.
+
+
+The application setting `trust proxy` may be set to one of the values listed in the following table.
+
+
+ Type Value
+
+
+ Boolean
+
+If `true`, the client's IP address is understood as the left-most entry in the `X-Forwarded-For` header.
+
+If `false`, the app is understood as directly facing the client and the client's IP address is derived from `req.socket.remoteAddress`. This is the default setting.
+
+
+When setting to `true`, it is important to ensure that the last reverse proxy trusted is removing/overwriting all of the following HTTP headers: `X-Forwarded-For`, `X-Forwarded-Host`, and `X-Forwarded-Proto`, otherwise it may be possible for the client to provide any value.
+
+
+
+
+ IP addresses
+
+An IP address, subnet, or an array of IP addresses and subnets to trust as being a reverse proxy. The following list shows the pre-configured subnet names:
+
+- loopback - `127.0.0.1/8`, `::1/128`
+- linklocal - `169.254.0.0/16`, `fe80::/10`
+- uniquelocal - `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7`
+
+You can set IP addresses in any of the following ways:
+
+```js
+app.set('trust proxy', 'loopback'); // specify a single subnet
+app.set('trust proxy', 'loopback, 123.123.123.123'); // specify a subnet and an address
+app.set('trust proxy', 'loopback, linklocal, uniquelocal'); // specify multiple subnets as CSV
+app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']); // specify multiple subnets as an array
+```
+
+When specified, the IP addresses or the subnets are excluded from the address determination process, and the untrusted IP address nearest to the application server is determined as the client's IP address. This works by checking if `req.socket.remoteAddress` is trusted. If so, then each address in `X-Forwarded-For` is checked from right to left until the first non-trusted address.
+
+
+
+
+ Number
+
+Use the address that is at most `n` number of hops away from the Express application. `req.socket.remoteAddress` is the first hop, and the rest are looked for in the `X-Forwarded-For` header from right to left. A value of `0` means that the first untrusted address would be `req.socket.remoteAddress`, i.e. there is no reverse proxy.
+
+
+When using this setting, it is important to ensure there are not multiple, different-length paths to the Express application such that the client can be less than the configured number of hops away, otherwise it may be possible for the client to provide any value.
+
+
+
+
+ Function
+
+Custom trust implementation.
+
+```js
+app.set('trust proxy', (ip) => {
+ if (ip === '127.0.0.1' || ip === '123.123.123.123')
+ return true; // trusted IPs
+ else return false;
+});
+```
+
+
+
+
+
+
+Enabling `trust proxy` will have the following impact:
+
+
+ The value of [req.hostname](/en/api#req.hostname) is derived from the value set in the `X-Forwarded-Host` header, which can be set by the client or by the proxy.
+
+ `X-Forwarded-Proto` can be set by the reverse proxy to tell the app whether it is `https` or `http` or even an invalid name. This value is reflected by [req.protocol](/en/api#req.protocol).
+
+ The [req.ip](/en/api#req.ip) and [req.ips](/en/api#req.ips) values are populated based on the socket address and `X-Forwarded-For` header, starting at the first untrusted address.
+
+
+
+The `trust proxy` setting is implemented using the [proxy-addr](https://www.npmjs.com/package/proxy-addr) package. For more information, see its documentation.
diff --git a/astro/src/content/docs/en/5x/guide/database-integration.md b/astro/src/content/docs/en/5x/guide/database-integration.md
new file mode 100644
index 0000000000..3c653355ad
--- /dev/null
+++ b/astro/src/content/docs/en/5x/guide/database-integration.md
@@ -0,0 +1,501 @@
+---
+title: Express database integration
+description: Discover how to integrate various databases with Express.js applications, including setup examples for MongoDB, MySQL, PostgreSQL, and more.
+---
+
+# Database integration
+
+Adding the capability to connect databases to Express apps is just a matter of loading an appropriate Node.js driver for the database in your app. This document briefly explains how to add and use some of the most popular Node.js modules for database systems in your Express app:
+
+- [Cassandra](#cassandra)
+- [Couchbase](#couchbase)
+- [CouchDB](#couchdb)
+- [LevelDB](#leveldb)
+- [MySQL](#mysql)
+- [MongoDB](#mongodb)
+- [Neo4j](#neo4j)
+- [Oracle](#oracle)
+- [PostgreSQL](#postgresql)
+- [Redis](#redis)
+- [SQL Server](#sql-server)
+- [SQLite](#sqlite)
+- [Elasticsearch](#elasticsearch)
+
+
+These database drivers are among many that are available. For other options,
+search on the [npm](https://www.npmjs.com/) site.
+
+
+## Cassandra
+
+**Module**: [cassandra-driver](https://github.com/datastax/nodejs-driver)
+
+### Installation
+
+```bash
+$ npm install cassandra-driver
+```
+
+### Example
+
+```js
+const cassandra = require('cassandra-driver');
+const client = new cassandra.Client({ contactPoints: ['localhost'] });
+
+client.execute('select key from system.local', (err, result) => {
+ if (err) throw err;
+ console.log(result.rows[0]);
+});
+```
+
+## Couchbase
+
+**Module**: [couchnode](https://github.com/couchbase/couchnode)
+
+### Installation
+
+```bash
+$ npm install couchbase
+```
+
+### Example
+
+```js
+const couchbase = require('couchbase');
+const bucket = new couchbase.Cluster('http://localhost:8091').openBucket('bucketName');
+
+// add a document to a bucket
+bucket.insert('document-key', { name: 'Matt', shoeSize: 13 }, (err, result) => {
+ if (err) {
+ console.log(err);
+ } else {
+ console.log(result);
+ }
+});
+
+// get all documents with shoe size 13
+const n1ql = 'SELECT d.* FROM `bucketName` d WHERE shoeSize = $1';
+const query = N1qlQuery.fromString(n1ql);
+bucket.query(query, [13], (err, result) => {
+ if (err) {
+ console.log(err);
+ } else {
+ console.log(result);
+ }
+});
+```
+
+## CouchDB
+
+**Module**: [nano](https://github.com/dscape/nano)
+
+### Installation
+
+```bash
+$ npm install nano
+```
+
+### Example
+
+```js
+const nano = require('nano')('http://localhost:5984');
+nano.db.create('books');
+const books = nano.db.use('books');
+
+// Insert a book document in the books database
+books.insert({ name: 'The Art of war' }, null, (err, body) => {
+ if (err) {
+ console.log(err);
+ } else {
+ console.log(body);
+ }
+});
+
+// Get a list of all books
+books.list((err, body) => {
+ if (err) {
+ console.log(err);
+ } else {
+ console.log(body.rows);
+ }
+});
+```
+
+## LevelDB
+
+**Module**: [levelup](https://github.com/rvagg/node-levelup)
+
+### Installation
+
+```bash
+$ npm install level levelup leveldown
+```
+
+### Example
+
+```js
+const levelup = require('levelup');
+const db = levelup('./mydb');
+
+db.put('name', 'LevelUP', (err) => {
+ if (err) return console.log('Ooops!', err);
+
+ db.get('name', (err, value) => {
+ if (err) return console.log('Ooops!', err);
+
+ console.log(`name=${value}`);
+ });
+});
+```
+
+## MySQL
+
+**Module**: [mysql](https://github.com/felixge/node-mysql/)
+
+### Installation
+
+```bash
+$ npm install mysql
+```
+
+### Example
+
+```js
+const mysql = require('mysql');
+const connection = mysql.createConnection({
+ host: 'localhost',
+ user: 'dbuser',
+ password: 's3kreee7',
+ database: 'my_db',
+});
+
+connection.connect();
+
+connection.query('SELECT 1 + 1 AS solution', (err, rows, fields) => {
+ if (err) throw err;
+
+ console.log('The solution is: ', rows[0].solution);
+});
+
+connection.end();
+```
+
+## MongoDB
+
+**Module**: [mongodb](https://github.com/mongodb/node-mongodb-native)
+
+### Installation
+
+```bash
+$ npm install mongodb
+```
+
+### Example (v2.\*)
+
+```js
+const MongoClient = require('mongodb').MongoClient;
+
+MongoClient.connect('mongodb://localhost:27017/animals', (err, db) => {
+ if (err) throw err;
+
+ db.collection('mammals')
+ .find()
+ .toArray((err, result) => {
+ if (err) throw err;
+
+ console.log(result);
+ });
+});
+```
+
+### Example (v3.\*)
+
+```js
+const MongoClient = require('mongodb').MongoClient;
+
+MongoClient.connect('mongodb://localhost:27017/animals', (err, client) => {
+ if (err) throw err;
+
+ const db = client.db('animals');
+
+ db.collection('mammals')
+ .find()
+ .toArray((err, result) => {
+ if (err) throw err;
+
+ console.log(result);
+ });
+});
+```
+
+If you want an object model driver for MongoDB, look at [Mongoose](https://github.com/LearnBoost/mongoose).
+
+## Neo4j
+
+**Module**: [neo4j-driver](https://github.com/neo4j/neo4j-javascript-driver)
+
+### Installation
+
+```bash
+$ npm install neo4j-driver
+```
+
+### Example
+
+```js
+const neo4j = require('neo4j-driver');
+const driver = neo4j.driver('neo4j://localhost:7687', neo4j.auth.basic('neo4j', 'letmein'));
+
+const session = driver.session();
+
+session.readTransaction((tx) => {
+ return tx
+ .run('MATCH (n) RETURN count(n) AS count')
+ .then((res) => {
+ console.log(res.records[0].get('count'));
+ })
+ .catch((error) => {
+ console.log(error);
+ });
+});
+```
+
+## Oracle
+
+**Module**: [oracledb](https://github.com/oracle/node-oracledb)
+
+### Installation
+
+NOTE: [See installation prerequisites](https://github.com/oracle/node-oracledb#-installation).
+
+```bash
+$ npm install oracledb
+```
+
+### Example
+
+```js
+const oracledb = require('oracledb');
+const config = {
+ user: '',
+ password: '',
+ connectString: 'localhost:1521/orcl',
+};
+
+async function getEmployee(empId) {
+ let conn;
+
+ try {
+ conn = await oracledb.getConnection(config);
+
+ const result = await conn.execute('select * from employees where employee_id = :id', [empId]);
+
+ console.log(result.rows[0]);
+ } catch (err) {
+ console.log('Ouch!', err);
+ } finally {
+ if (conn) {
+ // conn assignment worked, need to close
+ await conn.close();
+ }
+ }
+}
+
+getEmployee(101);
+```
+
+## PostgreSQL
+
+**Module**: [pg-promise](https://github.com/vitaly-t/pg-promise)
+
+### Installation
+
+```bash
+$ npm install pg-promise
+```
+
+### Example
+
+```js
+const pgp = require('pg-promise')(/* options */);
+const db = pgp('postgres://username:password@host:port/database');
+
+db.one('SELECT $1 AS value', 123)
+ .then((data) => {
+ console.log('DATA:', data.value);
+ })
+ .catch((error) => {
+ console.log('ERROR:', error);
+ });
+```
+
+## Redis
+
+**Module**: [redis](https://github.com/mranney/node_redis)
+
+### Installation
+
+```bash
+$ npm install redis
+```
+
+### Example
+
+```js
+const redis = require('redis');
+const client = redis.createClient();
+
+client.on('error', (err) => {
+ console.log(`Error ${err}`);
+});
+
+client.set('string key', 'string val', redis.print);
+client.hset('hash key', 'hashtest 1', 'some value', redis.print);
+client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print);
+
+client.hkeys('hash key', (err, replies) => {
+ console.log(`${replies.length} replies:`);
+
+ replies.forEach((reply, i) => {
+ console.log(` ${i}: ${reply}`);
+ });
+
+ client.quit();
+});
+```
+
+## SQL Server
+
+**Module**: [tedious](https://github.com/tediousjs/tedious)
+
+### Installation
+
+```bash
+$ npm install tedious
+```
+
+### Example
+
+```js
+const Connection = require('tedious').Connection;
+const Request = require('tedious').Request;
+
+const config = {
+ server: 'localhost',
+ authentication: {
+ type: 'default',
+ options: {
+ userName: 'your_username', // update me
+ password: 'your_password', // update me
+ },
+ },
+};
+
+const connection = new Connection(config);
+
+connection.on('connect', (err) => {
+ if (err) {
+ console.log(err);
+ } else {
+ executeStatement();
+ }
+});
+
+function executeStatement() {
+ request = new Request("select 123, 'hello world'", (err, rowCount) => {
+ if (err) {
+ console.log(err);
+ } else {
+ console.log(`${rowCount} rows`);
+ }
+ connection.close();
+ });
+
+ request.on('row', (columns) => {
+ columns.forEach((column) => {
+ if (column.value === null) {
+ console.log('NULL');
+ } else {
+ console.log(column.value);
+ }
+ });
+ });
+
+ connection.execSql(request);
+}
+```
+
+## SQLite
+
+**Module**: [sqlite3](https://github.com/mapbox/node-sqlite3)
+
+### Installation
+
+```bash
+$ npm install sqlite3
+```
+
+### Example
+
+```js
+const sqlite3 = require('sqlite3').verbose();
+const db = new sqlite3.Database(':memory:');
+
+db.serialize(() => {
+ db.run('CREATE TABLE lorem (info TEXT)');
+ const stmt = db.prepare('INSERT INTO lorem VALUES (?)');
+
+ for (let i = 0; i < 10; i++) {
+ stmt.run(`Ipsum ${i}`);
+ }
+
+ stmt.finalize();
+
+ db.each('SELECT rowid AS id, info FROM lorem', (err, row) => {
+ console.log(`${row.id}: ${row.info}`);
+ });
+});
+
+db.close();
+```
+
+## Elasticsearch
+
+**Module**: [elasticsearch](https://github.com/elastic/elasticsearch-js)
+
+### Installation
+
+```bash
+$ npm install elasticsearch
+```
+
+### Example
+
+```js
+const elasticsearch = require('elasticsearch');
+const client = elasticsearch.Client({
+ host: 'localhost:9200',
+});
+
+client
+ .search({
+ index: 'books',
+ type: 'book',
+ body: {
+ query: {
+ multi_match: {
+ query: 'express js',
+ fields: ['title', 'description'],
+ },
+ },
+ },
+ })
+ .then(
+ (response) => {
+ const hits = response.hits.hits;
+ },
+ (error) => {
+ console.trace(error.message);
+ }
+ );
+```
diff --git a/astro/src/content/docs/en/5x/guide/debugging.md b/astro/src/content/docs/en/5x/guide/debugging.md
new file mode 100755
index 0000000000..dfd3374883
--- /dev/null
+++ b/astro/src/content/docs/en/5x/guide/debugging.md
@@ -0,0 +1,127 @@
+---
+title: Debugging Express
+description: Learn how to enable and use debugging logs in Express.js applications by setting the DEBUG environment variable for enhanced troubleshooting.
+---
+
+# Debugging Express
+
+To see all the internal logs used in Express, set the `DEBUG` environment variable to
+`express:*` when launching your app.
+
+```bash
+$ DEBUG=express:* node index.js
+```
+
+On Windows, use the corresponding command.
+
+```bash
+> $env:DEBUG = "express:*"; node index.js
+```
+
+Running this command on the default app generated by the [express generator](/en/starter/generator) prints the following output:
+
+```bash
+$ DEBUG=express:* node ./bin/www
+ express:router:route new / +0ms
+ express:router:layer new / +1ms
+ express:router:route get / +1ms
+ express:router:layer new / +0ms
+ express:router:route new / +1ms
+ express:router:layer new / +0ms
+ express:router:route get / +0ms
+ express:router:layer new / +0ms
+ express:application compile etag weak +1ms
+ express:application compile query parser extended +0ms
+ express:application compile trust proxy false +0ms
+ express:application booting in development mode +1ms
+ express:router use / query +0ms
+ express:router:layer new / +0ms
+ express:router use / expressInit +0ms
+ express:router:layer new / +0ms
+ express:router use / favicon +1ms
+ express:router:layer new / +0ms
+ express:router use / logger +0ms
+ express:router:layer new / +0ms
+ express:router use / jsonParser +0ms
+ express:router:layer new / +1ms
+ express:router use / urlencodedParser +0ms
+ express:router:layer new / +0ms
+ express:router use / cookieParser +0ms
+ express:router:layer new / +0ms
+ express:router use / stylus +90ms
+ express:router:layer new / +0ms
+ express:router use / serveStatic +0ms
+ express:router:layer new / +0ms
+ express:router use / router +0ms
+ express:router:layer new / +1ms
+ express:router use /users router +0ms
+ express:router:layer new /users +0ms
+ express:router use / <anonymous> +0ms
+ express:router:layer new / +0ms
+ express:router use / <anonymous> +0ms
+ express:router:layer new / +0ms
+ express:router use / <anonymous> +0ms
+ express:router:layer new / +0ms
+```
+
+When a request is then made to the app, you will see the logs specified in the Express code:
+
+```bash
+ express:router dispatching GET / +4h
+ express:router query : / +2ms
+ express:router expressInit : / +0ms
+ express:router favicon : / +0ms
+ express:router logger : / +1ms
+ express:router jsonParser : / +0ms
+ express:router urlencodedParser : / +1ms
+ express:router cookieParser : / +0ms
+ express:router stylus : / +0ms
+ express:router serveStatic : / +2ms
+ express:router router : / +2ms
+ express:router dispatching GET / +1ms
+ express:view lookup "index.pug" +338ms
+ express:view stat "/projects/example/views/index.pug" +0ms
+ express:view render "/projects/example/views/index.pug" +1ms
+```
+
+To see the logs only from the router implementation, set the value of `DEBUG` to `express:router`. Likewise, to see logs only from the application implementation, set the value of `DEBUG` to `express:application`, and so on.
+
+## Applications generated by `express`
+
+An application generated by the `express` command uses the `debug` module and its debug namespace is scoped to the name of the application.
+
+For example, if you generated the app with `$ express sample-app`, you can enable the debug statements with the following command:
+
+```bash
+$ DEBUG=sample-app:* node ./bin/www
+```
+
+You can specify more than one debug namespace by assigning a comma-separated list of names:
+
+```bash
+$ DEBUG=http,mail,express:* node index.js
+```
+
+## Advanced options
+
+When running through Node.js, you can set a few environment variables that will change the behavior of the debug logging:
+
+| Name | Purpose |
+| ------------------- | ------------------------------------------------- |
+| `DEBUG` | Enables/disables specific debugging namespaces. |
+| `DEBUG_COLORS` | Whether or not to use colors in the debug output. |
+| `DEBUG_DEPTH` | Object inspection depth. |
+| `DEBUG_FD` | File descriptor to write debug output to. |
+| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. |
+
+{% capture debug-text %}
+
+The environment variables beginning with `DEBUG_` end up being
+converted into an Options object that gets used with `%o`/`%O` formatters.
+See the Node.js documentation for
+[`util.inspect()`](https://nodejs.org/api/util#util_util_inspect_object_options)
+for the complete list.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=debug-text %}
diff --git a/astro/src/content/docs/en/5x/guide/error-handling.md b/astro/src/content/docs/en/5x/guide/error-handling.md
new file mode 100755
index 0000000000..2a8263931f
--- /dev/null
+++ b/astro/src/content/docs/en/5x/guide/error-handling.md
@@ -0,0 +1,306 @@
+---
+title: Express error handling
+description: Understand how Express.js handles errors in synchronous and asynchronous code, and learn to implement custom error handling middleware for your applications.
+---
+
+# Error Handling
+
+_Error Handling_ refers to how Express catches and processes errors that
+occur both synchronously and asynchronously. Express comes with a default error
+handler so you don't need to write your own to get started.
+
+## Catching Errors
+
+It's important to ensure that Express catches all errors that occur while
+running route handlers and middleware.
+
+Errors that occur in synchronous code inside route handlers and middleware
+require no extra work. If synchronous code throws an error, then Express will
+catch and process it. For example:
+
+```js
+app.get('/', (req, res) => {
+ throw new Error('BROKEN'); // Express will catch this on its own.
+});
+```
+
+For errors returned from asynchronous functions invoked by route handlers
+and middleware, you must pass them to the `next()` function, where Express will
+catch and process them. For example:
+
+```js
+app.get('/', (req, res, next) => {
+ fs.readFile('/file-does-not-exist', (err, data) => {
+ if (err) {
+ next(err); // Pass errors to Express.
+ } else {
+ res.send(data);
+ }
+ });
+});
+```
+
+Starting with Express 5, route handlers and middleware that return a Promise
+will call `next(value)` automatically when they reject or throw an error.
+For example:
+
+```js
+app.get('/user/:id', async (req, res, next) => {
+ const user = await getUserById(req.params.id);
+ res.send(user);
+});
+```
+
+If `getUserById` throws an error or rejects, `next` will be called with either
+the thrown error or the rejected value. If no rejected value is provided, `next`
+will be called with a default Error object provided by the Express router.
+
+If you pass anything to the `next()` function (except the string `'route'`),
+Express regards the current request as being an error and will skip any
+remaining non-error handling routing and middleware functions.
+
+If the callback in a sequence provides no data, only errors, you can simplify
+this code as follows:
+
+```js
+app.get('/', [
+ function (req, res, next) {
+ fs.writeFile('/inaccessible-path', 'data', next);
+ },
+ function (req, res) {
+ res.send('OK');
+ },
+]);
+```
+
+In the above example, `next` is provided as the callback for `fs.writeFile`,
+which is called with or without errors. If there is no error, the second
+handler is executed, otherwise Express catches and processes the error.
+
+You must catch errors that occur in asynchronous code invoked by route handlers or
+middleware and pass them to Express for processing. For example:
+
+```js
+app.get('/', (req, res, next) => {
+ setTimeout(() => {
+ try {
+ throw new Error('BROKEN');
+ } catch (err) {
+ next(err);
+ }
+ }, 100);
+});
+```
+
+The above example uses a `try...catch` block to catch errors in the
+asynchronous code and pass them to Express. If the `try...catch`
+block were omitted, Express would not catch the error since it is not part of the synchronous
+handler code.
+
+Use promises to avoid the overhead of the `try...catch` block or when using functions
+that return promises. For example:
+
+```js
+app.get('/', (req, res, next) => {
+ Promise.resolve()
+ .then(() => {
+ throw new Error('BROKEN');
+ })
+ .catch(next); // Errors will be passed to Express.
+});
+```
+
+Since promises automatically catch both synchronous errors and rejected promises,
+you can simply provide `next` as the final catch handler and Express will catch errors,
+because the catch handler is given the error as the first argument.
+
+You could also use a chain of handlers to rely on synchronous error
+catching, by reducing the asynchronous code to something trivial. For example:
+
+```js
+app.get('/', [
+ function (req, res, next) {
+ fs.readFile('/maybe-valid-file', 'utf-8', (err, data) => {
+ res.locals.data = data;
+ next(err);
+ });
+ },
+ function (req, res) {
+ res.locals.data = res.locals.data.split(',')[1];
+ res.send(res.locals.data);
+ },
+]);
+```
+
+The above example has a couple of trivial statements from the `readFile`
+call. If `readFile` causes an error, then it passes the error to Express, otherwise you
+quickly return to the world of synchronous error handling in the next handler
+in the chain. Then, the example above tries to process the data. If this fails, then the
+synchronous error handler will catch it. If you had done this processing inside
+the `readFile` callback, then the application might exit and the Express error
+handlers would not run.
+
+Whichever method you use, if you want Express error handlers to be called in and the
+application to survive, you must ensure that Express receives the error.
+
+## The default error handler
+
+Express comes with a built-in error handler that takes care of any errors that might be encountered in the app. This default error-handling middleware function is added at the end of the middleware function stack.
+
+If you pass an error to `next()` and you do not handle it in a custom error
+handler, it will be handled by the built-in error handler; the error will be
+written to the client with the stack trace. The stack trace is not included
+in the production environment.
+
+
+Set the environment variable `NODE_ENV` to `production`, to run the app in production mode.
+
+
+When an error is written, the following information is added to the
+response:
+
+- The `res.statusCode` is set from `err.status` (or `err.statusCode`). If
+ this value is outside the 4xx or 5xx range, it will be set to 500.
+- The `res.statusMessage` is set according to the status code.
+- The body will be the HTML of the status code message when in production
+ environment, otherwise will be `err.stack`.
+- Any headers specified in an `err.headers` object.
+
+If you call `next()` with an error after you have started writing the
+response (for example, if you encounter an error while streaming the
+response to the client), the Express default error handler closes the
+connection and fails the request.
+
+So when you add a custom error handler, you must delegate to
+the default Express error handler, when the headers
+have already been sent to the client:
+
+```js
+function errorHandler(err, req, res, next) {
+ if (res.headersSent) {
+ return next(err);
+ }
+ res.status(500);
+ res.render('error', { error: err });
+}
+```
+
+Note that the default error handler can get triggered if you call `next()` with an error
+in your code more than once, even if custom error handling middleware is in place.
+
+Other error handling middleware can be found at [Express middleware](/en/resources/middleware).
+
+## Writing error handlers
+
+Define error-handling middleware functions in the same way as other middleware functions,
+except error-handling functions have four arguments instead of three:
+`(err, req, res, next)`. For example:
+
+```js
+app.use((err, req, res, next) => {
+ console.error(err.stack);
+ res.status(500).send('Something broke!');
+});
+```
+
+You define error-handling middleware last, after other `app.use()` and routes calls; for example:
+
+```js
+const bodyParser = require('body-parser');
+const methodOverride = require('method-override');
+
+app.use(
+ bodyParser.urlencoded({
+ extended: true,
+ })
+);
+app.use(bodyParser.json());
+app.use(methodOverride());
+app.use((err, req, res, next) => {
+ // logic
+});
+```
+
+Responses from within a middleware function can be in any format, such as an HTML error page, a simple message, or a JSON string.
+
+For organizational (and higher-level framework) purposes, you can define
+several error-handling middleware functions, much as you would with
+regular middleware functions. For example, to define an error-handler
+for requests made by using `XHR` and those without:
+
+```js
+const bodyParser = require('body-parser');
+const methodOverride = require('method-override');
+
+app.use(
+ bodyParser.urlencoded({
+ extended: true,
+ })
+);
+app.use(bodyParser.json());
+app.use(methodOverride());
+app.use(logErrors);
+app.use(clientErrorHandler);
+app.use(errorHandler);
+```
+
+In this example, the generic `logErrors` might write request and
+error information to `stderr`, for example:
+
+```js
+function logErrors(err, req, res, next) {
+ console.error(err.stack);
+ next(err);
+}
+```
+
+Also in this example, `clientErrorHandler` is defined as follows; in this case, the error is explicitly passed along to the next one.
+
+Notice that when _not_ calling "next" in an error-handling function, you are responsible for writing (and ending) the response. Otherwise, those requests will "hang" and will not be eligible for garbage collection.
+
+```js
+function clientErrorHandler(err, req, res, next) {
+ if (req.xhr) {
+ res.status(500).send({ error: 'Something failed!' });
+ } else {
+ next(err);
+ }
+}
+```
+
+Implement the "catch-all" `errorHandler` function as follows (for example):
+
+```js
+function errorHandler(err, req, res, next) {
+ res.status(500);
+ res.render('error', { error: err });
+}
+```
+
+If you have a route handler with multiple callback functions, you can use the `route` parameter to skip to the next route handler. For example:
+
+```js
+app.get(
+ '/a_route_behind_paywall',
+ (req, res, next) => {
+ if (!req.user.hasPaid) {
+ // continue handling this request
+ next('route');
+ } else {
+ next();
+ }
+ },
+ (req, res, next) => {
+ PaidContent.find((err, doc) => {
+ if (err) return next(err);
+ res.json(doc);
+ });
+ }
+);
+```
+
+In this example, the `getPaidContent` handler will be skipped but any remaining handlers in `app` for `/a_route_behind_paywall` would continue to be executed.
+
+
+Calls to `next()` and `next(err)` indicate that the current handler is complete and in what state. `next(err)` will skip all remaining handlers in the chain except for those that are set up to handle errors as described above.
+
diff --git a/astro/src/content/docs/en/5x/guide/migrating-4.md b/astro/src/content/docs/en/5x/guide/migrating-4.md
new file mode 100755
index 0000000000..3e35818153
--- /dev/null
+++ b/astro/src/content/docs/en/5x/guide/migrating-4.md
@@ -0,0 +1,613 @@
+---
+title: Migrating to Express 4
+description: A guide to migrating your Express.js applications from version 3 to 4, covering changes in middleware, routing, and how to update your codebase effectively.
+---
+
+# Moving to Express 4
+
+Overview
+
+Express 4 is a breaking change from Express 3. That means an existing Express 3 app will _not_ work if you update the Express version in its dependencies.
+
+This article covers:
+
+
+
+Changes in Express 4
+
+There are several significant changes in Express 4:
+
+
+
+See also:
+
+- [New features in 4.x.](https://github.com/expressjs/express/wiki/New-features-in-4.x)
+- [Migrating from 3.x to 4.x.](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x)
+
+
+Changes to Express core and middleware system
+
+
+Express 4 no longer depends on Connect, and removes all built-in
+middleware from its core, except for the `express.static` function. This means that
+Express is now an independent routing and middleware web framework, and
+Express versioning and releases are not affected by middleware updates.
+
+Without built-in middleware, you must explicitly add all the
+middleware that is required to run your app. Simply follow these steps:
+
+1. Install the module: `npm install --save `
+2. In your app, require the module: `require('module-name')`
+3. Use the module according to its documentation: `app.use( ... )`
+
+The following table lists Express 3 middleware and their counterparts in Express 4.
+
+
+
+Here is the [complete list](https://github.com/senchalabs/connect#middleware) of Express 4 middleware.
+
+In most cases, you can simply replace the old version 3 middleware with
+its Express 4 counterpart. For details, see the module documentation in
+GitHub.
+
+app.use accepts parameters
+
+In version 4 you can use a variable parameter to define the path where middleware functions are loaded, then read the value of the parameter from the route handler.
+For example:
+
+```js
+app.use('/book/:id', (req, res, next) => {
+ console.log('ID:', req.params.id);
+ next();
+});
+```
+
+
+The routing system
+
+
+Apps now implicitly load routing middleware, so you no longer have to
+worry about the order in which middleware is loaded with respect to
+the `router` middleware.
+
+The way you define routes is unchanged, but the routing system has two
+new features to help organize your routes:
+
+{: .doclist }
+
+- A new method, `app.route()`, to create chainable route handlers for a route path.
+- A new class, `express.Router`, to create modular mountable route handlers.
+
+app.route() method
+
+The new `app.route()` method enables you to create chainable route handlers
+for a route path. Because the path is specified in a single location, creating modular routes is helpful, as is reducing redundancy and typos. For more
+information about routes, see [`Router()` documentation](/en/4x/api#router).
+
+Here is an example of chained route handlers that are defined by using the `app.route()` function.
+
+```js
+app
+ .route('/book')
+ .get((req, res) => {
+ res.send('Get a random book');
+ })
+ .post((req, res) => {
+ res.send('Add a book');
+ })
+ .put((req, res) => {
+ res.send('Update the book');
+ });
+```
+
+express.Router class
+
+The other feature that helps to organize routes is a new class,
+`express.Router`, that you can use to create modular mountable
+route handlers. A `Router` instance is a complete middleware and
+routing system; for this reason it is often referred to as a "mini-app".
+
+The following example creates a router as a module, loads middleware in
+it, defines some routes, and mounts it on a path on the main app.
+
+For example, create a router file named `birds.js` in the app directory,
+with the following content:
+
+```js
+var express = require('express');
+var router = express.Router();
+
+// middleware specific to this router
+router.use((req, res, next) => {
+ console.log('Time: ', Date.now());
+ next();
+});
+// define the home page route
+router.get('/', (req, res) => {
+ res.send('Birds home page');
+});
+// define the about route
+router.get('/about', (req, res) => {
+ res.send('About birds');
+});
+
+module.exports = router;
+```
+
+Then, load the router module in the app:
+
+```js
+var birds = require('./birds');
+
+// ...
+
+app.use('/birds', birds);
+```
+
+The app will now be able to handle requests to the `/birds` and
+`/birds/about` paths, and will call the `timeLog`
+middleware that is specific to the route.
+
+
+Other changes
+
+
+The following table lists other small but important changes in Express 4:
+
+
+
+Object
+Description
+
+
+Node.js
+Express 4 requires Node.js 0.10.x or later and has dropped support for
+Node.js 0.8.x.
+
+
+
+`http.createServer()`
+
+
+The `http` module is no longer needed, unless you need to directly work with it (socket.io/SPDY/HTTPS). The app can be started by using the
+`app.listen()` function.
+
+
+
+
+`app.configure()`
+
+
+The `app.configure()` function has been removed. Use the
+`process.env.NODE_ENV` or
+`app.get('env')` function to detect the environment and configure the app accordingly.
+
+
+
+
+`json spaces`
+
+
+The `json spaces` application property is disabled by default in Express 4.
+
+
+
+
+`req.accepted()`
+
+
+Use `req.accepts()`, `req.acceptsEncodings()`,
+`req.acceptsCharsets()`, and `req.acceptsLanguages()`.
+
+
+
+
+`res.location()`
+
+
+No longer resolves relative URLs.
+
+
+
+
+`req.params`
+
+
+Was an array; now an object.
+
+
+
+
+`res.locals`
+
+
+Was a function; now an object.
+
+
+
+
+`res.headerSent`
+
+
+Changed to `res.headersSent`.
+
+
+
+
+`app.route`
+
+
+Now available as `app.mountpath`.
+
+
+
+
+`res.on('header')`
+
+
+Removed.
+
+
+
+
+`res.charset`
+
+
+Removed.
+
+
+
+
+`res.setHeader('Set-Cookie', val)`
+
+
+Functionality is now limited to setting the basic cookie value. Use
+`res.cookie()` for added functionality.
+
+
+
+
+Example app migration
+
+Here is an example of migrating an Express 3 application to Express 4.
+The files of interest are `app.js` and `package.json`.
+
+
+Version 3 app
+
+
+app.js
+
+Consider an Express v.3 application with the following `app.js` file:
+
+```js
+var express = require('express');
+var routes = require('./routes');
+var user = require('./routes/user');
+var http = require('http');
+var path = require('path');
+
+var app = express();
+
+// all environments
+app.set('port', process.env.PORT || 3000);
+app.set('views', path.join(__dirname, 'views'));
+app.set('view engine', 'pug');
+app.use(express.favicon());
+app.use(express.logger('dev'));
+app.use(express.methodOverride());
+app.use(express.session({ secret: 'your secret here' }));
+app.use(express.bodyParser());
+app.use(app.router);
+app.use(express.static(path.join(__dirname, 'public')));
+
+// development only
+if (app.get('env') === 'development') {
+ app.use(express.errorHandler());
+}
+
+app.get('/', routes.index);
+app.get('/users', user.list);
+
+http.createServer(app).listen(app.get('port'), () => {
+ console.log('Express server listening on port ' + app.get('port'));
+});
+```
+
+package.json
+
+The accompanying version 3 `package.json` file might look
+something like this:
+
+```json
+{
+ "name": "application-name",
+ "version": "0.0.1",
+ "private": true,
+ "scripts": {
+ "start": "node app.js"
+ },
+ "dependencies": {
+ "express": "3.12.0",
+ "pug": "*"
+ }
+}
+```
+
+
+Process
+
+
+Begin the migration process by installing the required middleware for the
+Express 4 app and updating Express and Pug to their respective latest
+version with the following command:
+
+```bash
+$ npm install serve-favicon morgan method-override express-session body-parser multer errorhandler express@latest pug@latest --save
+```
+
+Make the following changes to `app.js`:
+
+1. The built-in Express middleware functions `express.favicon`,
+ `express.logger`, `express.methodOverride`,
+ `express.session`, `express.bodyParser` and
+ `express.errorHandler` are no longer available on the
+ `express` object. You must install their alternatives
+ manually and load them in the app.
+
+2. You no longer need to load the `app.router` function.
+ It is not a valid Express 4 app object, so remove the
+ `app.use(app.router);` code.
+
+3. Make sure that the middleware functions are loaded in the correct order - load `errorHandler` after loading the app routes.
+
+Version 4 app
+
+package.json
+
+Running the above `npm` command will update `package.json` as follows:
+
+```json
+{
+ "name": "application-name",
+ "version": "0.0.1",
+ "private": true,
+ "scripts": {
+ "start": "node app.js"
+ },
+ "dependencies": {
+ "body-parser": "^1.5.2",
+ "errorhandler": "^1.1.1",
+ "express": "^4.8.0",
+ "express-session": "^1.7.2",
+ "pug": "^2.0.0",
+ "method-override": "^2.1.2",
+ "morgan": "^1.2.2",
+ "multer": "^0.1.3",
+ "serve-favicon": "^2.0.1"
+ }
+}
+```
+
+app.js
+
+Then, remove invalid code, load the required middleware, and make other
+changes as necessary. The `app.js` file will look like this:
+
+```js
+var http = require('http');
+var express = require('express');
+var routes = require('./routes');
+var user = require('./routes/user');
+var path = require('path');
+
+var favicon = require('serve-favicon');
+var logger = require('morgan');
+var methodOverride = require('method-override');
+var session = require('express-session');
+var bodyParser = require('body-parser');
+var multer = require('multer');
+var errorHandler = require('errorhandler');
+
+var app = express();
+
+// all environments
+app.set('port', process.env.PORT || 3000);
+app.set('views', path.join(__dirname, 'views'));
+app.set('view engine', 'pug');
+app.use(favicon(path.join(__dirname, '/public/favicon.ico')));
+app.use(logger('dev'));
+app.use(methodOverride());
+app.use(
+ session({
+ resave: true,
+ saveUninitialized: true,
+ secret: 'uwotm8',
+ })
+);
+app.use(bodyParser.json());
+app.use(bodyParser.urlencoded({ extended: true }));
+app.use(multer());
+app.use(express.static(path.join(__dirname, 'public')));
+
+app.get('/', routes.index);
+app.get('/users', user.list);
+
+// error handling middleware should be loaded after the loading the routes
+if (app.get('env') === 'development') {
+ app.use(errorHandler());
+}
+
+var server = http.createServer(app);
+server.listen(app.get('port'), () => {
+ console.log('Express server listening on port ' + app.get('port'));
+});
+```
+
+
+Unless you need to work directly with the `http` module (socket.io/SPDY/HTTPS), loading it is not required, and the app can be simply started this way:
+
+```js
+app.listen(app.get('port'), () => {
+ console.log('Express server listening on port ' + app.get('port'));
+});
+```
+
+
+
+Run the app
+
+The migration process is complete, and the app is now an
+Express 4 app. To confirm, start the app by using the following command:
+
+```bash
+$ node .
+```
+
+Load [http://localhost:3000](http://localhost:3000)
+and see the home page being rendered by Express 4.
+
+Upgrading to the Express 4 app generator
+
+The command-line tool to generate an Express app is still
+`express`, but to upgrade to the new version, you must uninstall
+the Express 3 app generator and then install the new
+`express-generator`.
+
+Installing
+
+If you already have the Express 3 app generator installed on your system,
+you must uninstall it:
+
+```bash
+$ npm uninstall -g express
+```
+
+Depending on how your file and directory privileges are configured,
+you might need to run this command with `sudo`.
+
+Now install the new generator:
+
+```bash
+$ npm install -g express-generator
+```
+
+Depending on how your file and directory privileges are configured,
+you might need to run this command with `sudo`.
+
+Now the `express` command on your system is updated to the
+Express 4 generator.
+
+Changes to the app generator
+
+Command options and use largely remain the same, with the following exceptions:
+
+{: .doclist }
+
+- Removed the `--sessions` option.
+- Removed the `--jshtml` option.
+- Added the `--hogan` option to support [Hogan.js](http://twitter.github.io/hogan.js/).
+
+Example
+
+Execute the following command to create an Express 4 app:
+
+```bash
+$ express app4
+```
+
+If you look at the contents of the `app4/app.js` file, you will notice
+that all the middleware functions (except `express.static`) that are required for
+the app are loaded as independent modules, and the `router` middleware
+is no longer explicitly loaded in the app.
+
+You will also notice that the `app.js` file is now a Node.js module, in contrast to the standalone app that was generated by the old generator.
+
+After installing the dependencies, start the app by using the following command:
+
+```bash
+$ npm start
+```
+
+If you look at the `npm start` script in the `package.json` file,
+you will notice that the actual command that starts the app is
+`node ./bin/www`, which used to be `node app.js`
+in Express 3.
+
+Because the `app.js` file that was generated by the Express 4 generator
+is now a Node.js module, it can no longer be started independently as an app
+(unless you modify the code). The module must be loaded in a Node.js file
+and started via the Node.js file. The Node.js file is `./bin/www`
+in this case.
+
+Neither the `bin` directory nor the extensionless `www`
+file is mandatory for creating an Express app or starting the app. They are
+just suggestions made by the generator, so feel free to modify them to suit your
+needs.
+
+To get rid of the `www` directory and keep things the "Express 3 way",
+delete the line that says `module.exports = app;` at the end of the
+`app.js` file, then paste the following code in its place:
+
+```js
+app.set('port', process.env.PORT || 3000);
+
+var server = app.listen(app.get('port'), () => {
+ debug('Express server listening on port ' + server.address().port);
+});
+```
+
+Ensure that you load the `debug` module at the top of the `app.js` file by using the following code:
+
+```js
+var debug = require('debug')('app4');
+```
+
+Next, change `"start": "node ./bin/www"` in the `package.json` file to `"start": "node app.js"`.
+
+You have now moved the functionality of `./bin/www` back to
+`app.js`. This change is not recommended, but the exercise helps you
+to understand how the `./bin/www` file works, and why the `app.js` file
+no longer starts on its own.
diff --git a/astro/src/content/docs/en/5x/guide/migrating-5.md b/astro/src/content/docs/en/5x/guide/migrating-5.md
new file mode 100755
index 0000000000..f042d5ffb4
--- /dev/null
+++ b/astro/src/content/docs/en/5x/guide/migrating-5.md
@@ -0,0 +1,614 @@
+---
+title: Migrating to Express 5
+description: A comprehensive guide to migrating your Express.js applications from version 4 to 5, detailing breaking changes, deprecated methods, and new improvements.
+---
+
+# Moving to Express 5
+
+Overview
+
+Express 5 is not very different from Express 4; although it maintains the same basic API, there are still changes that break compatibility with the previous version. Therefore, an application built with Express 4 might not work if you update it to use Express 5.
+
+To install this version, you need to have a Node.js version 18 or higher. Then, execute the following command in your application directory:
+
+```sh
+npm install "express@5"
+```
+
+You can then run your automated tests to see what fails, and fix problems according to the updates listed below. After addressing test failures, run your app to see what errors occur. You'll find out right away if the app uses any methods or properties that are not supported.
+
+## Express 5 Codemods
+
+To help you migrate your express server, we have created a set of codemods that will help you automatically update your code to the latest version of Express.
+
+Run the following command for run all the codemods available:
+
+```sh
+npx codemod@latest @expressjs/v5-migration-recipe
+```
+
+If you want to run a specific codemod, you can run the following command:
+
+```sh
+npx codemod@latest @expressjs/name-of-the-codemod
+```
+
+You can find the list of available codemods [here](https://codemod.link/express).
+
+Changes in Express 5
+
+**Removed methods and properties**
+
+
+
+**Changed**
+
+
+
+**Improvements**
+
+
+
+## Removed methods and properties
+
+If you use any of these methods or properties in your app, it will crash. So, you'll need to change your app after you update to version 5.
+
+app.del()
+
+Express 5 no longer supports the `app.del()` function. If you use this function, an error is thrown. For registering HTTP DELETE routes, use the `app.delete()` function instead.
+
+Initially, `del` was used instead of `delete`, because `delete` is a reserved keyword in JavaScript. However, as of ECMAScript 6, `delete` and other reserved keywords can legally be used as property names.
+
+{% capture codemod-route-del-to-delete %}
+You can replace the deprecated signatures with the following command:
+
+```plaintext
+npx codemod@latest @expressjs/route-del-to-delete
+```
+
+{% endcapture %}
+
+{% include admonitions/note.html content=codemod-route-del-to-delete %}
+
+```js
+// v4
+app.del('/user/:id', (req, res) => {
+ res.send(`DELETE /user/${req.params.id}`);
+});
+
+// v5
+app.delete('/user/:id', (req, res) => {
+ res.send(`DELETE /user/${req.params.id}`);
+});
+```
+
+app.param(fn)
+
+The `app.param(fn)` signature was used for modifying the behavior of the `app.param(name, fn)` function. It has been deprecated since v4.11.0, and Express 5 no longer supports it at all.
+
+Pluralized method names
+
+The following method names have been pluralized. In Express 4, using the old methods resulted in a deprecation warning. Express 5 no longer supports them at all:
+
+`req.acceptsCharset()` is replaced by `req.acceptsCharsets()`.
+
+`req.acceptsEncoding()` is replaced by `req.acceptsEncodings()`.
+
+`req.acceptsLanguage()` is replaced by `req.acceptsLanguages()`.
+
+{% capture codemod-pluralized-methods %}
+You can replace the deprecated signatures with the following command:
+
+```plaintext
+npx codemod@latest @expressjs/pluralize-method-names
+```
+
+{% endcapture %}
+
+{% include admonitions/note.html content=codemod-pluralized-methods %}
+
+```js
+// v4
+app.all('/', (req, res) => {
+ req.acceptsCharset('utf-8');
+ req.acceptsEncoding('br');
+ req.acceptsLanguage('en');
+
+ // ...
+});
+
+// v5
+app.all('/', (req, res) => {
+ req.acceptsCharsets('utf-8');
+ req.acceptsEncodings('br');
+ req.acceptsLanguages('en');
+
+ // ...
+});
+```
+
+Leading colon (:) in the name for app.param(name, fn)
+
+A leading colon character (:) in the name for the `app.param(name, fn)` function is a remnant of Express 3, and for the sake of backwards compatibility, Express 4 supported it with a deprecation notice. Express 5 will silently ignore it and use the name parameter without prefixing it with a colon.
+
+This should not affect your code if you follow the Express 4 documentation of [app.param](/en/4x/api#app.param), as it makes no mention of the leading colon.
+
+req.param(name)
+
+This potentially confusing and dangerous method of retrieving form data has been removed. You will now need to specifically look for the submitted parameter name in the `req.params`, `req.body`, or `req.query` object.
+
+{% capture codemod-req-param %}
+You can replace the deprecated signatures with the following command:
+
+```plaintext
+npx codemod@latest @expressjs/explicit-request-params
+```
+
+{% endcapture %}
+
+{% include admonitions/note.html content=codemod-req-param %}
+
+```js
+// v4
+app.post('/user', (req, res) => {
+ const id = req.param('id');
+ const body = req.param('body');
+ const query = req.param('query');
+
+ // ...
+});
+
+// v5
+app.post('/user', (req, res) => {
+ const id = req.params.id;
+ const body = req.body;
+ const query = req.query;
+
+ // ...
+});
+```
+
+res.json(obj, status)
+
+Express 5 no longer supports the signature `res.json(obj, status)`. Instead, set the status and then chain it to the `res.json()` method like this: `res.status(status).json(obj)`.
+
+{% capture codemod-status-send-order %}
+You can replace the deprecated signatures with the following command:
+
+```plaintext
+npx codemod@latest @expressjs/status-send-order
+```
+
+{% endcapture %}
+
+{% include admonitions/note.html content=codemod-status-send-order %}
+
+```js
+// v4
+app.post('/user', (req, res) => {
+ res.json({ name: 'Ruben' }, 201);
+});
+
+// v5
+app.post('/user', (req, res) => {
+ res.status(201).json({ name: 'Ruben' });
+});
+```
+
+res.jsonp(obj, status)
+
+Express 5 no longer supports the signature `res.jsonp(obj, status)`. Instead, set the status and then chain it to the `res.jsonp()` method like this: `res.status(status).jsonp(obj)`.
+
+{% include admonitions/note.html content=codemod-status-send-order %}
+
+```js
+// v4
+app.post('/user', (req, res) => {
+ res.jsonp({ name: 'Ruben' }, 201);
+});
+
+// v5
+app.post('/user', (req, res) => {
+ res.status(201).jsonp({ name: 'Ruben' });
+});
+```
+
+res.redirect(url, status)
+
+Express 5 no longer supports the signature `res.redirect(url, status)`. Instead, use the following signature: `res.redirect(status, url)`.
+
+{% capture codemod-redirect-arg-order %}
+You can replace the deprecated signatures with the following command:
+
+```plaintext
+npx codemod@latest @expressjs/redirect-arg-order
+```
+
+{% endcapture %}
+
+{% include admonitions/note.html content=codemod-redirect-arg-order %}
+
+```js
+// v4
+app.get('/user', (req, res) => {
+ res.redirect('/users', 301);
+});
+
+// v5
+app.get('/user', (req, res) => {
+ res.redirect(301, '/users');
+});
+```
+
+res.redirect('back') and res.location('back')
+
+Express 5 no longer supports the magic string `back` in the `res.redirect()` and `res.location()` methods. Instead, use the `req.get('Referrer') || '/'` value to redirect back to the previous page. In Express 4, the `res.redirect('back')` and `res.location('back')` methods were deprecated.
+
+{% capture codemod-back-redirect-deprecated %}
+You can replace the deprecated signatures with the following command:
+
+```plaintext
+npx codemod@latest @expressjs/back-redirect-deprecated
+```
+
+{% endcapture %}
+
+{% include admonitions/note.html content=codemod-back-redirect-deprecated %}
+
+```js
+// v4
+app.get('/user', (req, res) => {
+ res.redirect('back');
+});
+
+// v5
+app.get('/user', (req, res) => {
+ res.redirect(req.get('Referrer') || '/');
+});
+```
+
+res.send(body, status)
+
+Express 5 no longer supports the signature `res.send(obj, status)`. Instead, set the status and then chain it to the `res.send()` method like this: `res.status(status).send(obj)`.
+
+{% include admonitions/note.html content=codemod-status-send-order %}
+
+```js
+// v4
+app.get('/user', (req, res) => {
+ res.send({ name: 'Ruben' }, 200);
+});
+
+// v5
+app.get('/user', (req, res) => {
+ res.status(200).send({ name: 'Ruben' });
+});
+```
+
+res.send(status)
+
+Express 5 no longer supports the signature `res.send(status)`, where `status` is a number. Instead, use the `res.sendStatus(statusCode)` function, which sets the HTTP response header status code and sends the text version of the code: "Not Found", "Internal Server Error", and so on.
+If you need to send a number by using the `res.send()` function, quote the number to convert it to a string, so that Express does not interpret it as an attempt to use the unsupported old signature.
+
+{% include admonitions/note.html content=codemod-status-send-order %}
+
+```js
+// v4
+app.get('/user', (req, res) => {
+ res.send(200);
+});
+
+// v5
+app.get('/user', (req, res) => {
+ res.sendStatus(200);
+});
+```
+
+res.sendfile()
+
+The `res.sendfile()` function has been replaced by a camel-cased version `res.sendFile()` in Express 5.
+
+**Note:** In Express 5, `res.sendFile()` uses the `mime-types` package for MIME type detection, which returns different Content-Type values than Express 4 for several common file types:
+
+- JavaScript files (.js): now "text/javascript" instead of "application/javascript"
+- JSON files (.json): now "application/json" instead of "text/json"
+- CSS files (.css): now "text/css" instead of "text/plain"
+- XML files (.xml): now "application/xml" instead of "text/xml"
+- Font files (.woff): now "font/woff" instead of "application/font-woff"
+- SVG files (.svg): now "image/svg+xml" instead of "application/svg+xml"
+
+{% capture codemod-camelcase-sendfile %}
+You can replace the deprecated signatures with the following command:
+
+```plaintext
+npx codemod@latest @expressjs/camelcase-sendfile
+```
+
+{% endcapture %}
+
+{% include admonitions/note.html content=codemod-camelcase-sendfile %}
+
+```js
+// v4
+app.get('/user', (req, res) => {
+ res.sendfile('/path/to/file');
+});
+
+// v5
+app.get('/user', (req, res) => {
+ res.sendFile('/path/to/file');
+});
+```
+
+router.param(fn)
+
+The `router.param(fn)` signature was used for modifying the behavior of the `router.param(name, fn)` function. It has been deprecated since v4.11.0, and Express 5 no longer supports it at all.
+
+express.static.mime
+
+In Express 5, `mime` is no longer an exported property of the `static` field.
+Use the [`mime-types` package](https://github.com/jshttp/mime-types) to work with MIME type values.
+
+**Important:** This change affects not only direct usage of `express.static.mime` but also other Express methods that rely on MIME type detection, such as `res.sendFile()`. The following MIME types have changed from Express 4:
+
+- JavaScript files (.js): now served as "text/javascript" instead of "application/javascript"
+- JSON files (.json): now served as "application/json" instead of "text/json"
+- CSS files (.css): now served as "text/css" instead of "text/plain"
+- HTML files (): now served as "text/html; charset=utf-8" instead of just "text/html"
+- XML files (.xml): now served as "application/xml" instead of "text/xml"
+- Font files (.woff): now served as "font/woff" instead of "application/font-woff"
+
+```js
+// v4
+express.static.mime.lookup('json');
+
+// v5
+const mime = require('mime-types');
+mime.lookup('json');
+```
+
+express:router debug logs
+
+In Express 5, router handling logic is performed by a dependency. Therefore, the
+debug logs for the router are no longer available under the `express:` namespace.
+In v4, the logs were available under the namespaces `express:router`, `express:router:layer`,
+and `express:router:route`. All of these were included under the namespace `express:*`.
+In v5.1+, the logs are available under the namespaces `router`, `router:layer`, and `router:route`.
+The logs from `router:layer` and `router:route` are included in the namespace `router:*`.
+To achieve the same detail of debug logging when using `express:*` in v4, use a conjunction of
+`express:*`, `router`, and `router:*`.
+
+```sh
+# v4
+DEBUG=express:* node index.js
+
+# v5
+DEBUG=express:*,router,router:* node index.js
+```
+
+## Changed
+
+Path route matching syntax
+
+Path route matching syntax is when a string is supplied as the first parameter to the `app.all()`, `app.use()`, `app.METHOD()`, `router.all()`, `router.METHOD()`, and `router.use()` APIs. The following changes have been made to how the path string is matched to an incoming request:
+
+- The wildcard `*` must have a name, matching the behavior of parameters `:`, use `/*splat` instead of `/*`
+
+```js
+// v4
+app.get('/*', async (req, res) => {
+ res.send('ok');
+});
+
+// v5
+app.get('/*splat', async (req, res) => {
+ res.send('ok');
+});
+```
+
+{% capture note_wildcard %}
+`*splat` matches any path without the root path. If you need to match the root path as well `/`, you can use `/{*splat}`, wrapping the wildcard in braces.
+
+```js
+// v5
+app.get('/{*splat}', async (req, res) => {
+ res.send('ok');
+});
+```
+
+{% endcapture %}
+{% include admonitions/note.html content=note_wildcard %}
+
+- The optional character `?` is no longer supported, use braces instead.
+
+```js
+// v4
+app.get('/:file.:ext?', async (req, res) => {
+ res.send('ok');
+});
+
+// v5
+app.get('/:file{.:ext}', async (req, res) => {
+ res.send('ok');
+});
+```
+
+- Regexp characters are not supported. For example:
+
+```js
+app.get('/[discussion|page]/:slug', async (req, res) => {
+ res.status(200).send('ok');
+});
+```
+
+should be changed to:
+
+```js
+app.get(['/discussion/:slug', '/page/:slug'], async (req, res) => {
+ res.status(200).send('ok');
+});
+```
+
+- Some characters have been reserved to avoid confusion during upgrade (`()[]?+!`), use `\` to escape them.
+- Parameter names now support valid JavaScript identifiers, or quoted like `:"this"`.
+
+Rejected promises handled from middleware and handlers
+
+Request middleware and handlers that return rejected promises are now handled by forwarding the rejected value as an `Error` to the error handling middleware. This means that using `async` functions as middleware and handlers are easier than ever. When an error is thrown in an `async` function or a rejected promise is `await`ed inside an async function, those errors will be passed to the error handler as if calling `next(err)`.
+
+Details of how Express handles errors is covered in the [error handling documentation](/en/guide/error-handling).
+
+express.urlencoded
+
+The `express.urlencoded` method makes the `extended` option `false` by default.
+
+express.static dotfiles
+
+In Express 5, the `express.static` middleware's `dotfiles` option now defaults to `"ignore"`. This is a change from Express 4, where dotfiles were served by default. As a result, files inside a directory that starts with a dot (`.`), such as `.well-known`, will no longer be accessible and will return a **404 Not Found** error. This can break functionality that depends on serving dot-directories, such as Android App Links, and Apple Universal Links.
+
+Example of breaking code:
+
+```js
+// v4
+app.use(express.static('public'));
+```
+
+After migrating to Express 5, a request to `/.well-known/assetlinks.json` will result in a **404 Not Found**.
+
+To fix this, serve specific dot-directories explicitly using the `dotfiles: "allow"` option:
+
+```js
+// v5
+app.use('/.well-known', express.static('public/.well-known', { dotfiles: 'allow' }));
+app.use(express.static('public'));
+```
+
+This approach allows you to safely serve only the intended dot-directories while keeping the default secure behavior for other dotfiles, which remain inaccessible.
+
+app.listen
+
+In Express 5, the `app.listen` method will invoke the user-provided callback function (if provided) when the server receives an error event. In Express 4, such errors would be thrown. This change shifts error-handling responsibility to the callback function in Express 5. If there is an error, it will be passed to the callback as an argument.
+For example:
+
+```js
+const server = app.listen(8080, '0.0.0.0', (error) => {
+ if (error) {
+ throw error; // e.g. EADDRINUSE
+ }
+ console.log(`Listening on ${JSON.stringify(server.address())}`);
+});
+```
+
+app.router
+
+The `app.router` object, which was removed in Express 4, has made a comeback in Express 5. In the new version, this object is a just a reference to the base Express router, unlike in Express 3, where an app had to explicitly load it.
+
+req.body
+
+The `req.body` property returns `undefined` when the body has not been parsed. In Express 4, it returns `{}` by default.
+
+req.host
+
+In Express 4, the `req.host` function incorrectly stripped off the port number if it was present. In Express 5, the port number is maintained.
+
+req.params
+
+The `req.params` object now has a **null prototype** when using string paths. However, if the path is defined with a regular expression, `req.params` remains a standard object with a normal prototype. Additionally, there are two important behavioral changes:
+
+**Wildcard parameters are now arrays:**
+
+Wildcards (e.g., `/*splat`) capture path segments as an array instead of a single string.
+
+```js
+app.get('/*splat', (req, res) => {
+ // GET /foo/bar
+ console.dir(req.params);
+ // => [Object: null prototype] { splat: [ 'foo', 'bar' ] }
+});
+```
+
+**Unmatched parameters are omitted:**
+
+In Express 4, unmatched wildcards were empty strings (`''`) and optional `:` parameters (using `?`) had a key with value `undefined`. In Express 5, unmatched parameters are completely omitted from `req.params`.
+
+```js
+// v4: unmatched wildcard is empty string
+app.get('/*', (req, res) => {
+ // GET /
+ console.dir(req.params);
+ // => { '0': '' }
+});
+
+// v4: unmatched optional param is undefined
+app.get('/:file.:ext?', (req, res) => {
+ // GET /image
+ console.dir(req.params);
+ // => { file: 'image', ext: undefined }
+});
+
+// v5: unmatched optional param is omitted
+app.get('/:file{.:ext}', (req, res) => {
+ // GET /image
+ console.dir(req.params);
+ // => [Object: null prototype] { file: 'image' }
+});
+```
+
+req.query
+
+The `req.query` property is no longer a writable property and is instead a getter. The default query parser has been changed from "extended" to "simple".
+
+res.clearCookie
+
+The `res.clearCookie` method ignores the `maxAge` and `expires` options provided by the user.
+
+res.status
+
+The `res.status` method only accepts integers in the range of `100` to `999`, following the behavior defined by Node.js, and it returns an error when the status code is not an integer.
+
+res.vary
+
+The `res.vary` throws an error when the `field` argument is missing. In Express 4, if the argument was omitted, it gave a warning in the console
+
+## Improvements
+
+res.render()
+
+This method now enforces asynchronous behavior for all view engines, avoiding bugs caused by view engines that had a synchronous implementation and that violated the recommended interface.
+
+Brotli encoding support
+
+Express 5 supports Brotli encoding for requests received from clients that support it.
diff --git a/astro/src/content/docs/en/5x/guide/overriding-express-api.md b/astro/src/content/docs/en/5x/guide/overriding-express-api.md
new file mode 100644
index 0000000000..8f78a06422
--- /dev/null
+++ b/astro/src/content/docs/en/5x/guide/overriding-express-api.md
@@ -0,0 +1,70 @@
+---
+title: Overriding the Express API
+description: Discover how to customize and extend the Express.js API by overriding methods and properties on the request and response objects using prototypes.
+---
+
+# Overriding the Express API
+
+The Express API consists of various methods and properties on the request and response objects. These are inherited by prototype. There are two extension points for the Express API:
+
+1. The global prototypes at `express.request` and `express.response`.
+2. App-specific prototypes at `app.request` and `app.response`.
+
+Altering the global prototypes will affect all loaded Express apps in the same process. If desired, alterations can be made app-specific by only altering the app-specific prototypes after creating a new app.
+
+## Methods
+
+You can override the signature and behavior of existing methods with your own, by assigning a custom function.
+
+Following is an example of overriding the behavior of [res.sendStatus](/en/4x/api#res.sendStatus).
+
+```js
+app.response.sendStatus = function (statusCode, type, message) {
+ // code is intentionally kept simple for demonstration purpose
+ return this.contentType(type).status(statusCode).send(message);
+};
+```
+
+The above implementation completely changes the original signature of `res.sendStatus`. It now accepts a status code, encoding type, and the message to be sent to the client.
+
+The overridden method may now be used this way:
+
+```js
+res.sendStatus(404, 'application/json', '{"error":"resource not found"}');
+```
+
+## Properties
+
+Properties in the Express API are either:
+
+1. Assigned properties (ex: `req.baseUrl`, `req.originalUrl`)
+2. Defined as getters (ex: `req.secure`, `req.ip`)
+
+Since properties under category 1 are dynamically assigned on the `request` and `response` objects in the context of the current request-response cycle, their behavior cannot be overridden.
+
+Properties under category 2 can be overwritten using the Express API extensions API.
+
+The following code rewrites how the value of `req.ip` is to be derived. Now, it simply returns the value of the `Client-IP` request header.
+
+```js
+Object.defineProperty(app.request, 'ip', {
+ configurable: true,
+ enumerable: true,
+ get() {
+ return this.get('Client-IP');
+ },
+});
+```
+
+## Prototype
+
+In order to provide the Express API, the request/response objects passed to Express (via `app(req, res)`, for example) need to inherit from the same prototype chain. By default, this is `http.IncomingRequest.prototype` for the request and `http.ServerResponse.prototype` for the response.
+
+Unless necessary, it is recommended that this be done only at the application level, rather than globally. Also, take care that the prototype that is being used matches the functionality as closely as possible to the default prototypes.
+
+```js
+// Use FakeRequest and FakeResponse in place of http.IncomingRequest and http.ServerResponse
+// for the given app reference
+Object.setPrototypeOf(Object.getPrototypeOf(app.request), FakeRequest.prototype);
+Object.setPrototypeOf(Object.getPrototypeOf(app.response), FakeResponse.prototype);
+```
diff --git a/astro/src/content/docs/en/5x/guide/routing.md b/astro/src/content/docs/en/5x/guide/routing.md
new file mode 100755
index 0000000000..cb7868d359
--- /dev/null
+++ b/astro/src/content/docs/en/5x/guide/routing.md
@@ -0,0 +1,417 @@
+---
+title: Express routing
+description: Learn how to define and use routes in Express.js applications, including route methods, route paths, parameters, and using Router for modular routing.
+---
+
+# Routing
+
+_Routing_ refers to how an application's endpoints (URIs) respond to client requests.
+For an introduction to routing, see [Basic routing](/en/starter/basic-routing).
+
+You define routing using methods of the Express `app` object that correspond to HTTP methods;
+for example, `app.get()` to handle GET requests and `app.post` to handle POST requests. For a full list,
+see [app.METHOD](/en/5x/api#app.METHOD). You can also use [app.all()](/en/5x/api#app.all) to handle all HTTP methods and [app.use()](/en/5x/api#app.use) to
+specify middleware as the callback function (See [Using middleware](/en/guide/using-middleware) for details).
+
+These routing methods specify a callback function (sometimes called "handler functions") called when the application receives a request to the specified route (endpoint) and HTTP method. In other words, the application "listens" for requests that match the specified route(s) and method(s), and when it detects a match, it calls the specified callback function.
+
+In fact, the routing methods can have more than one callback function as arguments.
+With multiple callback functions, it is important to provide `next` as an argument to the callback function and then call `next()` within the body of the function to hand off control
+to the next callback.
+
+The following code is an example of a very basic route.
+
+```js
+const express = require('express');
+const app = express();
+
+// respond with "hello world" when a GET request is made to the homepage
+app.get('/', (req, res) => {
+ res.send('hello world');
+});
+```
+
+Route methods
+
+A route method is derived from one of the HTTP methods, and is attached to an instance of the `express` class.
+
+The following code is an example of routes that are defined for the `GET` and the `POST` methods to the root of the app.
+
+```js
+// GET method route
+app.get('/', (req, res) => {
+ res.send('GET request to the homepage');
+});
+
+// POST method route
+app.post('/', (req, res) => {
+ res.send('POST request to the homepage');
+});
+```
+
+Express supports methods that correspond to all HTTP request methods: `get`, `post`, and so on.
+For a full list, see [app.METHOD](/en/5x/api#app.METHOD).
+
+There is a special routing method, `app.all()`, used to load middleware functions at a path for _all_ HTTP request methods. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods).
+
+```js
+app.all('/secret', (req, res, next) => {
+ console.log('Accessing the secret section ...');
+ next(); // pass control to the next handler
+});
+```
+
+Route paths
+
+Route paths, in combination with a request method, define the endpoints at which requests can be made. Route paths can be strings, string patterns, or regular expressions.
+
+{% capture caution-character %} In express 5, the characters `?`, `+`, `*`, `[]`, and `()` are handled differently than in version 4, please review the [migration guide](/en/guide/migrating-5#path-syntax) for more information.{% endcapture %}
+
+{% include admonitions/caution.html content=caution-character %}
+
+{% capture note-dollar-character %}In express 4, regular expression characters such as `$` need to be escaped with a `\`.
+{% endcapture %}
+
+{% include admonitions/caution.html content=note-dollar-character %}
+
+{% capture note-path-to-regexp %}
+
+Express uses [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) for matching the route paths; see the path-to-regexp documentation for all the possibilities in defining route paths. [Express Playground Router](https://bjohansebas.github.io/playground-router/) is a handy tool for testing basic Express routes, although it does not support pattern matching.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=note-path-to-regexp %}
+
+{% capture query-string-note %}
+
+Query strings are not part of the route path.
+
+{% endcapture %}
+
+{% include admonitions/warning.html content=query-string-note %}
+
+### Route paths based on strings
+
+This route path will match requests to the root route, `/`.
+
+```js
+app.get('/', (req, res) => {
+ res.send('root');
+});
+```
+
+This route path will match requests to `/about`.
+
+```js
+app.get('/about', (req, res) => {
+ res.send('about');
+});
+```
+
+This route path will match requests to `/random.text`.
+
+```js
+app.get('/random.text', (req, res) => {
+ res.send('random.text');
+});
+```
+
+### Route paths based on string patterns
+
+{% capture caution-string-patterns %} The string patterns in Express 5 no longer work. Please refer to the [migration guide](/en/guide/migrating-5#path-syntax) for more information.{% endcapture %}
+
+{% include admonitions/caution.html content=caution-string-patterns %}
+
+This route path will match `acd` and `abcd`.
+
+```js
+app.get('/ab?cd', (req, res) => {
+ res.send('ab?cd');
+});
+```
+
+This route path will match `abcd`, `abbcd`, `abbbcd`, and so on.
+
+```js
+app.get('/ab+cd', (req, res) => {
+ res.send('ab+cd');
+});
+```
+
+This route path will match `abcd`, `abxcd`, `abRANDOMcd`, `ab123cd`, and so on.
+
+```js
+app.get('/ab*cd', (req, res) => {
+ res.send('ab*cd');
+});
+```
+
+This route path will match `/abe` and `/abcde`.
+
+```js
+app.get('/ab(cd)?e', (req, res) => {
+ res.send('ab(cd)?e');
+});
+```
+
+### Route paths based on regular expressions
+
+This route path will match anything with an "a" in it.
+
+```js
+app.get(/a/, (req, res) => {
+ res.send('/a/');
+});
+```
+
+This route path will match `butterfly` and `dragonfly`, but not `butterflyman`, `dragonflyman`, and so on.
+
+```js
+app.get(/.*fly$/, (req, res) => {
+ res.send('/.*fly$/');
+});
+```
+
+Route parameters
+
+Route parameters are named URL segments that are used to capture the values specified at their position in the URL. The captured values are populated in the `req.params` object, with the name of the route parameter specified in the path as their respective keys.
+
+```
+Route path: /users/:userId/books/:bookId
+Request URL: http://localhost:3000/users/34/books/8989
+req.params: { "userId": "34", "bookId": "8989" }
+```
+
+To define routes with route parameters, simply specify the route parameters in the path of the route as shown below.
+
+```js
+app.get('/users/:userId/books/:bookId', (req, res) => {
+ res.send(req.params);
+});
+```
+
+
+The name of route parameters must be made up of "word characters" ([A-Za-z0-9_]).
+
+
+Since the hyphen (`-`) and the dot (`.`) are interpreted literally, they can be used along with route parameters for useful purposes.
+
+```
+Route path: /flights/:from-:to
+Request URL: http://localhost:3000/flights/LAX-SFO
+req.params: { "from": "LAX", "to": "SFO" }
+```
+
+```
+Route path: /plantae/:genus.:species
+Request URL: http://localhost:3000/plantae/Prunus.persica
+req.params: { "genus": "Prunus", "species": "persica" }
+```
+
+{% capture warning-regexp %}
+In express 5, Regexp characters are not supported in route paths, for more information please refer to the [migration guide](/en/guide/migrating-5#path-syntax).{% endcapture %}
+
+{% include admonitions/caution.html content=warning-regexp %}
+
+To have more control over the exact string that can be matched by a route parameter, you can append a regular expression in parentheses (`()`):
+
+```
+Route path: /user/:userId(\d+)
+Request URL: http://localhost:3000/user/42
+req.params: {"userId": "42"}
+```
+
+{% capture escape-advisory %}
+
+Because the regular expression is usually part of a literal string, be sure to escape any `\` characters with an additional backslash, for example `\\d+`.
+
+{% endcapture %}
+
+{% include admonitions/warning.html content=escape-advisory %}
+
+{% capture warning-version %}
+
+In Express 4.x, the `*` character in regular expressions is not interpreted in the usual way . As a workaround, use `{0,}` instead of `*`. This will likely be fixed in Express 5.
+
+{% endcapture %}
+
+{% include admonitions/warning.html content=warning-version %}
+
+Route handlers
+
+You can provide multiple callback functions that behave like [middleware](/en/guide/using-middleware) to handle a request. The only exception is that these callbacks might invoke `next('route')` to bypass the remaining route callbacks. You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there's no reason to proceed with the current route.
+
+```js
+app.get('/user/:id', (req, res, next) => {
+ if (req.params.id === '0') {
+ return next('route');
+ }
+ res.send(`User ${req.params.id}`);
+});
+
+app.get('/user/:id', (req, res) => {
+ res.send('Special handler for user ID 0');
+});
+```
+
+In this example:
+
+- `GET /user/5` → handled by first route → sends "User 5"
+- `GET /user/0` → first route calls `next('route')`, skipping to the next matching `/user/:id` route
+
+Route handlers can be in the form of a function, an array of functions, or combinations of both, as shown in the following examples.
+
+A single callback function can handle a route. For example:
+
+```js
+app.get('/example/a', (req, res) => {
+ res.send('Hello from A!');
+});
+```
+
+More than one callback function can handle a route (make sure you specify the `next` object). For example:
+
+```js
+app.get(
+ '/example/b',
+ (req, res, next) => {
+ console.log('the response will be sent by the next function ...');
+ next();
+ },
+ (req, res) => {
+ res.send('Hello from B!');
+ }
+);
+```
+
+An array of callback functions can handle a route. For example:
+
+```js
+const cb0 = function (req, res, next) {
+ console.log('CB0');
+ next();
+};
+
+const cb1 = function (req, res, next) {
+ console.log('CB1');
+ next();
+};
+
+const cb2 = function (req, res) {
+ res.send('Hello from C!');
+};
+
+app.get('/example/c', [cb0, cb1, cb2]);
+```
+
+A combination of independent functions and arrays of functions can handle a route. For example:
+
+```js
+const cb0 = function (req, res, next) {
+ console.log('CB0');
+ next();
+};
+
+const cb1 = function (req, res, next) {
+ console.log('CB1');
+ next();
+};
+
+app.get(
+ '/example/d',
+ [cb0, cb1],
+ (req, res, next) => {
+ console.log('the response will be sent by the next function ...');
+ next();
+ },
+ (req, res) => {
+ res.send('Hello from D!');
+ }
+);
+```
+
+Response methods
+
+The methods on the response object (`res`) in the following table can send a response to the client, and terminate the request-response cycle. If none of these methods are called from a route handler, the client request will be left hanging.
+
+| Method | Description |
+| --------------------------------------------- | ------------------------------------------------------------------------------------- |
+| [res.download()](/en/5x/api#res.download) | Prompt a file to be downloaded. |
+| [res.end()](/en/5x/api#res.end) | End the response process. |
+| [res.json()](/en/5x/api#res.json) | Send a JSON response. |
+| [res.jsonp()](/en/5x/api#res.jsonp) | Send a JSON response with JSONP support. |
+| [res.redirect()](/en/5x/api#res.redirect) | Redirect a request. |
+| [res.render()](/en/5x/api#res.render) | Render a view template. |
+| [res.send()](/en/5x/api#res.send) | Send a response of various types. |
+| [res.sendFile()](/en/5x/api#res.sendFile) | Send a file as an octet stream. |
+| [res.sendStatus()](/en/5x/api#res.sendStatus) | Set the response status code and send its string representation as the response body. |
+
+app.route()
+
+You can create chainable route handlers for a route path by using `app.route()`.
+Because the path is specified at a single location, creating modular routes is helpful, as is reducing redundancy and typos. For more information about routes, see: [Router() documentation](/en/5x/api#router).
+
+Here is an example of chained route handlers that are defined by using `app.route()`.
+
+```js
+app
+ .route('/book')
+ .get((req, res) => {
+ res.send('Get a random book');
+ })
+ .post((req, res) => {
+ res.send('Add a book');
+ })
+ .put((req, res) => {
+ res.send('Update the book');
+ });
+```
+
+express.Router
+
+Use the `express.Router` class to create modular, mountable route handlers. A `Router` instance is a complete middleware and routing system; for this reason, it is often referred to as a "mini-app".
+
+The following example creates a router as a module, loads a middleware function in it, defines some routes, and mounts the router module on a path in the main app.
+
+Create a router file named `birds.js` in the app directory, with the following content:
+
+```js
+const express = require('express');
+const router = express.Router();
+
+// middleware that is specific to this router
+const timeLog = (req, res, next) => {
+ console.log('Time: ', Date.now());
+ next();
+};
+router.use(timeLog);
+
+// define the home page route
+router.get('/', (req, res) => {
+ res.send('Birds home page');
+});
+// define the about route
+router.get('/about', (req, res) => {
+ res.send('About birds');
+});
+
+module.exports = router;
+```
+
+Then, load the router module in the app:
+
+```js
+const birds = require('./birds');
+
+// ...
+
+app.use('/birds', birds);
+```
+
+The app will now be able to handle requests to `/birds` and `/birds/about`, as well as call the `timeLog` middleware function that is specific to the route.
+
+But if the parent route `/birds` has path parameters, it will not be accessible by default from the sub-routes. To make it accessible, you will need to pass the `mergeParams` option to the Router constructor [reference](/en/5x/api#app.use).
+
+```js
+const router = express.Router({ mergeParams: true });
+```
diff --git a/astro/src/content/docs/en/5x/guide/using-middleware.md b/astro/src/content/docs/en/5x/guide/using-middleware.md
new file mode 100644
index 0000000000..f5e67a0b7d
--- /dev/null
+++ b/astro/src/content/docs/en/5x/guide/using-middleware.md
@@ -0,0 +1,295 @@
+---
+title: Using Express middleware
+description: Learn how to use middleware in Express.js applications, including application-level and router-level middleware, error handling, and integrating third-party middleware.
+---
+
+# Using middleware
+
+Express is a routing and middleware web framework that has minimal functionality of its own: An Express application is essentially a series of middleware function calls.
+
+_Middleware_ functions are functions that have access to the [request object](/en/5x/api#req) (`req`), the [response object](/en/5x/api#res) (`res`), and the next middleware function in the application's request-response cycle. The next middleware function is commonly denoted by a variable named `next`.
+
+Middleware functions can perform the following tasks:
+
+- Execute any code.
+- Make changes to the request and the response objects.
+- End the request-response cycle.
+- Call the next middleware function in the stack.
+
+If the current middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Otherwise, the request will be left hanging.
+
+An Express application can use the following types of middleware:
+
+- [Application-level middleware](#middleware.application)
+- [Router-level middleware](#middleware.router)
+- [Error-handling middleware](#middleware.error-handling)
+- [Built-in middleware](#middleware.built-in)
+- [Third-party middleware](#middleware.third-party)
+
+You can load application-level and router-level middleware with an optional mount path.
+You can also load a series of middleware functions together, which creates a sub-stack of the middleware system at a mount point.
+
+Application-level middleware
+
+Bind application-level middleware to an instance of the [app object](/en/5x/api#app) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the HTTP method of the request that the middleware function handles (such as GET, PUT, or POST) in lowercase.
+
+This example shows a middleware function with no mount path. The function is executed every time the app receives a request.
+
+```js
+const express = require('express');
+const app = express();
+
+app.use((req, res, next) => {
+ console.log('Time:', Date.now());
+ next();
+});
+```
+
+This example shows a middleware function mounted on the `/user/:id` path. The function is executed for any type of
+HTTP request on the `/user/:id` path.
+
+```js
+app.use('/user/:id', (req, res, next) => {
+ console.log('Request Type:', req.method);
+ next();
+});
+```
+
+This example shows a route and its handler function (middleware system). The function handles GET requests to the `/user/:id` path.
+
+```js
+app.get('/user/:id', (req, res, next) => {
+ res.send('USER');
+});
+```
+
+Here is an example of loading a series of middleware functions at a mount point, with a mount path.
+It illustrates a middleware sub-stack that prints request info for any type of HTTP request to the `/user/:id` path.
+
+```js
+app.use(
+ '/user/:id',
+ (req, res, next) => {
+ console.log('Request URL:', req.originalUrl);
+ next();
+ },
+ (req, res, next) => {
+ console.log('Request Type:', req.method);
+ next();
+ }
+);
+```
+
+Route handlers enable you to define multiple routes for a path. The example below defines two routes for GET requests to the `/user/:id` path. The second route will not cause any problems, but it will never get called because the first route ends the request-response cycle.
+
+This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path.
+
+```js
+app.get(
+ '/user/:id',
+ (req, res, next) => {
+ console.log('ID:', req.params.id);
+ next();
+ },
+ (req, res, next) => {
+ res.send('User Info');
+ }
+);
+
+// handler for the /user/:id path, which prints the user ID
+app.get('/user/:id', (req, res, next) => {
+ res.send(req.params.id);
+});
+```
+
+To skip the rest of the middleware functions from a router middleware stack, call `next('route')` to pass control to the next route.
+
+{% capture next-function %}
+
+`next('route')` will work only in middleware functions that were loaded by using the `app.METHOD()` or `router.METHOD()` functions.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=next-function %}
+
+This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path.
+
+```js
+app.get(
+ '/user/:id',
+ (req, res, next) => {
+ // if the user ID is 0, skip to the next route
+ if (req.params.id === '0') next('route');
+ // otherwise pass the control to the next middleware function in this stack
+ else next();
+ },
+ (req, res, next) => {
+ // send a regular response
+ res.send('regular');
+ }
+);
+
+// handler for the /user/:id path, which sends a special response
+app.get('/user/:id', (req, res, next) => {
+ res.send('special');
+});
+```
+
+Middleware can also be declared in an array for reusability.
+
+This example shows an array with a middleware sub-stack that handles GET requests to the `/user/:id` path
+
+```js
+function logOriginalUrl(req, res, next) {
+ console.log('Request URL:', req.originalUrl);
+ next();
+}
+
+function logMethod(req, res, next) {
+ console.log('Request Type:', req.method);
+ next();
+}
+
+const logStuff = [logOriginalUrl, logMethod];
+app.get('/user/:id', logStuff, (req, res, next) => {
+ res.send('User Info');
+});
+```
+
+Router-level middleware
+
+Router-level middleware works in the same way as application-level middleware, except it is bound to an instance of `express.Router()`.
+
+```js
+const router = express.Router();
+```
+
+Load router-level middleware by using the `router.use()` and `router.METHOD()` functions.
+
+The following example code replicates the middleware system that is shown above for application-level middleware, by using router-level middleware:
+
+```js
+const express = require('express');
+const app = express();
+const router = express.Router();
+
+// a middleware function with no mount path. This code is executed for every request to the router
+router.use((req, res, next) => {
+ console.log('Time:', Date.now());
+ next();
+});
+
+// a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path
+router.use(
+ '/user/:id',
+ (req, res, next) => {
+ console.log('Request URL:', req.originalUrl);
+ next();
+ },
+ (req, res, next) => {
+ console.log('Request Type:', req.method);
+ next();
+ }
+);
+
+// a middleware sub-stack that handles GET requests to the /user/:id path
+router.get(
+ '/user/:id',
+ (req, res, next) => {
+ // if the user ID is 0, skip to the next router
+ if (req.params.id === '0') next('route');
+ // otherwise pass control to the next middleware function in this stack
+ else next();
+ },
+ (req, res, next) => {
+ // render a regular page
+ res.render('regular');
+ }
+);
+
+// handler for the /user/:id path, which renders a special page
+router.get('/user/:id', (req, res, next) => {
+ console.log(req.params.id);
+ res.render('special');
+});
+
+// mount the router on the app
+app.use('/', router);
+```
+
+To skip the rest of the router's middleware functions, call `next('router')`
+to pass control back out of the router instance.
+
+This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path.
+
+```js
+const express = require('express');
+const app = express();
+const router = express.Router();
+
+// predicate the router with a check and bail out when needed
+router.use((req, res, next) => {
+ if (!req.headers['x-auth']) return next('router');
+ next();
+});
+
+router.get('/user/:id', (req, res) => {
+ res.send('hello, user!');
+});
+
+// use the router and 401 anything falling through
+app.use('/admin', router, (req, res) => {
+ res.sendStatus(401);
+});
+```
+
+Error-handling middleware
+
+
+Error-handling middleware always takes _four_ arguments. You must provide four arguments to identify it as an error-handling middleware function. Even if you don't need to use the `next` object, you must specify it to maintain the signature. Otherwise, the `next` object will be interpreted as regular middleware and will fail to handle errors.
+
+
+Define error-handling middleware functions in the same way as other middleware functions, except with four arguments instead of three, specifically with the signature `(err, req, res, next)`:
+
+```js
+app.use((err, req, res, next) => {
+ console.error(err.stack);
+ res.status(500).send('Something broke!');
+});
+```
+
+For details about error-handling middleware, see: [Error handling](/en/guide/error-handling).
+
+Built-in middleware
+
+Starting with version 4.x, Express no longer depends on [Connect](https://github.com/senchalabs/connect). The middleware
+functions that were previously included with Express are now in separate modules; see [the list of middleware functions](https://github.com/senchalabs/connect#middleware).
+
+Express has the following built-in middleware functions:
+
+- [express.static](/en/5x/api#express.static) serves static assets such as HTML files, images, and so on.
+- [express.json](/en/5x/api#express.json) parses incoming requests with JSON payloads. **NOTE: Available with Express 4.16.0+**
+- [express.urlencoded](/en/5x/api#express.urlencoded) parses incoming requests with URL-encoded payloads. **NOTE: Available with Express 4.16.0+**
+
+Third-party middleware
+
+Use third-party middleware to add functionality to Express apps.
+
+Install the Node.js module for the required functionality, then load it in your app at the application level or at the router level.
+
+The following example illustrates installing and loading the cookie-parsing middleware function `cookie-parser`.
+
+```bash
+$ npm install cookie-parser
+```
+
+```js
+const express = require('express');
+const app = express();
+const cookieParser = require('cookie-parser');
+
+// load the cookie-parsing middleware
+app.use(cookieParser());
+```
+
+For a partial list of third-party middleware functions that are commonly used with Express, see: [Third-party middleware](../resources/middleware).
diff --git a/astro/src/content/docs/en/5x/guide/using-template-engines.md b/astro/src/content/docs/en/5x/guide/using-template-engines.md
new file mode 100755
index 0000000000..a3c0cc1a6f
--- /dev/null
+++ b/astro/src/content/docs/en/5x/guide/using-template-engines.md
@@ -0,0 +1,63 @@
+---
+title: Using template engines with Express
+description: Discover how to integrate and use template engines like Pug, Handlebars, and EJS with Express.js to render dynamic HTML pages efficiently.
+---
+
+# Using template engines with Express
+
+A _template engine_ enables you to use static template files in your application. At runtime, the template engine replaces
+variables in a template file with actual values, and transforms the template into an HTML file sent to the client.
+This approach makes it easier to design an HTML page.
+
+The [Express application generator](/en/starter/generator) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it also supports [Handlebars](https://www.npmjs.com/package/handlebars), and [EJS](https://www.npmjs.com/package/ejs), among others.
+
+To render template files, set the following [application setting properties](/en/4x/api#app.set), in the default `app.js` created by the generator:
+
+- `views`, the directory where the template files are located. Eg: `app.set('views', './views')`.
+ This defaults to the `views` directory in the application root directory.
+- `view engine`, the template engine to use. For example, to use the Pug template engine: `app.set('view engine', 'pug')`.
+
+Then install the corresponding template engine npm package; for example to install Pug:
+
+```bash
+$ npm install pug --save
+```
+
+
+Express-compliant template engines such as Pug export a function named `__express(filePath, options, callback)`,
+which `res.render()` calls to render the template code.
+
+Some template engines do not follow this convention. The [@ladjs/consolidate](https://www.npmjs.com/package/@ladjs/consolidate)
+library follows this convention by mapping all of the popular Node.js template engines, and therefore works seamlessly within Express.
+
+
+
+After the view engine is set, you don't have to specify the engine or load the template engine module in your app;
+Express loads the module internally, for example:
+
+```js
+app.set('view engine', 'pug');
+```
+
+Then, create a Pug template file named `index.pug` in the `views` directory, with the following content:
+
+```pug
+html
+ head
+ title= title
+ body
+ h1= message
+```
+
+Create a route to render the `index.pug` file. If the `view engine` property is not set,
+you must specify the extension of the `view` file. Otherwise, you can omit it.
+
+```js
+app.get('/', (req, res) => {
+ res.render('index', { title: 'Hey', message: 'Hello there!' });
+});
+```
+
+When you make a request to the home page, the `index.pug` file will be rendered as HTML.
+
+The view engine cache does not cache the contents of the template's output, only the underlying template itself. The view is still re-rendered with every request even when the cache is on.
diff --git a/astro/src/content/docs/en/5x/guide/writing-middleware.md b/astro/src/content/docs/en/5x/guide/writing-middleware.md
new file mode 100755
index 0000000000..b53215ad49
--- /dev/null
+++ b/astro/src/content/docs/en/5x/guide/writing-middleware.md
@@ -0,0 +1,218 @@
+---
+title: Writing middleware for use in Express apps
+description: Learn how to write custom middleware functions for Express.js applications, including examples and best practices for enhancing request and response handling.
+---
+
+# Writing middleware for use in Express apps
+
+Overview
+
+_Middleware_ functions are functions that have access to the [request object](/en/5x/api#req) (`req`), the [response object](/en/5x/api#res) (`res`), and the `next` function in the application's request-response cycle. The `next` function is a function in the Express router which, when invoked, executes the middleware succeeding the current middleware.
+
+Middleware functions can perform the following tasks:
+
+- Execute any code.
+- Make changes to the request and the response objects.
+- End the request-response cycle.
+- Call the next middleware in the stack.
+
+If the current middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Otherwise, the request will be left hanging.
+
+The following figure shows the elements of a middleware function call:
+
+
+
+Starting with Express 5, middleware functions that return a Promise will call `next(value)` when they reject or throw an error. `next` will be called with either the rejected value or the thrown Error.
+
+Example
+
+Here is an example of a simple "Hello World" Express application.
+The remainder of this article will define and add three middleware functions to the application:
+one called `myLogger` that prints a simple log message, one called `requestTime` that
+displays the timestamp of the HTTP request, and one called `validateCookies` that validates incoming cookies.
+
+```js
+const express = require('express');
+const app = express();
+
+app.get('/', (req, res) => {
+ res.send('Hello World!');
+});
+
+app.listen(3000);
+```
+
+Middleware function myLogger
+Here is a simple example of a middleware function called "myLogger". This function just prints "LOGGED" when a request to the app passes through it. The middleware function is assigned to a variable named `myLogger`.
+
+```js
+const myLogger = function (req, res, next) {
+ console.log('LOGGED');
+ next();
+};
+```
+
+
+Notice the call above to `next()`. Calling this function invokes the next middleware function in the app.
+The `next()` function is not a part of the Node.js or Express API, but is the third argument that is passed to the middleware function. The `next()` function could be named anything, but by convention it is always named "next".
+To avoid confusion, always use this convention.
+
+
+To load the middleware function, call `app.use()`, specifying the middleware function.
+For example, the following code loads the `myLogger` middleware function before the route to the root path (/).
+
+```js
+const express = require('express');
+const app = express();
+
+const myLogger = function (req, res, next) {
+ console.log('LOGGED');
+ next();
+};
+
+app.use(myLogger);
+
+app.get('/', (req, res) => {
+ res.send('Hello World!');
+});
+
+app.listen(3000);
+```
+
+Every time the app receives a request, it prints the message "LOGGED" to the terminal.
+
+The order of middleware loading is important: middleware functions that are loaded first are also executed first.
+
+If `myLogger` is loaded after the route to the root path, the request never reaches it and the app doesn't print "LOGGED", because the route handler of the root path terminates the request-response cycle.
+
+The middleware function `myLogger` simply prints a message, then passes on the request to the next middleware function in the stack by calling the `next()` function.
+
+Middleware function requestTime
+
+Next, we'll create a middleware function called "requestTime" and add a property called `requestTime`
+to the request object.
+
+```js
+const requestTime = function (req, res, next) {
+ req.requestTime = Date.now();
+ next();
+};
+```
+
+The app now uses the `requestTime` middleware function. Also, the callback function of the root path route uses the property that the middleware function adds to `req` (the request object).
+
+```js
+const express = require('express');
+const app = express();
+
+const requestTime = function (req, res, next) {
+ req.requestTime = Date.now();
+ next();
+};
+
+app.use(requestTime);
+
+app.get('/', (req, res) => {
+ let responseText = 'Hello World! ';
+ responseText += `Requested at: ${req.requestTime} `;
+ res.send(responseText);
+});
+
+app.listen(3000);
+```
+
+When you make a request to the root of the app, the app now displays the timestamp of your request in the browser.
+
+Middleware function validateCookies
+
+Finally, we'll create a middleware function that validates incoming cookies and sends a 400 response if cookies are invalid.
+
+Here's an example function that validates cookies with an external async service.
+
+```js
+async function cookieValidator(cookies) {
+ try {
+ await externallyValidateCookie(cookies.testCookie);
+ } catch {
+ throw new Error('Invalid cookies');
+ }
+}
+```
+
+Here, we use the [`cookie-parser`](/en/resources/middleware/cookie-parser) middleware to parse incoming cookies off the `req` object and pass them to our `cookieValidator` function. The `validateCookies` middleware returns a Promise that upon rejection will automatically trigger our error handler.
+
+```js
+const express = require('express');
+const cookieParser = require('cookie-parser');
+const cookieValidator = require('./cookieValidator');
+
+const app = express();
+
+async function validateCookies(req, res, next) {
+ await cookieValidator(req.cookies);
+ next();
+}
+
+app.use(cookieParser());
+
+app.use(validateCookies);
+
+// error handler
+app.use((err, req, res, next) => {
+ res.status(400).send(err.message);
+});
+
+app.listen(3000);
+```
+
+
+Note how `next()` is called after `await cookieValidator(req.cookies)`. This ensures that if `cookieValidator` resolves, the next middleware in the stack will get called. If you pass anything to the `next()` function (except the string `'route'` or `'router'`), Express regards the current request as being an error and will skip any remaining non-error handling routing and middleware functions.
+
+
+Because you have access to the request object, the response object, the next middleware function in the stack, and the whole Node.js API, the possibilities with middleware functions are endless.
+
+For more information about Express middleware, see: [Using Express middleware](/en/guide/using-middleware).
+
+Configurable middleware
+
+If you need your middleware to be configurable, export a function which accepts an options object or other parameters, which, then returns the middleware implementation based on the input parameters.
+
+File: `my-middleware.js`
+
+```js
+module.exports = function (options) {
+ return function (req, res, next) {
+ // Implement the middleware function based on the options object
+ next();
+ };
+};
+```
+
+The middleware can now be used as shown below.
+
+```js
+const mw = require('./my-middleware.js');
+
+app.use(mw({ option1: '1', option2: '2' }));
+```
+
+Refer to [cookie-session](https://github.com/expressjs/cookie-session) and [compression](https://github.com/expressjs/compression) for examples of configurable middleware.
diff --git a/astro/src/content/docs/en/5x/starter/basic-routing.md b/astro/src/content/docs/en/5x/starter/basic-routing.md
new file mode 100755
index 0000000000..3bc26bc546
--- /dev/null
+++ b/astro/src/content/docs/en/5x/starter/basic-routing.md
@@ -0,0 +1,63 @@
+---
+title: Express basic routing
+description: Learn the fundamentals of routing in Express.js applications, including how to define routes, handle HTTP methods, and create route handlers for your web server.
+---
+
+# Basic routing
+
+_Routing_ refers to determining how an application responds to a client request to a particular endpoint, which is a URI (or path) and a specific HTTP request method (GET, POST, and so on).
+
+Each route can have one or more handler functions, which are executed when the route is matched.
+
+Route definition takes the following structure:
+
+```js
+app.METHOD(PATH, HANDLER);
+```
+
+Where:
+
+- `app` is an instance of `express`.
+- `METHOD` is an [HTTP request method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods), in lowercase.
+- `PATH` is a path on the server.
+- `HANDLER` is the function executed when the route is matched.
+
+
+This tutorial assumes that an instance of `express` named `app` is created and the server is running. If you are not familiar with creating an app and starting it, see the [Hello world example](/en/starter/hello-world).
+
+
+The following examples illustrate defining simple routes.
+
+Respond with `Hello World!` on the homepage:
+
+```js
+app.get('/', (req, res) => {
+ res.send('Hello World!');
+});
+```
+
+Respond to a POST request on the root route (`/`), the application's home page:
+
+```js
+app.post('/', (req, res) => {
+ res.send('Got a POST request');
+});
+```
+
+Respond to a PUT request to the `/user` route:
+
+```js
+app.put('/user', (req, res) => {
+ res.send('Got a PUT request at /user');
+});
+```
+
+Respond to a DELETE request to the `/user` route:
+
+```js
+app.delete('/user', (req, res) => {
+ res.send('Got a DELETE request at /user');
+});
+```
+
+For more details about routing, see the [routing guide](/en/guide/routing).
diff --git a/astro/src/content/docs/en/5x/starter/examples.md b/astro/src/content/docs/en/5x/starter/examples.md
new file mode 100755
index 0000000000..a25a6d9834
--- /dev/null
+++ b/astro/src/content/docs/en/5x/starter/examples.md
@@ -0,0 +1,16 @@
+---
+title: Express examples
+description: Explore a collection of Express.js application examples covering various use cases, integrations, and advanced configurations to help you learn and build your projects.
+---
+
+{% capture examples %}{% include readmes/express-master/examples.md %}{% endcapture %}
+{{ examples | replace: "](.", "](https://github.com/expressjs/express/tree/master/examples" }}
+
+## Additional examples
+
+These are some additional examples with more extensive integrations.
+
+{% include community-caveat.html %}
+
+- [prisma-fullstack](https://github.com/prisma/prisma-examples/tree/latest/pulse/fullstack-simple-chat) - Fullstack app with Express and Next.js using [Prisma](https://www.npmjs.com/package/prisma) as an ORM
+- [prisma-rest-api-ts](https://github.com/prisma/prisma-examples/tree/latest/orm/express) - REST API with Express in TypeScript using [Prisma](https://www.npmjs.com/package/prisma) as an ORM
diff --git a/astro/src/content/docs/en/5x/starter/faq.md b/astro/src/content/docs/en/5x/starter/faq.md
new file mode 100755
index 0000000000..7c82d80c50
--- /dev/null
+++ b/astro/src/content/docs/en/5x/starter/faq.md
@@ -0,0 +1,92 @@
+---
+title: Express FAQ
+description: Find answers to frequently asked questions about Express.js, including topics on application structure, models, authentication, template engines, error handling, and more.
+---
+
+# FAQ
+
+## How should I structure my application?
+
+There is no definitive answer to this question. The answer depends
+on the scale of your application and the team that is involved. To be as
+flexible as possible, Express makes no assumptions in terms of structure.
+
+Routes and other application-specific logic can live in as many files
+as you wish, in any directory structure you prefer. View the following
+examples for inspiration:
+
+- [Route listings](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-L47)
+- [Route map](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66)
+- [MVC style controllers](https://github.com/expressjs/express/tree/master/examples/mvc)
+
+Also, there are third-party extensions for Express, which simplify some of these patterns:
+
+- [Resourceful routing](https://github.com/expressjs/express-resource)
+
+## How do I define models?
+
+Express has no notion of a database. This concept is
+left up to third-party Node modules, allowing you to
+interface with nearly any database.
+
+See [LoopBack](http://loopback.io) for an Express-based framework that is centered around models.
+
+## How can I authenticate users?
+
+Authentication is another opinionated area that Express does not
+venture into. You may use any authentication scheme you wish.
+For a simple username / password scheme, see [this example](https://github.com/expressjs/express/tree/master/examples/auth).
+
+## Which template engines does Express support?
+
+Express supports any template engine that conforms with the `(path, locals, callback)` signature.
+To normalize template engine interfaces and caching, see the
+[consolidate.js](https://github.com/visionmedia/consolidate.js)
+project for support. Unlisted template engines might still support the Express signature.
+
+For more information, see [Using template engines with Express](/en/guide/using-template-engines).
+
+## How do I handle 404 responses?
+
+In Express, 404 responses are not the result of an error, so
+the error-handler middleware will not capture them. This behavior is
+because a 404 response simply indicates the absence of additional work to do;
+in other words, Express has executed all middleware functions and routes,
+and found that none of them responded. All you need to
+do is add a middleware function at the very bottom of the stack (below all other functions)
+to handle a 404 response:
+
+```js
+app.use((req, res, next) => {
+ res.status(404).send("Sorry can't find that!");
+});
+```
+
+Add routes dynamically at runtime on an instance of `express.Router()`
+so the routes are not superseded by a middleware function.
+
+## How do I setup an error handler?
+
+You define error-handling middleware in the same way as other middleware,
+except with four arguments instead of three; specifically with the signature `(err, req, res, next)`:
+
+```js
+app.use((err, req, res, next) => {
+ console.error(err.stack);
+ res.status(500).send('Something broke!');
+});
+```
+
+For more information, see [Error handling](/en/guide/error-handling).
+
+## How do I render plain HTML?
+
+You don't! There's no need to "render" HTML with the `res.render()` function.
+If you have a specific file, use the `res.sendFile()` function.
+If you are serving many assets from a directory, use the `express.static()`
+middleware function.
+
+## What version of Node.js does Express require?
+
+- [Express 4.x](/en/4x/api) requires Node.js 0.10 or higher.
+- [Express 5.x](/en/5x/api) requires Node.js 18 or higher.
diff --git a/astro/src/content/docs/en/5x/starter/generator.md b/astro/src/content/docs/en/5x/starter/generator.md
new file mode 100755
index 0000000000..4ee5058a18
--- /dev/null
+++ b/astro/src/content/docs/en/5x/starter/generator.md
@@ -0,0 +1,122 @@
+---
+title: Express application generator
+description: Learn how to use the Express application generator tool to quickly create a skeleton for your Express.js applications, streamlining setup and configuration.
+---
+
+# Express application generator
+
+Use the application generator tool, `express-generator`, to quickly create an application skeleton.
+
+You can run the application generator with the `npx` command (available in Node.js 8.2.0).
+
+```bash
+$ npx express-generator
+```
+
+For earlier Node versions, install the application generator as a global npm package and then launch it:
+
+```bash
+$ npm install -g express-generator
+$ express
+```
+
+Display the command options with the `-h` option:
+
+```bash
+$ express -h
+
+ Usage: express [options] [dir]
+
+ Options:
+
+ -h, --help output usage information
+ --version output the version number
+ -e, --ejs add ejs engine support
+ --hbs add handlebars engine support
+ --pug add pug engine support
+ -H, --hogan add hogan.js engine support
+ --no-view generate without view engine
+ -v, --view add view support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
+ -c, --css add stylesheet support (less|stylus|compass|sass) (defaults to plain css)
+ --git add .gitignore
+ -f, --force force on non-empty directory
+```
+
+For example, the following creates an Express app named _myapp_. The app will be created in a folder named _myapp_ in the current working directory and the view engine will be set to Pug :
+
+```bash
+$ express --view=pug myapp
+
+ create : myapp
+ create : myapp/package.json
+ create : myapp/app.js
+ create : myapp/public
+ create : myapp/public/javascripts
+ create : myapp/public/images
+ create : myapp/routes
+ create : myapp/routes/index.js
+ create : myapp/routes/users.js
+ create : myapp/public/stylesheets
+ create : myapp/public/stylesheets/style.css
+ create : myapp/views
+ create : myapp/views/index.pug
+ create : myapp/views/layout.pug
+ create : myapp/views/error.pug
+ create : myapp/bin
+ create : myapp/bin/www
+```
+
+Then install dependencies:
+
+```bash
+$ cd myapp
+$ npm install
+```
+
+On MacOS or Linux, run the app with this command:
+
+```bash
+$ DEBUG=myapp:* npm start
+```
+
+On Windows Command Prompt, use this command:
+
+```bash
+> set DEBUG=myapp:* & npm start
+```
+
+On Windows PowerShell, use this command:
+
+```bash
+PS> $env:DEBUG='myapp:*'; npm start
+```
+
+Then, load `http://localhost:3000/` in your browser to access the app.
+
+The generated app has the following directory structure:
+
+```bash
+.
+├── app.js
+├── bin
+│ └── www
+├── package.json
+├── public
+│ ├── images
+│ ├── javascripts
+│ └── stylesheets
+│ └── style.css
+├── routes
+│ ├── index.js
+│ └── users.js
+└── views
+ ├── error.pug
+ ├── index.pug
+ └── layout.pug
+
+7 directories, 9 files
+```
+
+
+The app structure created by the generator is just one of many ways to structure Express apps. Feel free to use this structure or modify it to best suit your needs.
+
diff --git a/astro/src/content/docs/en/5x/starter/hello-world.md b/astro/src/content/docs/en/5x/starter/hello-world.md
new file mode 100755
index 0000000000..97da56d686
--- /dev/null
+++ b/astro/src/content/docs/en/5x/starter/hello-world.md
@@ -0,0 +1,46 @@
+---
+title: Express "Hello World" example
+description: Get started with Express.js by building a simple 'Hello World' application, demonstrating the basic setup and server creation for beginners.
+---
+
+# Hello world example
+
+
+Embedded below is essentially the simplest Express app you can create. It is a single file app — _not_ what you'd get if you use the [Express generator](/en/starter/generator), which creates the scaffolding for a full app with numerous JavaScript files, Jade templates, and sub-directories for various purposes.
+
+
+```js
+const express = require('express');
+const app = express();
+const port = 3000;
+
+app.get('/', (req, res) => {
+ res.send('Hello World!');
+});
+
+app.listen(port, () => {
+ console.log(`Example app listening on port ${port}`);
+});
+```
+
+This app starts a server and listens on port 3000 for connections. The app responds with "Hello World!" for requests
+to the root URL (`/`) or _route_. For every other path, it will respond with a **404 Not Found**.
+
+### Running Locally
+
+First create a directory named `myapp`, change to it and run `npm init`. Then, install `express` as a dependency, as per the [installation guide](/en/starter/installing).
+
+In the `myapp` directory, create a file named `app.js` and copy the code from the example above.
+
+
+The `req` (request) and `res` (response) are the exact same objects that Node provides, so you can invoke
+`req.pipe()`, `req.on('data', callback)`, and anything else you would do without Express involved.
+
+
+Run the app with the following command:
+
+```bash
+$ node app.js
+```
+
+Then, load `http://localhost:3000/` in a browser to see the output.
diff --git a/astro/src/content/docs/en/5x/starter/installing.mdx b/astro/src/content/docs/en/5x/starter/installing.mdx
new file mode 100755
index 0000000000..d989d04a60
--- /dev/null
+++ b/astro/src/content/docs/en/5x/starter/installing.mdx
@@ -0,0 +1,63 @@
+---
+title: Installing Express
+description: Learn how to install Express.js in your Node.js environment, including setting up your project directory and managing dependencies with npm.
+---
+
+import Alert from '@components/primitives/Alert/Alert.astro';
+
+# Installing
+
+
+ Express 5.x is still in beta. Some APIs may change before the final release. Avoid using it in
+ production without first reviewing the [migration guide](/en/guide/migrating-5).
+
+
+
+ Never commit your `node_modules` directory to version control. Add it to your `.gitignore` to
+ prevent accidentally exposing local paths or platform-specific binaries.
+
+
+
+ By default with npm 5.0+, `npm install` adds the module to the `dependencies` list in the
+ `package.json` file. With earlier versions of npm, you must specify the `--save` option
+ explicitly. Afterwards, running `npm install` in the app directory will automatically install all
+ modules in the dependencies list.
+
+
+Assuming you've already installed [Node.js](https://nodejs.org/), create a directory to hold your application, and make that your working directory.
+
+- [Express 4.x](/en/4x/api) requires Node.js 0.10 or higher.
+- [Express 5.x](/en/5x/api) requires Node.js 18 or higher.
+
+```bash
+$ mkdir myapp
+$ cd myapp
+```
+
+Use the `npm init` command to create a `package.json` file for your application.
+For more information on how `package.json` works, see [Specifics of npm's package.json handling](https://docs.npmjs.com/files/package.json).
+
+```bash
+$ npm init
+```
+
+This command prompts you for a number of things, such as the name and version of your application.
+For now, you can simply hit RETURN to accept the defaults for most of them, with the following exception:
+
+```
+entry point: (index.js)
+```
+
+Enter `app.js`, or whatever you want the name of the main file to be. If you want it to be `index.js`, hit RETURN to accept the suggested default file name.
+
+Now, install Express in the `myapp` directory and save it in the dependencies list. For example:
+
+```bash
+$ npm install express
+```
+
+To install Express temporarily and not add it to the dependencies list:
+
+```bash
+$ npm install express --no-save
+```
diff --git a/astro/src/content/docs/en/5x/starter/static-files.md b/astro/src/content/docs/en/5x/starter/static-files.md
new file mode 100755
index 0000000000..652de2690e
--- /dev/null
+++ b/astro/src/content/docs/en/5x/starter/static-files.md
@@ -0,0 +1,76 @@
+---
+title: Serving static files in Express
+description: Understand how to serve static files like images, CSS, and JavaScript in Express.js applications using the built-in 'static' middleware.
+---
+
+# Serving static files in Express
+
+To serve static files such as images, CSS files, and JavaScript files, use the `express.static` built-in middleware function in Express.
+
+The function signature is:
+
+```js
+express.static(root, [options]);
+```
+
+The `root` argument specifies the root directory from which to serve static assets.
+For more information on the `options` argument, see [express.static](/en/5x/api#express.static).
+
+For example, use the following code to serve images, CSS files, and JavaScript files in a directory named `public`:
+
+```js
+app.use(express.static('public'));
+```
+
+Now, you can load the files that are in the `public` directory:
+
+```text
+http://localhost:3000/images/kitten.jpg
+http://localhost:3000/css/style.css
+http://localhost:3000/js/app.js
+http://localhost:3000/images/bg.png
+http://localhost:3000/hello.html
+```
+
+
+Express looks up the files relative to the static directory, so the name of the static directory is not part of the URL.
+
+
+To use multiple static assets directories, call the `express.static` middleware function multiple times:
+
+```js
+app.use(express.static('public'));
+app.use(express.static('files'));
+```
+
+Express looks up the files in the order in which you set the static directories with the `express.static` middleware function.
+
+{% capture alert_content %}
+For best results, [use a reverse proxy](/en/advanced/best-practice-performance#use-a-reverse-proxy) cache to improve performance of serving static assets.
+{% endcapture %}
+{% include admonitions/note.html content=alert_content %}
+
+To create a virtual path prefix (where the path does not actually exist in the file system) for files that are served by the `express.static` function, [specify a mount path](/en/5x/api#app.use) for the static directory, as shown below:
+
+```js
+app.use('/static', express.static('public'));
+```
+
+Now, you can load the files that are in the `public` directory from the `/static` path prefix.
+
+```text
+http://localhost:3000/static/images/kitten.jpg
+http://localhost:3000/static/css/style.css
+http://localhost:3000/static/js/app.js
+http://localhost:3000/static/images/bg.png
+http://localhost:3000/static/hello.html
+```
+
+However, the path that you provide to the `express.static` function is relative to the directory from where you launch your `node` process. If you run the express app from another directory, it's safer to use the absolute path of the directory that you want to serve:
+
+```js
+const path = require('path');
+app.use('/static', express.static(path.join(__dirname, 'public')));
+```
+
+For more details about the `serve-static` function and its options, see [serve-static](/en/resources/middleware/serve-static).
diff --git a/astro/src/content/docs/es/3x/api.md b/astro/src/content/docs/es/3x/api.md
new file mode 100644
index 0000000000..f7f2148877
--- /dev/null
+++ b/astro/src/content/docs/es/3x/api.md
@@ -0,0 +1,23 @@
+---
+version: 3x
+title: Express 3.x - Referencia de API
+description: Access the API reference for Express.js version 3.x, noting that this version is end-of-life and no longer maintained - includes details on modules and methods.
+---
+
+
+
+
+ **Express 3.x YA NO SE MANTIENE**
+
+Los problemas de rendimiento y seguridad conocidos y desconocidos en 3.x no se han solucionado desde la última actualización (1 de agosto de 2015). Se recomienda especialmente utilizar la última versión de Express.
+
+If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/en/support#commercial-support-options).
+
+
+
+
API de 3.x
+
+
+{% include api/en/3x/app.md %}
+
+
diff --git a/astro/src/content/docs/es/4x/api.md b/astro/src/content/docs/es/4x/api.md
new file mode 100644
index 0000000000..32f222a249
--- /dev/null
+++ b/astro/src/content/docs/es/4x/api.md
@@ -0,0 +1,26 @@
+---
+version: 4x
+title: Express 4.x - Referencia de API
+description: Access the API reference for Express.js 4.x, detailing all modules, methods, and properties for building web applications with this version.
+---
+
+
+
+
API de 4.x
+
+{% capture node-version %}
+
+Express 4.0 requires Node.js 0.10 or higher.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=node-version %}
+
+
+{% include api/en/4x/express.md %}
+{% include api/en/4x/app.md %}
+{% include api/en/4x/req.md %}
+{% include api/en/4x/res.md %}
+{% include api/en/4x/router.md %}
+
+
diff --git a/astro/src/content/docs/es/5x/advanced/best-practice-performance.md b/astro/src/content/docs/es/5x/advanced/best-practice-performance.md
new file mode 100644
index 0000000000..e9e4134cee
--- /dev/null
+++ b/astro/src/content/docs/es/5x/advanced/best-practice-performance.md
@@ -0,0 +1,307 @@
+---
+title: Performance Best Practices Using Express in Production
+description: Discover performance and reliability best practices for Express apps in production, covering code optimizations and environment setups for optimal performance.
+---
+
+# Production best practices: performance and reliabilityss
+
+This article discusses performance and reliability best practices for Express applications deployed to production.
+
+This topic clearly falls into the "devops" world, spanning both traditional development and operations. Accordingly, the information is divided into two parts:
+
+- Things to do in your code (the dev part):
+ - [Use gzip compression](#use-gzip-compression)
+ - [Don't use synchronous functions](#dont-use-synchronous-functions)
+ - [Do logging correctly](#do-logging-correctly)
+ - [Handle exceptions properly](#handle-exceptions-properly)
+- Things to do in your environment / setup (the ops part):
+ - [Set NODE_ENV to "production"](#set-node_env-to-production)
+ - [Ensure your app automatically restarts](#ensure-your-app-automatically-restarts)
+ - [Run your app in a cluster](#run-your-app-in-a-cluster)
+ - [Cache request results](#cache-request-results)
+ - [Use a load balancer](#use-a-load-balancer)
+ - [Use a reverse proxy](#use-a-reverse-proxy)
+
+## Things to do in your code {#in-code}
+
+Here are some things you can do in your code to improve your application's performance:
+
+- [Use gzip compression](#use-gzip-compression)
+- [Don't use synchronous functions](#dont-use-synchronous-functions)
+- [Do logging correctly](#do-logging-correctly)
+- [Handle exceptions properly](#handle-exceptions-properly)
+
+### Use gzip compression
+
+Gzip compressing can greatly decrease the size of the response body and hence increase the speed of a web app. Use the [compression](https://www.npmjs.com/package/compression) middleware for gzip compression in your Express app. For example:
+
+```js
+const compression = require('compression');
+const express = require('express');
+const app = express();
+
+app.use(compression());
+```
+
+For a high-traffic website in production, the best way to put compression in place is to implement it at a reverse proxy level (see [Use a reverse proxy](#use-a-reverse-proxy)). In that case, you do not need to use compression middleware. For details on enabling gzip compression in Nginx, see [Module ngx_http_gzip_module](http://nginx.org/en/docs/http/ngx_http_gzip_module) in the Nginx documentation.
+
+### Don't use synchronous functions
+
+Synchronous functions and methods tie up the executing process until they return. A single call to a synchronous function might return in a few microseconds or milliseconds, however in high-traffic websites, these calls add up and reduce the performance of the app. Avoid their use in production.
+
+Although Node and many modules provide synchronous and asynchronous versions of their functions, always use the asynchronous version in production. The only time when a synchronous function can be justified is upon initial startup.
+
+You can use the `--trace-sync-io` command-line flag to print a warning and a stack trace whenever your application uses a synchronous API. Of course, you wouldn't want to use this in production, but rather to ensure that your code is ready for production. See the [node command-line options documentation](https://nodejs.org/api/cli#cli_trace_sync_io) for more information.
+
+### Do logging correctly
+
+In general, there are two reasons for logging from your app: For debugging and for logging app activity (essentially, everything else). Using `console.log()` or `console.error()` to print log messages to the terminal is common practice in development. But [these functions are synchronous](https://nodejs.org/api/console#console) when the destination is a terminal or a file, so they are not suitable for production, unless you pipe the output to another program.
+
+#### For debugging
+
+If you're logging for purposes of debugging, then instead of using `console.log()`, use a special debugging module like [debug](https://www.npmjs.com/package/debug). This module enables you to use the DEBUG environment variable to control what debug messages are sent to `console.error()`, if any. To keep your app purely asynchronous, you'd still want to pipe `console.error()` to another program. But then, you're not really going to debug in production, are you?
+
+#### For app activity
+
+If you're logging app activity (for example, tracking traffic or API calls), instead of using `console.log()`, use a logging library like [Pino](https://www.npmjs.com/package/pino), which is the fastest and most efficient option available.
+
+### Handle exceptions properly
+
+Node apps crash when they encounter an uncaught exception. Not handling exceptions and taking appropriate actions will make your Express app crash and go offline. If you follow the advice in [Ensure your app automatically restarts](#ensure-your-app-automatically-restarts) below, then your app will recover from a crash. Fortunately, Express apps typically have a short startup time. Nevertheless, you want to avoid crashing in the first place, and to do that, you need to handle exceptions properly.
+
+To ensure you handle all exceptions, use the following techniques:
+
+- [Use try-catch](#use-try-catch)
+- [Use promises](#use-promises)
+
+Before diving into these topics, you should have a basic understanding of Node/Express error handling: using error-first callbacks, and propagating errors in middleware. Node uses an "error-first callback" convention for returning errors from asynchronous functions, where the first parameter to the callback function is the error object, followed by result data in succeeding parameters. To indicate no error, pass null as the first parameter. The callback function must correspondingly follow the error-first callback convention to meaningfully handle the error. And in Express, the best practice is to use the next() function to propagate errors through the middleware chain.
+
+For more on the fundamentals of error handling, see:
+
+- [Error Handling in Node.js](https://www.tritondatacenter.com/node-js/production/design/errors)
+
+#### Use try-catch
+
+Try-catch is a JavaScript language construct that you can use to catch exceptions in synchronous code. Use try-catch, for example, to handle JSON parsing errors as shown below.
+
+Here is an example of using try-catch to handle a potential process-crashing exception.
+This middleware function accepts a query field parameter named "params" that is a JSON object.
+
+```js
+app.get('/search', (req, res) => {
+ // Simulating async operation
+ setImmediate(() => {
+ const jsonStr = req.query.params;
+ try {
+ const jsonObj = JSON.parse(jsonStr);
+ res.send('Success');
+ } catch (e) {
+ res.status(400).send('Invalid JSON string');
+ }
+ });
+});
+```
+
+However, try-catch works only for synchronous code. Because the Node platform is primarily asynchronous (particularly in a production environment), try-catch won't catch a lot of exceptions.
+
+#### Use promises
+
+When an error is thrown in an `async` function or a rejected promise is awaited inside an `async` function, those errors will be passed to the error handler as if calling `next(err)`
+
+```js
+app.get('/', async (req, res, next) => {
+ const data = await userData(); // If this promise fails, it will automatically call `next(err)` to handle the error.
+
+ res.send(data);
+});
+
+app.use((err, req, res, next) => {
+ res.status(err.status ?? 500).send({ error: err.message });
+});
+```
+
+Also, you can use asynchronous functions for your middleware, and the router will handle errors if the promise fails, for example:
+
+```js
+app.use(async (req, res, next) => {
+ req.locals.user = await getUser(req);
+
+ next(); // This will be called if the promise does not throw an error.
+});
+```
+
+Best practice is to handle errors as close to the site as possible. So while this is now handled in the router, it’s best to catch the error in the middleware and handle it without relying on separate error-handling middleware.
+
+#### What not to do
+
+One thing you should _not_ do is to listen for the `uncaughtException` event, emitted when an exception bubbles all the way back to the event loop. Adding an event listener for `uncaughtException` will change the default behavior of the process that is encountering an exception; the process will continue to run despite the exception. This might sound like a good way of preventing your app from crashing, but continuing to run the app after an uncaught exception is a dangerous practice and is not recommended, because the state of the process becomes unreliable and unpredictable.
+
+Additionally, using `uncaughtException` is officially recognized as [crude](https://nodejs.org/api/process#process_event_uncaughtexception). So listening for `uncaughtException` is just a bad idea. This is why we recommend things like multiple processes and supervisors: crashing and restarting is often the most reliable way to recover from an error.
+
+We also don't recommend using [domains](https://nodejs.org/api/domain). It generally doesn't solve the problem and is a deprecated module.
+
+## Things to do in your environment / setup {#in-environment}
+
+Here are some things you can do in your system environment to improve your app's performance:
+
+- [Set NODE_ENV to "production"](#set-node_env-to-production)
+- [Ensure your app automatically restarts](#ensure-your-app-automatically-restarts)
+- [Run your app in a cluster](#run-your-app-in-a-cluster)
+- [Cache request results](#cache-request-results)
+- [Use a load balancer](#use-a-load-balancer)
+- [Use a reverse proxy](#use-a-reverse-proxy)
+
+### Set NODE_ENV to "production"
+
+The NODE_ENV environment variable specifies the environment in which an application is running (usually, development or production). One of the simplest things you can do to improve performance is to set NODE_ENV to `production`.
+
+Setting NODE_ENV to "production" makes Express:
+
+- Cache view templates.
+- Cache CSS files generated from CSS extensions.
+- Generate less verbose error messages.
+
+[Tests indicate](https://www.dynatrace.com/news/blog/the-drastic-effects-of-omitting-node-env-in-your-express-js-applications/) that just doing this can improve app performance by a factor of three!
+
+If you need to write environment-specific code, you can check the value of NODE_ENV with `process.env.NODE_ENV`. Be aware that checking the value of any environment variable incurs a performance penalty, and so should be done sparingly.
+
+In development, you typically set environment variables in your interactive shell, for example by using `export` or your `.bash_profile` file. But in general, you shouldn't do that on a production server; instead, use your OS's init system (systemd). The next section provides more details about using your init system in general, but setting `NODE_ENV` is so important for performance (and easy to do), that it's highlighted here.
+
+With systemd, use the `Environment` directive in your unit file. For example:
+
+```sh
+# /etc/systemd/system/myservice.service
+Environment=NODE_ENV=production
+```
+
+For more information, see [Using Environment Variables In systemd Units](https://www.flatcar.org/docs/latest/setup/systemd/environment-variables/).
+
+### Ensure your app automatically restarts
+
+In production, you don't want your application to be offline, ever. This means you need to make sure it restarts both if the app crashes and if the server itself crashes. Although you hope that neither of those events occurs, realistically you must account for both eventualities by:
+
+- Using a process manager to restart the app (and Node) when it crashes.
+- Using the init system provided by your OS to restart the process manager when the OS crashes. It's also possible to use the init system without a process manager.
+
+Node applications crash if they encounter an uncaught exception. The foremost thing you need to do is to ensure your app is well-tested and handles all exceptions (see [handle exceptions properly](#handle-exceptions-properly) for details). But as a fail-safe, put a mechanism in place to ensure that if and when your app crashes, it will automatically restart.
+
+#### Use a process manager
+
+In development, you started your app simply from the command line with `node server.js` or something similar. But doing this in production is a recipe for disaster. If the app crashes, it will be offline until you restart it. To ensure your app restarts if it crashes, use a process manager. A process manager is a "container" for applications that facilitates deployment, provides high availability, and enables you to manage the application at runtime.
+
+In addition to restarting your app when it crashes, a process manager can enable you to:
+
+- Gain insights into runtime performance and resource consumption.
+- Modify settings dynamically to improve performance.
+- Control clustering (pm2).
+
+Historically, it was popular to use a Node.js process manager like [PM2](https://github.com/Unitech/pm2). See their documentation if you wish to do this. However, we recommend using your init system for process management.
+
+#### Use an init system
+
+The next layer of reliability is to ensure that your app restarts when the server restarts. Systems can still go down for a variety of reasons. To ensure that your app restarts if the server crashes, use the init system built into your OS. The main init system in use today is [systemd](https://wiki.debian.org/systemd).
+
+There are two ways to use init systems with your Express app:
+
+- Run your app in a process manager, and install the process manager as a service with the init system. The process manager will restart your app when the app crashes, and the init system will restart the process manager when the OS restarts. This is the recommended approach.
+- Run your app (and Node) directly with the init system. This is somewhat simpler, but you don't get the additional advantages of using a process manager.
+
+##### Systemd
+
+Systemd is a Linux system and service manager. Most major Linux distributions have adopted systemd as their default init system.
+
+A systemd service configuration file is called a _unit file_, with a filename ending in `.service`. Here's an example unit file to manage a Node app directly. Replace the values enclosed in `` for your system and app:
+
+```sh
+[Unit]
+Description=
+
+[Service]
+Type=simple
+ExecStart=/usr/local/bin/node
+WorkingDirectory=
+
+User=nobody
+Group=nogroup
+
+# Environment variables:
+Environment=NODE_ENV=production
+
+# Allow many incoming connections
+LimitNOFILE=infinity
+
+# Allow core dumps for debugging
+LimitCORE=infinity
+
+StandardInput=null
+StandardOutput=syslog
+StandardError=syslog
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
+```
+
+For more information on systemd, see the [systemd reference (man page)](http://www.freedesktop.org/software/systemd/man/systemd.unit).
+
+### Run your app in a cluster
+
+In a multi-core system, you can increase the performance of a Node app by many times by launching a cluster of processes. A cluster runs multiple instances of the app, ideally one instance on each CPU core, thereby distributing the load and tasks among the instances.
+
+
+
+IMPORTANT: Since the app instances run as separate processes, they do not share the same memory space. That is, objects are local to each instance of the app. Therefore, you cannot maintain state in the application code. However, you can use an in-memory datastore like [Redis](http://redis.io/) to store session-related data and state. This caveat applies to essentially all forms of horizontal scaling, whether clustering with multiple processes or multiple physical servers.
+
+In clustered apps, worker processes can crash individually without affecting the rest of the processes. Apart from performance advantages, failure isolation is another reason to run a cluster of app processes. Whenever a worker process crashes, always make sure to log the event and spawn a new process using cluster.fork().
+
+#### Using Node's cluster module
+
+Clustering is made possible with Node's [cluster module](https://nodejs.org/api/cluster). This enables a master process to spawn worker processes and distribute incoming connections among the workers.
+
+#### Using PM2
+
+If you deploy your application with PM2, then you can take advantage of clustering _without_ modifying your application code. You should ensure your [application is stateless](https://pm2.keymetrics.io/docs/usage/specifics/#stateless-apps) first, meaning no local data is stored in the process (such as sessions, websocket connections and the like).
+
+When running an application with PM2, you can enable **cluster mode** to run it in a cluster with a number of instances of your choosing, such as the matching the number of available CPUs on the machine. You can manually change the number of processes in the cluster using the `pm2` command line tool without stopping the app.
+
+To enable cluster mode, start your application like so:
+
+```bash
+# Start 4 worker processes
+$ pm2 start npm --name my-app -i 4 -- start
+# Auto-detect number of available CPUs and start that many worker processes
+$ pm2 start npm --name my-app -i max -- start
+```
+
+This can also be configured within a PM2 process file (`ecosystem.config.js` or similar) by setting `exec_mode` to `cluster` and `instances` to the number of workers to start.
+
+Once running, the application can be scaled like so:
+
+```bash
+# Add 3 more workers
+$ pm2 scale my-app +3
+# Scale to a specific number of workers
+$ pm2 scale my-app 2
+```
+
+For more information on clustering with PM2, see [Cluster Mode](https://pm2.keymetrics.io/docs/usage/cluster-mode/) in the PM2 documentation.
+
+### Cache request results
+
+Another strategy to improve the performance in production is to cache the result of requests, so that your app does not repeat the operation to serve the same request repeatedly.
+
+Use a caching server like [Varnish](https://www.varnish-cache.org/) or [Nginx](https://blog.nginx.org/blog/nginx-caching-guide) (see also [Nginx Caching](https://serversforhackers.com/nginx-caching/)) to greatly improve the speed and performance of your app.
+
+### Use a load balancer
+
+No matter how optimized an app is, a single instance can handle only a limited amount of load and traffic. One way to scale an app is to run multiple instances of it and distribute the traffic via a load balancer. Setting up a load balancer can improve your app's performance and speed, and enable it to scale more than is possible with a single instance.
+
+A load balancer is usually a reverse proxy that orchestrates traffic to and from multiple application instances and servers. You can easily set up a load balancer for your app by using [Nginx](https://nginx.org/en/docs/http/load_balancing) or [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts).
+
+With load balancing, you might have to ensure that requests that are associated with a particular session ID connect to the process that originated them. This is known as _session affinity_, or _sticky sessions_, and may be addressed by the suggestion above to use a data store such as Redis for session data (depending on your application). For a discussion, see [Using multiple nodes](https://socket.io/docs/v4/using-multiple-nodes/).
+
+### Use a reverse proxy
+
+A reverse proxy sits in front of a web app and performs supporting operations on the requests, apart from directing requests to the app. It can handle error pages, compression, caching, serving files, and load balancing among other things.
+
+Handing over tasks that do not require knowledge of application state to a reverse proxy frees up Express to perform specialized application tasks. For this reason, it is recommended to run Express behind a reverse proxy like [Nginx](https://www.nginx.org/) or [HAProxy](https://www.haproxy.org/) in production.
diff --git a/astro/src/content/docs/es/5x/api.md b/astro/src/content/docs/es/5x/api.md
new file mode 100644
index 0000000000..8f4978f308
--- /dev/null
+++ b/astro/src/content/docs/es/5x/api.md
@@ -0,0 +1,26 @@
+---
+version: 5x
+title: Express 5.x - Referencia de API
+description: Access the API reference for Express.js 5.x, detailing all modules, methods, and properties for building web applications with this latest version.
+---
+
+
+
+
5.x API
+
+{% capture node-version %}
+
+Express 5.0 requires Node.js 18 or higher.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=node-version %}
+
+
+{% include api/en/5x/express.md %}
+{% include api/en/5x/app.md %}
+{% include api/en/5x/req.md %}
+{% include api/en/5x/res.md %}
+{% include api/en/5x/router.md %}
+
+
diff --git a/astro/src/content/docs/fr/3x/api.md b/astro/src/content/docs/fr/3x/api.md
new file mode 100644
index 0000000000..dc184b0a08
--- /dev/null
+++ b/astro/src/content/docs/fr/3x/api.md
@@ -0,0 +1,23 @@
+---
+version: 3x
+title: Express 3.x - Référence de l'API
+description: Access the API reference for Express.js version 3.x, noting that this version is end-of-life and no longer maintained - includes details on modules and methods.
+---
+
+
+
+
+ **Express 3.x N'EST PLUS PRIS EN CHARGE**
+
+Les problèmes de performances et de sécurité connus et inconnus n'ont pas été traités depuis la dernière mise à jour (1er août 2015). Il est fortement recommandé d'utiliser la dernière version d'Express.
+
+If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/en/support#commercial-support-options).
+
+
+
+
API 3.x
+
+
+{% include api/en/3x/app.md %}
+
+
diff --git a/astro/src/content/docs/fr/4x/api.md b/astro/src/content/docs/fr/4x/api.md
new file mode 100644
index 0000000000..7e1c0c7d04
--- /dev/null
+++ b/astro/src/content/docs/fr/4x/api.md
@@ -0,0 +1,26 @@
+---
+version: 4x
+title: Express 4.x - Référence de l'API
+description: Access the API reference for Express.js 4.x, detailing all modules, methods, and properties for building web applications with this version.
+---
+
+
+
+
API 4.x
+
+{% capture node-version %}
+
+Express 4.0 requires Node.js 0.10 or higher.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=node-version %}
+
+
+{% include api/en/4x/express.md %}
+{% include api/en/4x/app.md %}
+{% include api/en/4x/req.md %}
+{% include api/en/4x/res.md %}
+{% include api/en/4x/router.md %}
+
+
diff --git a/astro/src/content/docs/fr/5x/api.md b/astro/src/content/docs/fr/5x/api.md
new file mode 100644
index 0000000000..3ff3f0e991
--- /dev/null
+++ b/astro/src/content/docs/fr/5x/api.md
@@ -0,0 +1,26 @@
+---
+version: 5x
+title: Express 5.x - Référence de l'API
+description: Access the API reference for Express.js 5.x, detailing all modules, methods, and properties for building web applications with this latest version.
+---
+
+
+
+
5.x API
+
+{% capture node-version %}
+
+Express 5.0 requires Node.js 18 or higher.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=node-version %}
+
+
+{% include api/en/5x/express.md %}
+{% include api/en/5x/app.md %}
+{% include api/en/5x/req.md %}
+{% include api/en/5x/res.md %}
+{% include api/en/5x/router.md %}
+
+
diff --git a/astro/src/content/docs/it/3x/api.md b/astro/src/content/docs/it/3x/api.md
new file mode 100644
index 0000000000..5b67aab027
--- /dev/null
+++ b/astro/src/content/docs/it/3x/api.md
@@ -0,0 +1,23 @@
+---
+version: 3x
+title: Express 3.x - Riferimento API
+description: Access the API reference for Express.js version 3.x, noting that this version is end-of-life and no longer maintained - includes details on modules and methods.
+---
+
+
+
+
+ **Express 3.x NON È PIU' SUPPORTATO**
+
+I problemi noti e non noti relativi alla sicurezza presenti in 3.x non sono stati indirizzati dall'ultimo aggiornamento (1 agosto 2015). Si consiglia di utilizzare l'ultima versione di Express.
+
+If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/en/support#commercial-support-options).
+
+
+
+
API 3.x
+
+
+{% include api/en/3x/app.md %}
+
+
diff --git a/astro/src/content/docs/it/4x/api.md b/astro/src/content/docs/it/4x/api.md
new file mode 100644
index 0000000000..684819a994
--- /dev/null
+++ b/astro/src/content/docs/it/4x/api.md
@@ -0,0 +1,26 @@
+---
+version: 4x
+title: Express 4.x - Riferimento API
+description: Access the API reference for Express.js 4.x, detailing all modules, methods, and properties for building web applications with this version.
+---
+
+
+
+
API 4.x
+
+{% capture node-version %}
+
+Express 4.0 requires Node.js 0.10 or higher.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=node-version %}
+
+
+{% include api/en/4x/express.md %}
+{% include api/en/4x/app.md %}
+{% include api/en/4x/req.md %}
+{% include api/en/4x/res.md %}
+{% include api/en/4x/router.md %}
+
+
diff --git a/astro/src/content/docs/it/5x/api.md b/astro/src/content/docs/it/5x/api.md
new file mode 100644
index 0000000000..76f0822f91
--- /dev/null
+++ b/astro/src/content/docs/it/5x/api.md
@@ -0,0 +1,26 @@
+---
+version: 5x
+title: Express 5.x - Riferimento API
+description: Access the API reference for Express.js 5.x, detailing all modules, methods, and properties for building web applications with this latest version.
+---
+
+
+
+
5.x API
+
+{% capture node-version %}
+
+Express 5.0 requires Node.js 18 or higher.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=node-version %}
+
+
+{% include api/en/5x/express.md %}
+{% include api/en/5x/app.md %}
+{% include api/en/5x/req.md %}
+{% include api/en/5x/res.md %}
+{% include api/en/5x/router.md %}
+
+
diff --git a/astro/src/content/docs/ja/3x/api.md b/astro/src/content/docs/ja/3x/api.md
new file mode 100644
index 0000000000..10b409d997
--- /dev/null
+++ b/astro/src/content/docs/ja/3x/api.md
@@ -0,0 +1,23 @@
+---
+version: 3x
+title: Express 3.x - API リファレンス
+description: Access the API reference for Express.js version 3.x, noting that this version is end-of-life and no longer maintained - includes details on modules and methods.
+---
+
+
+
+
+ **Express 3.x は保守されなくなりました**
+
+3.xの既知および未知のセキュリティ問題は、最終更新(2015年8月1日)以降は対処されていません。3.x系を使用することは安全であると見なされるべきではありません。 It is highly recommended to use the latest version of Express.
+
+If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/en/support#commercial-support-options).
+
+
+
+
3.x API
+
+
+{% include api/en/3x/app.md %}
+
+
diff --git a/astro/src/content/docs/ja/4x/api.md b/astro/src/content/docs/ja/4x/api.md
new file mode 100644
index 0000000000..0a4c7888a1
--- /dev/null
+++ b/astro/src/content/docs/ja/4x/api.md
@@ -0,0 +1,26 @@
+---
+version: 4x
+title: Express 4.x - API リファレンス
+description: Access the API reference for Express.js 4.x, detailing all modules, methods, and properties for building web applications with this version.
+---
+
+
+
+
4.x API
+
+{% capture node-version %}
+
+Express 4.0 requires Node.js 0.10 or higher.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=node-version %}
+
+
+{% include api/en/4x/express.md %}
+{% include api/en/4x/app.md %}
+{% include api/en/4x/req.md %}
+{% include api/en/4x/res.md %}
+{% include api/en/4x/router.md %}
+
+
diff --git a/astro/src/content/docs/ja/5x/api.md b/astro/src/content/docs/ja/5x/api.md
new file mode 100644
index 0000000000..978914721c
--- /dev/null
+++ b/astro/src/content/docs/ja/5x/api.md
@@ -0,0 +1,26 @@
+---
+version: 5x
+title: Express 5.x - API リファレンス
+description: Access the API reference for Express.js 5.x, detailing all modules, methods, and properties for building web applications with this latest version.
+---
+
+
+
+
5.x API
+
+{% capture node-version %}
+
+Express 5.0 requires Node.js 18 or higher.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=node-version %}
+
+
+{% include api/en/5x/express.md %}
+{% include api/en/5x/app.md %}
+{% include api/en/5x/req.md %}
+{% include api/en/5x/res.md %}
+{% include api/en/5x/router.md %}
+
+
diff --git a/astro/src/content/docs/ko/3x/api.md b/astro/src/content/docs/ko/3x/api.md
new file mode 100644
index 0000000000..a96c0ff8ae
--- /dev/null
+++ b/astro/src/content/docs/ko/3x/api.md
@@ -0,0 +1,26 @@
+---
+version: 3x
+title: Express 3.x - API 참조
+description: Express.js 3.x 버전의 API 참조에 접근할 수 있습니다. 이 버전은 지원이 종료되었으며 더 이상 유지보수되지 않습니다. 모듈과 메소드에 대한 상세한 정보가 포함되어 있습니다.
+---
+
+
+
+
+ **Express 3.x은 더 이상 유지보수되지 않습니다.**
+
+3.x의 알려진 또는 알려지지 않은 보안 및 성능 문제는 마지막 업데이트(2015년 8월 1일) 이후로 처리되지 않고 있습니다. 최신 버전의 Express를 사용할 것을 강력히 권장합니다.
+
+버전 3.x 이상으로 업그레이드할 수 없는 경우, [상업적 지원 옵션](/en/support#commercial-support-options)을 고려해주시기 바랍니다.
+
+
+
+
3.x API
+
+{% include api/en/3x/express.md %}
+{% include api/en/3x/app.md %}
+{% include api/en/3x/req.md %}
+{% include api/en/3x/res.md %}
+{% include api/en/3x/middleware.md %}
+
+
diff --git a/astro/src/content/docs/ko/4x/api.md b/astro/src/content/docs/ko/4x/api.md
new file mode 100644
index 0000000000..d6bb85d431
--- /dev/null
+++ b/astro/src/content/docs/ko/4x/api.md
@@ -0,0 +1,26 @@
+---
+version: 4x
+title: Express 4.x - API 참조
+description: Express.js 4.x의 API 레퍼런스를 확인하여, 이 버전으로 웹 애플리케이션을 구축할 때 사용할 수 있는 모든 모듈, 메서드, 속성에 대해 자세히 알아봅니다.
+---
+
+
+
+
4.x API
+
+{% capture node-version %}
+
+Express 4.0에는 Node.js 0.10 이상이 필요합니다.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=node-version %}
+
+
+{% include api/en/4x/express.md %}
+{% include api/en/4x/app.md %}
+{% include api/en/4x/req.md %}
+{% include api/en/4x/res.md %}
+{% include api/en/4x/router.md %}
+
+
diff --git a/astro/src/content/docs/ko/5x/api.md b/astro/src/content/docs/ko/5x/api.md
new file mode 100644
index 0000000000..41a0efb560
--- /dev/null
+++ b/astro/src/content/docs/ko/5x/api.md
@@ -0,0 +1,26 @@
+---
+version: 5x
+title: Express 5.x - API 참조
+description: Express.js 5.x의 API 레퍼런스를 확인하여, 이 버전으로 웹 애플리케이션을 구축할 때 사용할 수 있는 모든 모듈, 메서드, 속성에 대해 자세히 알아봅니다.
+---
+
+
+
+
5.x API
+
+{% capture node-version %}
+
+Express 5.0에는 Node.js 18 이상이 필요합니다.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=node-version %}
+
+
+{% include api/en/5x/express.md %}
+{% include api/en/5x/app.md %}
+{% include api/en/5x/req.md %}
+{% include api/en/5x/res.md %}
+{% include api/en/5x/router.md %}
+
+
diff --git a/astro/src/content/docs/pt-br/3x/api.md b/astro/src/content/docs/pt-br/3x/api.md
new file mode 100644
index 0000000000..03eacd9177
--- /dev/null
+++ b/astro/src/content/docs/pt-br/3x/api.md
@@ -0,0 +1,23 @@
+---
+version: 3x
+title: Express 3.x - Referência de API
+description: Acesso à referência da API do Express.js versão 3.x, observando que esta versão é final de vida e não mais mantida - inclui detalhes sobre módulos e métodos.
+---
+
+
+
+
+ **Express 3.x support is ending soon**
+
+This series will continue to receive only security updates and bug fixes until July 2015. It is highly recommended to upgrade to Express 4.x.
+
+Se você não puder atualizar as últimas 3.x, por favor considere as [Opções de Suporte Comercial](/en/support#comercial-support-options).
+
+
+
+
3.x API
+
+
+{% include api/en/3x/app.md %}
+
+
diff --git a/astro/src/content/docs/pt-br/4x/api.md b/astro/src/content/docs/pt-br/4x/api.md
new file mode 100644
index 0000000000..6b40fd947f
--- /dev/null
+++ b/astro/src/content/docs/pt-br/4x/api.md
@@ -0,0 +1,26 @@
+---
+version: 4x
+title: Express 4.x - Referência de API
+description: Acesse a referência da API para Express.js 4.x, detalhando todos os módulos, métodos e propriedades para construir aplicações web com esta versão.
+---
+
+
+
+
API 4.x
+
+{% capture node-version %}
+
+Express 4.0 requer Node.js 0.10 ou superior.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=node-version %}
+
+
+{% include api/en/4x/express.md %}
+{% include api/en/4x/app.md %}
+{% include api/en/4x/req.md %}
+{% include api/en/4x/res.md %}
+{% include api/en/4x/router.md %}
+
+
diff --git a/astro/src/content/docs/pt-br/5x/api.md b/astro/src/content/docs/pt-br/5x/api.md
new file mode 100644
index 0000000000..28692618b7
--- /dev/null
+++ b/astro/src/content/docs/pt-br/5x/api.md
@@ -0,0 +1,26 @@
+---
+version: 5x
+title: Express 5.x - Referência da API
+description: Acesse a referência da API para Express.js 5.x, detalhando todos os módulos, métodos e propriedades para construir aplicações web com esta versão mais recente.
+---
+
+
+
+
5.x API
+
+{% capture node-version %}
+
+Express 5.0 requer Node.js 18 ou superior.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=node-version %}
+
+
+{% include api/en/5x/express.md %}
+{% include api/en/5x/app.md %}
+{% include api/en/5x/req.md %}
+{% include api/en/5x/res.md %}
+{% include api/en/5x/router.md %}
+
+
diff --git a/astro/src/content/docs/zh-cn/3x/api.md b/astro/src/content/docs/zh-cn/3x/api.md
new file mode 100644
index 0000000000..bf93c23044
--- /dev/null
+++ b/astro/src/content/docs/zh-cn/3x/api.md
@@ -0,0 +1,23 @@
+---
+version: 3x
+title: Express 3.x - API 参考
+description: Access the API reference for Express.js version 3.x, noting that this version is end-of-life and no longer maintained - includes details on modules and methods.
+---
+
+
+
+
+ **Express 3.x 不再受到维护**
+
+Known and unknown security and performance issues in 3.x have not been addressed since the last update (1 August, 2015). It is highly recommended to use the latest version of Express.
+
+If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/en/support#commercial-support-options).
+
+
+
+
3.x API
+
+
+{% include api/en/3x/app.md %}
+
+
diff --git a/astro/src/content/docs/zh-cn/4x/api.md b/astro/src/content/docs/zh-cn/4x/api.md
new file mode 100644
index 0000000000..a504c0acc3
--- /dev/null
+++ b/astro/src/content/docs/zh-cn/4x/api.md
@@ -0,0 +1,26 @@
+---
+version: 4x
+title: Express 4.x - API 参考
+description: Access the API reference for Express.js 4.x, detailing all modules, methods, and properties for building web applications with this version.
+---
+
+
+
+
4.x API
+
+{% capture node-version %}
+
+Express 4.0 requires Node.js 0.10 or higher.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=node-version %}
+
+
+{% include api/en/4x/express.md %}
+{% include api/en/4x/app.md %}
+{% include api/en/4x/req.md %}
+{% include api/en/4x/res.md %}
+{% include api/en/4x/router.md %}
+
+
diff --git a/astro/src/content/docs/zh-cn/5x/api.md b/astro/src/content/docs/zh-cn/5x/api.md
new file mode 100644
index 0000000000..13d67f0666
--- /dev/null
+++ b/astro/src/content/docs/zh-cn/5x/api.md
@@ -0,0 +1,26 @@
+---
+version: 5x
+title: Express 5.x - API 参考
+description: Access the API reference for Express.js 5.x, detailing all modules, methods, and properties for building web applications with this latest version.
+---
+
+
+
+
5.x API
+
+{% capture node-version %}
+
+Express 5.0 requires Node.js 18 or higher.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=node-version %}
+
+
+{% include api/en/5x/express.md %}
+{% include api/en/5x/app.md %}
+{% include api/en/5x/req.md %}
+{% include api/en/5x/res.md %}
+{% include api/en/5x/router.md %}
+
+
diff --git a/astro/src/content/docs/zh-tw/3x/api.md b/astro/src/content/docs/zh-tw/3x/api.md
new file mode 100644
index 0000000000..2c4796fc21
--- /dev/null
+++ b/astro/src/content/docs/zh-tw/3x/api.md
@@ -0,0 +1,23 @@
+---
+version: 3x
+title: Express 3.x - API 參照
+description: Access the API reference for Express.js version 3.x, noting that this version is end-of-life and no longer maintained - includes details on modules and methods.
+---
+
+
+
+
+ **Express 3.x 已不再維護**
+
+Known and unknown security and performance issues in 3.x have not been addressed since the last update (1 August, 2015). It is highly recommended to use the latest version of Express.
+
+If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/en/support#commercial-support-options).
+
+
+
+
3.x API
+
+
+{% include api/en/3x/app.md %}
+
+
diff --git a/astro/src/content/docs/zh-tw/4x/api.md b/astro/src/content/docs/zh-tw/4x/api.md
new file mode 100644
index 0000000000..0846c8f06d
--- /dev/null
+++ b/astro/src/content/docs/zh-tw/4x/api.md
@@ -0,0 +1,26 @@
+---
+version: 4x
+title: Express 4.x - API 參照
+description: Access the API reference for Express.js 4.x, detailing all modules, methods, and properties for building web applications with this version.
+---
+
+
+
+
4.x API
+
+{% capture node-version %}
+
+Express 4.0 requires Node.js 0.10 or higher.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=node-version %}
+
+
+{% include api/en/4x/express.md %}
+{% include api/en/4x/app.md %}
+{% include api/en/4x/req.md %}
+{% include api/en/4x/res.md %}
+{% include api/en/4x/router.md %}
+
+
diff --git a/astro/src/content/docs/zh-tw/5x/api.md b/astro/src/content/docs/zh-tw/5x/api.md
new file mode 100644
index 0000000000..857895824e
--- /dev/null
+++ b/astro/src/content/docs/zh-tw/5x/api.md
@@ -0,0 +1,26 @@
+---
+version: 5x
+title: Express 5.x - API 參照
+description: Access the API reference for Express.js 5.x, detailing all modules, methods, and properties for building web applications with this latest version.
+---
+
+
+
+
5.x API
+
+{% capture node-version %}
+
+Express 5.0 requires Node.js 18 or higher.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=node-version %}
+
+
+{% include api/en/5x/express.md %}
+{% include api/en/5x/app.md %}
+{% include api/en/5x/req.md %}
+{% include api/en/5x/res.md %}
+{% include api/en/5x/router.md %}
+
+
diff --git a/astro/src/content/resources/de/community.md b/astro/src/content/resources/de/community.md
new file mode 100755
index 0000000000..e40d97e421
--- /dev/null
+++ b/astro/src/content/resources/de/community.md
@@ -0,0 +1,70 @@
+---
+title: Express community
+description: Connect with the Express.js community, learn about the technical committee, find resources, explore community-contributed modules, and get involved in discussions.
+---
+
+# Community
+
+## Technical committee
+
+The Express technical committee meets online every two weeks (as needed) to discuss development and maintenance of Express,
+and other issues relevant to the Express project. Each meeting is typically announced in an
+[expressjs/discussions issue](https://github.com/expressjs/discussions/issues) with a link to join or view the meeting, which is
+open to all observers.
+
+The meetings are recorded; for a list of the recordings, see the [Express.js YouTube channel](https://www.youtube.com/channel/UCYjxjAeH6TRik9Iwy5nXw7g).
+
+Members of the Express technical committee are:
+
+**Active:**
+
+- [@blakeembrey](https://github.com/blakeembrey) - Blake Embrey
+- [@crandmck](https://github.com/crandmck) - Rand McKinney
+- [@LinusU](https://github.com/LinusU) - Linus Unnebäck
+- [@ulisesgascon](https://github.com/ulisesGascon) - Ulises Gascón
+- [@sheplu](https://github.com/sheplu) - Jean Burellier
+- [@wesleytodd](https://github.com/wesleytodd) - Wes Todd
+- [@jonchurch](https://github.com/jonchurch) - Jon Church
+- [@ctcpip](https://github.com/ctcpip/) - Chris de Almeida
+
+**Inactive:**
+
+- [@dougwilson](https://github.com/dougwilson) - Douglas Wilson
+- [@hacksparrow](https://github.com/hacksparrow) - Hage Yaapa
+- [@jonathanong](https://github.com/jonathanong) - jongleberry
+- [@niftylettuce](https://github.com/niftylettuce) - niftylettuce
+- [@troygoode](https://github.com/troygoode) - Troy Goode
+
+## Express is made of many modules
+
+Our vibrant community has created a large variety of extensions,
+[middleware modules](/en/resources/middleware) and higher-level frameworks.
+
+Additionally, the Express community maintains modules in these two GitHub orgs:
+
+- [jshttp](https://github.com/jshttp) modules providing useful utility functions; see [Utility modules](/en/resources/utils).
+- [pillarjs](https://github.com/pillarjs): low-level modules that Express uses internally.
+
+To keep up with what is going on in the whole community, check out the [ExpressJS StatusBoard](https://expressjs.github.io/statusboard/).
+
+## Issues
+
+If you've come across what you think is a bug, or just want to make
+a feature request open a ticket in the [issue queue](https://github.com/expressjs/express/issues).
+
+## Examples
+
+View dozens of Express application [examples](https://github.com/expressjs/express/tree/master/examples)
+in the repository covering everything from API design and authentication to template engine integration.
+
+## Github Discussions
+
+The [GitHub Discussions](https://github.com/expressjs/discussions) section is an excellent space to engage in conversations about the development and maintenance of Express, as well as to share ideas and discuss topics related to its usage.
+
+# Branding of Express.js
+
+## Express.js Logo
+
+Express is a project of the OpenJS Foundation. Please review the [trademark policy](https://trademark-policy.openjsf.org/) for information about permissible use of Express.js logos and marks.
+
+
diff --git a/astro/src/content/resources/de/contributing.md b/astro/src/content/resources/de/contributing.md
new file mode 100644
index 0000000000..82c6b8fed7
--- /dev/null
+++ b/astro/src/content/resources/de/contributing.md
@@ -0,0 +1,482 @@
+---
+title: Contributing to Express
+description: Find out how to contribute to Express.js, including guidelines for reporting issues, submitting pull requests, becoming a collaborator, and understanding security policies.
+---
+
+# Contributing to Express
+
+### Looking to contribute to Expressjs.com? Click [here](#expressjs-website-contributing).
+
+Express and the other projects in the [expressjs organization on GitHub](https://github.com/expressjs) are projects of the [OpenJs Foundation](https://openjsf.org/).
+These projects are governed under the general policies and guidelines of the Node.js Foundation along with the additional guidelines below.
+
+- [Technical committee](#technical-committee)
+- [Community contributing guide](#community-contributing-guide)
+- [Collaborator's guide](#collaborators-guide)
+- [Security policies and procedures](#security-policies-and-procedures)
+
+## Technical committee
+
+The Express technical committee consists of active project members, and guides development and maintenance of the Express project. For more information, see [Express Community - Technical committee](/en/resources/community/#technical-committee).
+
+## Community contributing guide
+
+
+
+The goal of this document is to create a contribution process that:
+
+- Encourages new contributions.
+- Encourages contributors to remain involved.
+- Avoids unnecessary processes and bureaucracy whenever possible.
+- Creates a transparent decision making process that makes it clear how
+ contributors can be involved in decision making.
+
+### Vocabulary
+
+- A **Contributor** is any individual creating or commenting on an issue or pull request.
+- A **Committer** is a subset of contributors who have been given write access to the repository.
+- A **Project Captain** is the lead maintainer of a repository.
+- A **TC (Technical Committee)** is a group of committers representing the required technical
+ expertise to resolve rare disputes.
+- A **Triager** is a subset of contributors who have been given triage access to the repository.
+
+### Logging Issues
+
+Log an issue for any question or problem you might have. When in doubt, log an issue, and
+any additional policies about what to include will be provided in the responses. The only
+exception is security disclosures which should be sent privately.
+
+Committers may direct you to another repository, ask for additional clarifications, and
+add appropriate metadata before the issue is addressed.
+
+Please be courteous and respectful. Every participant is expected to follow the
+project's Code of Conduct.
+
+### Contributions
+
+Any change to resources in this repository must be through pull requests. This applies to all changes
+to documentation, code, binary files, etc. Even long term committers and TC members must use
+pull requests.
+
+No pull request can be merged without being reviewed.
+
+For non-trivial contributions, pull requests should sit for at least 36 hours to ensure that
+contributors in other timezones have time to review. Consideration should also be given to
+weekends and other holiday periods to ensure active committers all have reasonable time to
+become involved in the discussion and review process if they wish.
+
+The default for each contribution is that it is accepted once no committer has an objection.
+During a review, committers may also request that a specific contributor who is most versed in a
+particular area gives a "LGTM" before the PR can be merged. There is no additional "sign off"
+process for contributions to land. Once all issues brought by committers are addressed it can
+be landed by any committer.
+
+In the case of an objection being raised in a pull request by another committer, all involved
+committers should seek to arrive at a consensus by way of addressing concerns being expressed
+by discussion, compromise on the proposed change, or withdrawal of the proposed change.
+
+If a contribution is controversial and committers cannot agree about how to get it to land
+or if it should land then it should be escalated to the TC. TC members should regularly
+discuss pending contributions in order to find a resolution. It is expected that only a
+small minority of issues be brought to the TC for resolution and that discussion and
+compromise among committers be the default resolution mechanism.
+
+### Becoming a Triager
+
+Anyone can become a triager! Read more about the process of being a triager in
+[the triage process document](https://github.com/expressjs/discussions/blob/master/Triager-Guide.md).
+
+Currently, any existing [organization member](https://github.com/orgs/expressjs/people) can nominate
+a new triager. If you are interested in becoming a triager, our best advice is to actively participate
+in the community by helping triaging issues and pull requests. As well we recommend
+to engage in other community activities like attending the TC meetings, and participating in the Slack
+discussions. If you feel ready and have been helping triage some issues, reach out to an active member of the organization to ask if they'd
+be willing to support you. If they agree, they can create a pull request to formalize your nomination. In the case of an objection to the nomination, the triage team is responsible for working with the individuals involved and finding a resolution.
+
+You can also reach out to any of the [organization members](https://github.com/orgs/expressjs/people)
+if you have questions or need guidance.
+
+### Becoming a Committer
+
+All contributors who have landed significant and valuable contributions should be onboarded in a timely manner,
+and added as a committer, and be given write access to the repository.
+
+Committers are expected to follow this policy and continue to send pull requests, go through
+proper review, and have other committers merge their pull requests.
+
+### TC Process
+
+The TC uses a "consensus seeking" process for issues that are escalated to the TC.
+The group tries to find a resolution that has no open objections among TC members.
+If a consensus cannot be reached that has no objections then a majority wins vote
+is called. It is also expected that the majority of decisions made by the TC are via
+a consensus seeking process and that voting is only used as a last-resort.
+
+Resolution may involve returning the issue to project captains with suggestions on
+how to move forward towards a consensus. It is not expected that a meeting of the TC
+will resolve all issues on its agenda during that meeting and may prefer to continue
+the discussion happening among the project captains.
+
+Members can be added to the TC at any time. Any TC member can nominate another committer
+to the TC and the TC uses its standard consensus seeking process to evaluate whether or
+not to add this new member. The TC will consist of a minimum of 3 active members and a
+maximum of 10. If the TC should drop below 5 members the active TC members should nominate
+someone new. If a TC member is stepping down, they are encouraged (but not required) to
+nominate someone to take their place.
+
+TC members will be added as admin's on the Github orgs, npm orgs, and other resources as
+necessary to be effective in the role.
+
+To remain "active" a TC member should have participation within the last 12 months and miss
+no more than six consecutive TC meetings. Our goal is to increase participation, not punish
+people for any lack of participation, this guideline should be only be used as such
+(replace an inactive member with a new active one, for example). Members who do not meet this
+are expected to step down. If A TC member does not step down, an issue can be opened in the
+discussions repo to move them to inactive status. TC members who step down or are removed due
+to inactivity will be moved into inactive status.
+
+Inactive status members can become active members by self nomination if the TC is not already
+larger than the maximum of 10. They will also be given preference if, while at max size, an
+active member steps down.
+
+### Project Captains
+
+The Express TC can designate captains for individual projects/repos in the
+organizations. These captains are responsible for being the primary
+day-to-day maintainers of the repo on a technical and community front.
+Repo captains are empowered with repo ownership and package publication rights.
+When there are conflicts, especially on topics that effect the Express project
+at large, captains are responsible to raise it up to the TC and drive
+those conflicts to resolution. Captains are also responsible for making sure
+community members follow the community guidelines, maintaining the repo
+and the published package, as well as in providing user support.
+
+Like TC members, Repo captains are a subset of committers.
+
+To become a captain for a project the candidate is expected to participate in that
+project for at least 6 months as a committer prior to the request. They should have
+helped with code contributions as well as triaging issues. They are also required to
+have 2FA enabled on both their GitHub and npm accounts.
+
+Any TC member or an existing captain on the **same** repo can nominate another committer
+to the captain role. To do so, they should submit a PR to this document, updating the
+**Active Project Captains** section (while maintaining the sort order) with the project
+name, the nominee's GitHub handle, and their npm username (if different).
+
+- Repos can have as many captains as make sense for the scope of work.
+- A TC member or an existing repo captain **on the same project** can nominate a new captain.
+ Repo captains from other projects should not nominate captains for a different project.
+
+The PR will require at least 2 approvals from TC members and 2 weeks hold time to allow
+for comment and/or dissent. When the PR is merged, a TC member will add them to the
+proper GitHub/npm groups.
+
+#### Active Projects and Captains
+
+The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members)
+
+#### Current Initiative Captains
+
+The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains)
+
+### Inactivity and Emeritus Policy for Any Role
+
+To support the health and continuity of the project, all individuals holding a role within the community (such as Triager, Committer, WG member, Project Captain, or TC member) are encouraged to maintain active participation.
+
+Inactivity is defined as the absence of meaningful involvement in the project—such as contributions, code reviews, triage, meeting attendance, or discussion participation—for a continuous period of 6 months.
+
+#### Exceptions
+
+Anyone may request a temporary leave from active participation due to personal or professional reasons. In such cases, the individual should inform the relevant team or the Technical Committee (TC). During this time, the inactivity policy is paused, and the individual will not be flagged as inactive.
+
+#### Inactivity Process
+
+- If someone is deemed inactive, the individual may be transitioned to an emeritus role that reflects their past contributions. A best effort will be made to inform them that this has occurred. They may request to be reinstated when they are ready to be active again.
+- The emeritus status helps preserve a clear record of contributors who have meaningfully shaped the project over time.
+
+#### Accountability
+
+- The Technical Committee (TC) and the respective captains of each package/team are responsible for assessing activity levels and enacting this policy fairly and transparently, in coordination with other relevant teams.
+- In case of disagreement, the situation can be discussed and resolved by consensus within the TC or appropriate team.
+
+### Developer's Certificate of Origin 1.1
+
+```text
+By making a contribution to this project, I certify that:
+
+ (a) The contribution was created in whole or in part by me and I
+ have the right to submit it under the open source license
+ indicated in the file; or
+
+ (b) The contribution is based upon previous work that, to the best
+ of my knowledge, is covered under an appropriate open source
+ license and I have the right under that license to submit that
+ work with modifications, whether created in whole or in part
+ by me, under the same open source license (unless I am
+ permitted to submit under a different license), as indicated
+ in the file; or
+
+ (c) The contribution was provided directly to me by some other
+ person who certified (a), (b) or (c) and I have not modified
+ it.
+
+ (d) I understand and agree that this project and the contribution
+ are public and that a record of the contribution (including all
+ personal information I submit with it, including my sign-off) is
+ maintained indefinitely and may be redistributed consistent with
+ this project or the open source license(s) involved.
+```
+
+## Collaborator's guide
+
+
+
+### Website Issues
+
+Open issues for the expressjs.com website in https://github.com/expressjs/expressjs.com.
+
+For issues in other Express managed repos (everything in `expressjs`, `pillarjs` or `jshttp` other than `expressjs/express`), be sure to check their contributing guide and open issues and PRs in the appropriate repository.
+
+### PRs and Code contributions
+
+- Tests must pass.
+- Follow the [JavaScript Standard Style](https://standardjs.com/) and `npm run lint`.
+- If you fix a bug, add a test.
+
+### Branches
+
+Use the `master` branch for bug fixes or minor work that is intended for the
+current release stream.
+
+Use the correspondingly named branch, e.g. `6.x`, for anything intended for
+a future release of Express.
+
+### Steps for contributing
+
+1. Create an issue for the
+ bug you want to fix or the feature that you want to add.
+2. Create your own fork on GitHub, then
+ checkout your fork.
+3. Write your code in your local copy. It's good practice to create a branch for
+ each new issue you work on, although not compulsory.
+4. To run the test suite, first install the dependencies by running `npm install`,
+ then run `npm test`.
+5. Ensure your code is linted by running `npm run lint` -- fix any issue you
+ see listed.
+6. If the tests pass, you can commit your changes to your fork and then create
+ a pull request from there. Make sure to reference your issue from the pull
+ request comments by including the issue number e.g. `#123`.
+
+### Issues which are questions
+
+We will typically close any vague issues or questions that are specific to some
+app you are writing. Please double check the docs and other references before
+being trigger happy with posting a question issue.
+
+Things that will help get your question issue looked at:
+
+- Full and runnable JS code.
+- Clear description of the problem or unexpected behavior.
+- Clear description of the expected result.
+- Steps you have taken to debug it yourself.
+
+If you post a question and do not outline the above items or make it easy for
+us to understand and reproduce your issue, it will be closed.
+
+If your question meets all of the above requirements but you do not believe it needs to be looked at
+by the maintainers
+(for example, if you are just looking for community input) please open it as a discussion topic instead
+of an issue. If you
+are unsure and open an issue, we may move it to discussions if we triage them and decide they do
+not need high
+visibility or maintainer input.
+
+## Security Policies and Procedures
+
+
+
+This document outlines security procedures and general policies for the Express
+project.
+
+- [Reporting a Bug](#reporting-a-bug)
+- [Disclosure Policy](#disclosure-policy)
+- [Comments on this Policy](#comments-on-this-policy)
+
+### Reporting a Bug
+
+The Express team and community take all security bugs in Express seriously.
+Thank you for improving the security of Express. We appreciate your efforts and
+responsible disclosure and will make every effort to acknowledge your
+contributions.
+
+Report security bugs by emailing `express-security@lists.openjsf.org`.
+
+To ensure the timely response to your report, please ensure that the entirety
+of the report is contained within the email body and not solely behind a web
+link or an attachment.
+
+The lead maintainer will acknowledge your email within 48 hours, and will send a
+more detailed response within 48 hours indicating the next steps in handling
+your report. After the initial reply to your report, the security team will
+endeavor to keep you informed of the progress towards a fix and full
+announcement, and may ask for additional information or guidance.
+
+Report security bugs in third-party modules to the person or team maintaining
+the module.
+
+### Pre-release Versions
+
+Alpha and Beta releases are unstable and **not suitable for production use**.
+Vulnerabilities found in pre-releases should be reported according to the [Reporting a Bug](#reporting-a-bug) section.
+Due to the unstable nature of the branch it is not guaranteed that any fixes will be released in the next pre-release.
+
+### Disclosure Policy
+
+When the security team receives a security bug report, they will assign it to a
+primary handler. This person will coordinate the fix and release process,
+involving the following steps:
+
+- Confirm the problem and determine the affected versions.
+- Audit code to find any potential similar problems.
+- Prepare fixes for all releases still under maintenance. These fixes will be
+ released as fast as possible to npm.
+
+### The Express Threat Model
+
+We are currently working on a new version of the security model, the most updated version can be found [here](https://github.com/expressjs/security-wg/blob/main/docs/ThreatModel.md)
+
+### Comments on this Policy
+
+If you have suggestions on how this process could be improved please submit a
+pull request.
+
+---
+
+# Contributing to Expressjs.com {#expressjs-website-contributing}
+
+
+
+### The Official Documentation of the Express.js Framework
+
+This is the contribution documentation for the [expressjs.com](https://github.com/expressjs/expressjs.com) website.
+
+#### Need some ideas? These are some typical issues.
+
+1. **Website issues**: If you see anything on the site that could use a tune-up, think about how to fix it.
+ - Display or screen sizing problems
+ - Mobile responsiveness issues
+ - Missing or broken accessibility features
+ - Website outages
+ - Broken links
+ - Page structure or user interface enhancements
+
+2. **Content Issues**: Fix anything related to site content or typos.
+ - Spelling errors
+ - Incorrect/outdated Express.js documentation
+ - Missing content
+
+3. **Translation Issues**: Fix any translation errors or contribute new content.
+ - Fix spelling errors
+ - Fix incorrect/poorly translated words
+ - Check out the [Contributing translations](#contributing-translations) section below for a contributing guide.
+
+#### Want to work on a backlog issue?
+
+We often have bugs or enhancements that need work. You can find these under our repo's [Issues tab](https://github.com/expressjs/expressjs.com/issues). Check out the tags to find something that's a good match for you.
+
+#### Have an idea? Found a bug?
+
+If you've found a bug or a typo, or if you have an idea for an enhancement, you can:
+
+- Submit a [new issue](https://github.com/expressjs/expressjs.com/issues/new/choose) on our repo. Do this for larger proposals, or if you'd like to discuss or get feedback first.
+
+- Make a [GitHub pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). If you have already done work, and it's ready to go, feel free to send it our way.
+
+## Getting Started
+
+The steps below will guide you through the Expressjs.com contribution process.
+
+#### Step 1: (OPTIONAL) Open a New Issue
+
+So you've found a problem that you want to fix, or have a site enhancement you want to make.
+
+1. If you want to get feedback or discuss, open a discussion [issue](https://github.com/expressjs/expressjs.com/issues/new/choose) prior to starting work. This is not required, but encouraged for larger proposals.
+ - While we highly encourage this step, it is only for submissions proposing significant change. It helps us to clarify and focus the work, and ensure it aligns with overall project priorities.
+ - For submissions proposing minor improvements or corrections, this is not needed. You can skip this step.
+ - When opening an issue please give it a title and fill in the description section. The more details you provide, the more feedback we can give.
+
+2. After receiving your issue the Express.js documentation team will respond with feedback. We read every submission and always try to respond quickly with feedback.
+ - For submissions proposing significant change, we encourage you to follow the review process before starting work.
+
+#### Step 2: Get the Application Code Base
+
+Clone the repo and get the code:
+
+```sh
+git clone https://github.com/expressjs/expressjs.com.git
+```
+
+After you've got the code you're ready to start making your changes!
+
+But just in case you need a little extra explanation, this section below outlines the main sections of the code base, where most changes are likely to be made.
+
+**Markdown Page Files**:
+
+- These files render to html and make up the individual pages of the site. Most of the site's documentation text content is written in `md` files.
+- Change these to make changes to individual pages' content/text or markup.
+- Each language has its own complete set of pages, located under their respective language directories - all the Spanish markdown content is found in the `es` directory, for example.
+
+**Includes Partials and Layout Templates**
+
+- `_includes` are partials that are imported and reused across multiple pages.
+ - These are used to import text content for reuse across pages, such as the API documentation, e.g., `_includes > api > en > 5x`, which is included in every language.
+ - These are used to include the page components that make up site-wide user interface and periphery structure, e.g., Header, Footer, etc.
+- `_layouts` are the templates used to wrap the site's individual pages.
+ - These are used to display the structure of the site's periphery, such as the header and footer, and for injecting and displaying individual markdown pages inside the `content` tag.
+
+**Blog Markdown Files**
+
+- These files make up the individual blog posts. If you want to contribute a blog post please
+ follow the specific instructions for [How to write a blog post.](https://expressjs.com/en/blog/write-post)
+- Located under the `_posts` directory.
+
+**CSS or Javascript**
+
+- All css and js files are kept in `css` and `js` folders on the project root.
+
+The Express.js website is built using [Jekyll](https://jekyllrb.com/) and is hosted on [GitHub Pages](https://pages.github.com/).
+
+#### Step 3: Running the Application
+
+Now you'll need a way to see your changes, which means you'll need a running version of the application. You have two options.
+
+1. **Run Locally**: This gets the local version of the application up and running on your machine. Follow our [Local Setup Guide](https://github.com/expressjs/expressjs.com?tab=readme-ov-file#build-the-website-locally) to use this option.
+ - This is the recommended option for moderate to complex work.
+
+2. **Run using Deploy Preview**: Use this option if you don't want to bother with a local installation. Part of our continuous integration pipeline includes [Netlify Deploy Preview](https://docs.netlify.com/deploy/deploy-types/deploy-previews/).
+ 1. To use this you'll need to get your changes online - after you've made your first commit on your feature branch, make a _draft_ pull request.
+ 2. After the build steps are complete, you'll have access to a **Deploy Preview** tab that will run your changes on the web, rebuilding after each commit is pushed.
+ 3. After you are completely done your work, and it's ready for review, remove the draft status on your pull request and submit your work.
+
+## Contributing translations
+
+We use Crowdin to manage our translations in multiple languages and achieve automatic translation with artificial intelligence. Since these translations can be inefficient in some cases, we need help from the community to provide accurate and helpful translations.
+
+The documentation is translated into these languages:
+
+- Chinese Simplified (`zh-cn`)
+- Chinese Traditional (`zh-tw`)
+- English (`en`)
+- French (`fr`)
+- German (`de`)
+- Italian (`it`)
+- Japanese (`ja`)
+- Korean (`ko`)
+- Brazilian Portuguese (`pt-br`)
+- Spanish (`es`)
+
+### How to translate
+
+1. Request to join the Express.js Website project on [Crowdin](https://express.crowdin.com/website)
+2. [Select the language you want to translate](https://support.crowdin.com/for-translators/#starting-translation)
+3. [Start translating](https://support.crowdin.com/online-editor/)
diff --git a/astro/src/content/resources/de/glossary.md b/astro/src/content/resources/de/glossary.md
new file mode 100755
index 0000000000..8b45bf01eb
--- /dev/null
+++ b/astro/src/content/resources/de/glossary.md
@@ -0,0 +1,62 @@
+---
+title: Express glossary
+description: A comprehensive glossary of terms related to Express.js, Node.js, middleware, routing, and other key concepts to help you understand and use Express effectively.
+---
+
+# Glossary
+
+### application
+
+In general, one or more programs that are designed to carry out operations for a specific purpose. In the context of Express, a program that uses the Express API running on the Node.js platform. Might also refer to an [app object](/en/api#express).
+
+### API
+
+Application programming interface. Spell out the abbreviation when it is first used.
+
+### Express
+
+A fast, un-opinionated, minimalist web framework for Node.js applications. In general, "Express" is preferred to "Express.js," though the latter is acceptable.
+
+### libuv
+
+A multi-platform support library which focuses on asynchronous I/O, primarily developed for use by Node.js.
+
+### middleware
+
+A function that is invoked by the Express routing layer before the final request handler, and thus sits in the middle between a raw request and the final intended route. A few fine points of terminology around middleware:
+
+- `var foo = require('middleware')` is called _requiring_ or _using_ a Node.js module. Then the statement `var mw = foo()` typically returns the middleware.
+- `app.use(mw)` is called _adding the middleware to the global processing stack_.
+- `app.get('/foo', mw, function (req, res) { ... })` is called _adding the middleware to the "GET /foo" processing stack_.
+
+### Node.js
+
+A software platform that is used to build scalable network applications. Node.js uses JavaScript as its scripting language, and achieves high throughput via non-blocking I/O and a single-threaded event loop. See [nodejs.org](https://nodejs.org/en/). **Usage note**: Initially, "Node.js," thereafter "Node".
+
+### open-source, open source
+
+When used as an adjective, hyphenate; for example: "This is open-source software." See [Open-source software on Wikipedia](http://en.wikipedia.org/wiki/Open-source_software).
+
+{% capture english-rules %}
+
+Although it is common not to hyphenate this term, we are using the standard English rules for hyphenating a compound adjective.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=english-rules %}
+
+### request
+
+An HTTP request. A client submits an HTTP request message to a server, which returns a response. The request must use one of several [request methods](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods) such as GET, POST, and so on.
+
+### response
+
+An HTTP response. A server returns an HTTP response message to the client. The response contains completion status information about the request and might also contain requested content in its message body.
+
+### route
+
+Part of a URL that identifies a resource. For example, in `http://foo.com/products/id`, "/products/id" is the route.
+
+### router
+
+See [router](/en/api#router) in the API reference.
diff --git a/astro/src/content/resources/de/middleware/body-parser.md b/astro/src/content/resources/de/middleware/body-parser.md
new file mode 100644
index 0000000000..e82649a95c
--- /dev/null
+++ b/astro/src/content/resources/de/middleware/body-parser.md
@@ -0,0 +1,498 @@
+---
+title: Express body-parser middleware
+module: body-parser
+---
+
+# body-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+
+Node.js body parsing middleware.
+
+Parse incoming request bodies in a middleware before your handlers, available
+under the `req.body` property.
+
+**Note** As `req.body`'s shape is based on user-controlled input, all
+properties and values in this object are untrusted and should be validated
+before trusting. For example, `req.body.foo.toString()` may fail in multiple
+ways, for example the `foo` property may not be there or may not be a string,
+and `toString` may not be a function and instead a string or other user input.
+
+[Learn about the anatomy of an HTTP transaction in Node.js](https://nodejs.org/en/learn/http/anatomy-of-an-http-transaction).
+
+_This does not handle multipart bodies_, due to their complex and typically
+large nature. For multipart bodies, you may be interested in the following
+modules:
+
+- [busboy](https://www.npmjs.com/package/busboy#readme) and
+ [connect-busboy](https://www.npmjs.com/package/connect-busboy#readme)
+- [multiparty](https://www.npmjs.com/package/multiparty#readme) and
+ [connect-multiparty](https://www.npmjs.com/package/connect-multiparty#readme)
+- [formidable](https://www.npmjs.com/package/formidable#readme)
+- [multer](https://www.npmjs.com/package/multer#readme)
+
+This module provides the following parsers:
+
+- [JSON body parser](#bodyparserjsonoptions)
+- [Raw body parser](#bodyparserrawoptions)
+- [Text body parser](#bodyparsertextoptions)
+- [URL-encoded form body parser](#bodyparserurlencodedoptions)
+
+Other body parsers you might be interested in:
+
+- [body](https://www.npmjs.com/package/body#readme)
+- [co-body](https://www.npmjs.com/package/co-body#readme)
+
+## Installation
+
+```sh
+$ npm install body-parser
+```
+
+## API
+
+```js
+const bodyParser = require('body-parser');
+```
+
+The `bodyParser` object exposes various factories to create middlewares. All
+middlewares will populate the `req.body` property with the parsed body when
+the `Content-Type` request header matches the `type` option.
+
+The various errors returned by this module are described in the
+[errors section](#errors).
+
+### bodyParser.json([options])
+
+Returns middleware that only parses `json` and only looks at requests where
+the `Content-Type` header matches the `type` option. This parser accepts any
+Unicode encoding of the body and supports automatic inflation of `gzip`,
+`br` (brotli) and `deflate` encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`).
+
+#### Options
+
+The `json` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### defaultCharset
+
+Specify the default character set for the json content if the charset is not
+specified in the `Content-Type` header of the request. Defaults to `utf-8`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### reviver
+
+The `reviver` option is passed directly to `JSON.parse` as the second
+argument. You can find more information on this argument
+[in the MDN documentation about JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Example.3A_Using_the_reviver_parameter).
+
+##### strict
+
+When set to `true`, will only accept arrays and objects; when `false` will
+accept anything `JSON.parse` accepts. Defaults to `true`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not a
+function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `json`), a mime type (like `application/json`), or
+a mime type with a wildcard (like `*/*` or `*/json`). If a function, the `type`
+option is called as `fn(req)` and the request is parsed if it returns a truthy
+value. Defaults to `application/json`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.raw([options])
+
+Returns middleware that parses all bodies as a `Buffer` and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser supports automatic inflation of `gzip`, `br` (brotli) and `deflate`
+encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This will be a `Buffer` object
+of the body.
+
+#### Options
+
+The `raw` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function.
+If not a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this
+can be an extension name (like `bin`), a mime type (like
+`application/octet-stream`), or a mime type with a wildcard (like `*/*` or
+`application/*`). If a function, the `type` option is called as `fn(req)`
+and the request is parsed if it returns a truthy value. Defaults to
+`application/octet-stream`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.text([options])
+
+Returns middleware that parses all bodies as a string and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser supports automatic inflation of `gzip`, `br` (brotli) and `deflate`
+encodings.
+
+A new `body` string containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This will be a string of the
+body.
+
+#### Options
+
+The `text` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### defaultCharset
+
+Specify the default character set for the text content if the charset is not
+specified in the `Content-Type` header of the request. Defaults to `utf-8`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not
+a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `txt`), a mime type (like `text/plain`), or a mime
+type with a wildcard (like `*/*` or `text/*`). If a function, the `type`
+option is called as `fn(req)` and the request is parsed if it returns a
+truthy value. Defaults to `text/plain`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.urlencoded([options])
+
+Returns middleware that only parses `urlencoded` bodies and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser accepts only UTF-8 encoding of the body and supports automatic
+inflation of `gzip`, `br` (brotli) and `deflate` encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This object will contain
+key-value pairs, where the value can be a string or array (when `extended` is
+`false`), or any type (when `extended` is `true`).
+
+#### Options
+
+The `urlencoded` function takes an optional `options` object that may contain
+any of the following keys:
+
+##### extended
+
+The "extended" syntax allows for rich objects and arrays to be encoded into the
+URL-encoded format, allowing for a JSON-like experience with URL-encoded. For
+more information, please [see the qs
+library](https://www.npmjs.com/package/qs#readme).
+
+Defaults to `false`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### parameterLimit
+
+The `parameterLimit` option controls the maximum number of parameters that
+are allowed in the URL-encoded data. If a request contains more parameters
+than this value, a 413 will be returned to the client. Defaults to `1000`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not
+a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `urlencoded`), a mime type (like
+`application/x-www-form-urlencoded`), or a mime type with a wildcard (like
+`*/x-www-form-urlencoded`). If a function, the `type` option is called as
+`fn(req)` and the request is parsed if it returns a truthy value. Defaults
+to `application/x-www-form-urlencoded`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+##### defaultCharset
+
+The default charset to parse as, if not specified in content-type. Must be
+either `utf-8` or `iso-8859-1`. Defaults to `utf-8`.
+
+##### charsetSentinel
+
+Whether to let the value of the `utf8` parameter take precedence as the charset
+selector. It requires the form to contain a parameter named `utf8` with a value
+of `✓`. Defaults to `false`.
+
+##### interpretNumericEntities
+
+Whether to decode numeric entities such as `☺` when parsing an iso-8859-1
+form. Defaults to `false`.
+
+##### depth
+
+The `depth` option is used to configure the maximum depth of the `qs` library when `extended` is `true`. This allows you to limit the amount of keys that are parsed and can be useful to prevent certain types of abuse. Defaults to `32`. It is recommended to keep this value as low as possible.
+
+## Errors
+
+The middlewares provided by this module create errors using the
+[`http-errors` module](https://www.npmjs.com/package/http-errors). The errors
+will typically have a `status`/`statusCode` property that contains the suggested
+HTTP response code, an `expose` property to determine if the `message` property
+should be displayed to the client, a `type` property to determine the type of
+error without matching against the `message`, and a `body` property containing
+the read body, if available.
+
+The following are the common errors created, though any error can come through
+for various reasons.
+
+### content encoding unsupported
+
+This error will occur when the request had a `Content-Encoding` header that
+contained an encoding but the "inflation" option was set to `false`. The
+`status` property is set to `415`, the `type` property is set to
+`'encoding.unsupported'`, and the `charset` property will be set to the
+encoding that is unsupported.
+
+### entity parse failed
+
+This error will occur when the request contained an entity that could not be
+parsed by the middleware. The `status` property is set to `400`, the `type`
+property is set to `'entity.parse.failed'`, and the `body` property is set to
+the entity value that failed parsing.
+
+### entity verify failed
+
+This error will occur when the request contained an entity that could not be
+failed verification by the defined `verify` option. The `status` property is
+set to `403`, the `type` property is set to `'entity.verify.failed'`, and the
+`body` property is set to the entity value that failed verification.
+
+### request aborted
+
+This error will occur when the request is aborted by the client before reading
+the body has finished. The `received` property will be set to the number of
+bytes received before the request was aborted and the `expected` property is
+set to the number of expected bytes. The `status` property is set to `400`
+and `type` property is set to `'request.aborted'`.
+
+### request entity too large
+
+This error will occur when the request body's size is larger than the "limit"
+option. The `limit` property will be set to the byte limit and the `length`
+property will be set to the request body's length. The `status` property is
+set to `413` and the `type` property is set to `'entity.too.large'`.
+
+### request size did not match content length
+
+This error will occur when the request's length did not match the length from
+the `Content-Length` header. This typically occurs when the request is malformed,
+typically when the `Content-Length` header was calculated based on characters
+instead of bytes. The `status` property is set to `400` and the `type` property
+is set to `'request.size.invalid'`.
+
+### stream encoding should not be set
+
+This error will occur when something called the `req.setEncoding` method prior
+to this middleware. This module operates directly on bytes only and you cannot
+call `req.setEncoding` when using this module. The `status` property is set to
+`500` and the `type` property is set to `'stream.encoding.set'`.
+
+### stream is not readable
+
+This error will occur when the request is no longer readable when this middleware
+attempts to read it. This typically means something other than a middleware from
+this module read the request body already and the middleware was also configured to
+read the same request. The `status` property is set to `500` and the `type`
+property is set to `'stream.not.readable'`.
+
+### too many parameters
+
+This error will occur when the content of the request exceeds the configured
+`parameterLimit` for the `urlencoded` parser. The `status` property is set to
+`413` and the `type` property is set to `'parameters.too.many'`.
+
+### unsupported charset "BOGUS"
+
+This error will occur when the request had a charset parameter in the
+`Content-Type` header, but the `iconv-lite` module does not support it OR the
+parser does not support it. The charset is contained in the message as well
+as in the `charset` property. The `status` property is set to `415`, the
+`type` property is set to `'charset.unsupported'`, and the `charset` property
+is set to the charset that is unsupported.
+
+### unsupported content encoding "bogus"
+
+This error will occur when the request had a `Content-Encoding` header that
+contained an unsupported encoding. The encoding is contained in the message
+as well as in the `encoding` property. The `status` property is set to `415`,
+the `type` property is set to `'encoding.unsupported'`, and the `encoding`
+property is set to the encoding that is unsupported.
+
+### The input exceeded the depth
+
+This error occurs when using `bodyParser.urlencoded` with the `extended` property set to `true` and the input exceeds the configured `depth` option. The `status` property is set to `400`. It is recommended to review the `depth` option and evaluate if it requires a higher value. When the `depth` option is set to `32` (default value), the error will not be thrown.
+
+## Examples
+
+### Express/Connect top-level generic
+
+This example demonstrates adding a generic JSON and URL-encoded parser as a
+top-level middleware, which will parse the bodies of all incoming requests.
+This is the simplest setup.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// parse application/x-www-form-urlencoded
+app.use(bodyParser.urlencoded());
+
+// parse application/json
+app.use(bodyParser.json());
+
+app.use(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.write('you posted:\n');
+ res.end(String(JSON.stringify(req.body, null, 2)));
+});
+```
+
+### Express route-specific
+
+This example demonstrates adding body parsers specifically to the routes that
+need them. In general, this is the most recommended way to use body-parser with
+Express.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// create application/json parser
+const jsonParser = bodyParser.json();
+
+// create application/x-www-form-urlencoded parser
+const urlencodedParser = bodyParser.urlencoded();
+
+// POST /login gets urlencoded bodies
+app.post('/login', urlencodedParser, function (req, res) {
+ if (!req.body || !req.body.username) res.sendStatus(400);
+ res.send('welcome, ' + req.body.username);
+});
+
+// POST /api/users gets JSON bodies
+app.post('/api/users', jsonParser, function (req, res) {
+ if (!req.body) res.sendStatus(400);
+ // create user in req.body
+});
+```
+
+### Change accepted type for parsers
+
+All the parsers accept a `type` option which allows you to change the
+`Content-Type` that the middleware will parse.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// parse various different custom JSON types as JSON
+app.use(bodyParser.json({ type: 'application/*+json' }));
+
+// parse some custom thing into a Buffer
+app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }));
+
+// parse an HTML body into a string
+app.use(bodyParser.text({ type: 'text/html' }));
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/body-parser/ci.yml?branch=master&label=ci
+[ci-url]: https://github.com/expressjs/body-parser/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coverallsCoverage/github/expressjs/body-parser?branch=master
+[coveralls-url]: https://coveralls.io/r/expressjs/body-parser?branch=master
+[npm-downloads-image]: https://img.shields.io/npm/dm/body-parser
+[npm-url]: https://npmjs.com/package/body-parser
+[npm-version-image]: https://img.shields.io/npm/v/body-parser
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/body-parser/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/body-parser
diff --git a/astro/src/content/resources/de/middleware/compression.md b/astro/src/content/resources/de/middleware/compression.md
new file mode 100644
index 0000000000..6ac63fcb7a
--- /dev/null
+++ b/astro/src/content/resources/de/middleware/compression.md
@@ -0,0 +1,314 @@
+---
+title: Express compression middleware
+module: compression
+---
+
+# compression
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+[![Funding][funding-image]][funding-url]
+
+Node.js compression middleware.
+
+The following compression codings are supported:
+
+- deflate
+- gzip
+- br (brotli)
+
+**Note** Brotli is supported only since Node.js versions v11.7.0 and v10.16.0.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```bash
+$ npm install compression
+```
+
+## API
+
+```js
+var compression = require('compression');
+```
+
+### compression([options])
+
+Returns the compression middleware using the given `options`. The middleware
+will attempt to compress response bodies for all requests that traverse through
+the middleware, based on the given `options`.
+
+This middleware will never compress responses that include a `Cache-Control`
+header with the [`no-transform` directive](https://tools.ietf.org/html/rfc7234#section-5.2.2.4),
+as compressing will transform the body.
+
+#### Options
+
+`compression()` accepts these properties in the options object. In addition to
+those listed below, [zlib](https://nodejs.org/api/zlib.html) options may be
+passed in to the options object or
+[brotli](https://nodejs.org/api/zlib.html#zlib_class_brotlioptions) options.
+
+##### chunkSize
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_CHUNK`, or `16384`.
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### filter
+
+Type: `Function`
+
+A function to decide if the response should be considered for compression.
+This function is called as `filter(req, res)` and is expected to return
+`true` to consider the response for compression, or `false` to not compress
+the response.
+
+The default filter function uses the [compressible](https://www.npmjs.com/package/compressible)
+module to determine if `res.getHeader('Content-Type')` is compressible.
+
+##### level
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_COMPRESSION`, or `-1`
+
+The level of zlib compression to apply to responses. A higher level will result
+in better compression, but will take longer to complete. A lower level will
+result in less compression, but will be much faster.
+
+This is an integer in the range of `0` (no compression) to `9` (maximum
+compression). The special value `-1` can be used to mean the "default
+compression level", which is a default compromise between speed and
+compression (currently equivalent to level 6).
+
+- `-1` Default compression level (also `zlib.constants.Z_DEFAULT_COMPRESSION`).
+- `0` No compression (also `zlib.constants.Z_NO_COMPRESSION`).
+- `1` Fastest compression (also `zlib.constants.Z_BEST_SPEED`).
+- `2`
+- `3`
+- `4`
+- `5`
+- `6` (currently what `zlib.constants.Z_DEFAULT_COMPRESSION` points to).
+- `7`
+- `8`
+- `9` Best compression (also `zlib.constants.Z_BEST_COMPRESSION`).
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### memLevel
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_MEMLEVEL`, or `8`
+
+This specifies how much memory should be allocated for the internal compression
+state and is an integer in the range of `1` (minimum level) and `9` (maximum
+level).
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### brotli
+
+Type: `Object`
+
+This specifies the options for configuring Brotli. See [Node.js documentation](https://nodejs.org/api/zlib.html#class-brotlioptions) for a complete list of available options.
+
+##### strategy
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_STRATEGY`
+
+This is used to tune the compression algorithm. This value only affects the
+compression ratio, not the correctness of the compressed output, even if it
+is not set appropriately.
+
+- `zlib.constants.Z_DEFAULT_STRATEGY` Use for normal data.
+- `zlib.constants.Z_FILTERED` Use for data produced by a filter (or predictor).
+ Filtered data consists mostly of small values with a somewhat random
+ distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect is to force more Huffman coding and less
+ string matching; it is somewhat intermediate between `zlib.constants.Z_DEFAULT_STRATEGY`
+ and `zlib.constants.Z_HUFFMAN_ONLY`.
+- `zlib.constants.Z_FIXED` Use to prevent the use of dynamic Huffman codes, allowing
+ for a simpler decoder for special applications.
+- `zlib.constants.Z_HUFFMAN_ONLY` Use to force Huffman encoding only (no string match).
+- `zlib.constants.Z_RLE` Use to limit match distances to one (run-length encoding).
+ This is designed to be almost as fast as `zlib.constants.Z_HUFFMAN_ONLY`, but give
+ better compression for PNG image data.
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### threshold
+
+Type: `Number` or `String`
+Default: `1kb`
+
+The byte threshold for the response body size before compression is considered
+for the response. This is a number of bytes or any string
+accepted by the [bytes](https://www.npmjs.com/package/bytes) module.
+
+**Note** this is only an advisory setting; if the response size cannot be determined
+at the time the response headers are written, then it is assumed the response is
+_over_ the threshold. To guarantee the response size can be determined, be sure
+set a `Content-Length` response header.
+
+##### windowBits
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_WINDOWBITS`, or `15`
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### enforceEncoding
+
+Type: `String`
+Default: `identity`
+
+This is the default encoding to use when the client does not specify an encoding in the request's [Accept-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) header.
+
+#### .filter
+
+The default `filter` function. This is used to construct a custom filter
+function that is an extension of the default function.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+app.use(compression({ filter: shouldCompress }));
+
+function shouldCompress(req, res) {
+ if (req.headers['x-no-compression']) {
+ // don't compress responses with this request header
+ return false;
+ }
+
+ // fallback to standard filter function
+ return compression.filter(req, res);
+}
+```
+
+### res.flush
+
+This module adds a `res.flush()` method to force the partially-compressed
+response to be flushed to the client.
+
+## Examples
+
+### express
+
+When using this module with express, simply `app.use` the module as
+high as you like. Requests that pass through the middleware will be compressed.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress all responses
+app.use(compression());
+
+// add all routes
+```
+
+### Node.js HTTP server
+
+```js
+var compression = require('compression')({ threshold: 0 });
+var http = require('http');
+
+function createServer(fn) {
+ return http.createServer(function (req, res) {
+ compression(req, res, function (err) {
+ if (err) {
+ res.statusCode = err.status || 500;
+ res.end(err.message);
+ return;
+ }
+
+ fn(req, res);
+ });
+ });
+}
+
+var server = createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello world!');
+});
+
+server.listen(3000, () => {
+ console.log('> Listening at http://localhost:3000');
+});
+```
+
+### Server-Sent Events
+
+Because of the nature of compression this module does not work out of the box
+with server-sent events. To compress content, a window of the output needs to
+be buffered up in order to get good compression. Typically when using server-sent
+events, there are certain block of data that need to reach the client.
+
+You can achieve this by calling `res.flush()` when you need the data written to
+actually make it to the client.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress responses
+app.use(compression());
+
+// server-sent event stream
+app.get('/events', function (req, res) {
+ res.setHeader('Content-Type', 'text/event-stream');
+ res.setHeader('Cache-Control', 'no-cache');
+
+ // send a ping approx every 2 seconds
+ var timer = setInterval(function () {
+ res.write('data: ping\n\n');
+
+ // !!! this is the important part
+ res.flush();
+ }, 2000);
+
+ res.on('close', function () {
+ clearInterval(timer);
+ });
+});
+```
+
+## Contributing
+
+The Express.js project welcomes all constructive contributions. Contributions take many forms,
+from code for bug fixes and enhancements, to additions and fixes to documentation, additional
+tests, triaging incoming pull requests and issues, and more!
+
+See the [Contributing Guide](https://github.com/expressjs/express/blob/master/Contributing.md) for more technical details on contributing.
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://badgen.net/npm/v/compression
+[npm-url]: https://npmjs.org/package/compression
+[downloads-image]: https://badgen.net/npm/dm/compression
+[downloads-url]: https://npmcharts.com/compare/compression?minimal=true
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/compression/master?label=CI
+[github-actions-ci-url]: https://github.com/expressjs/compression/actions?query=workflow%3Aci
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/compression/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/compression
+[funding-url]: https://opencollective.com/express
+[funding-image]: https://badgen.net/badge/icon/sponsor/pink?icon=github&label=Open%20Collective
diff --git a/astro/src/content/resources/de/middleware/cookie-parser.md b/astro/src/content/resources/de/middleware/cookie-parser.md
new file mode 100644
index 0000000000..2a59496387
--- /dev/null
+++ b/astro/src/content/resources/de/middleware/cookie-parser.md
@@ -0,0 +1,124 @@
+---
+title: Express cookie-parser middleware
+module: cookie-parser
+---
+
+# cookie-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Parse `Cookie` header and populate `req.cookies` with an object keyed by the
+cookie names. Optionally you may enable signed cookie support by passing a
+`secret` string, which assigns `req.secret` so it may be used by other
+middleware.
+
+## Installation
+
+```sh
+$ npm install cookie-parser
+```
+
+## API
+
+```js
+var cookieParser = require('cookie-parser');
+```
+
+### cookieParser(secret, options)
+
+Create a new cookie parser middleware function using the given `secret` and
+`options`.
+
+- `secret` a string or array used for signing cookies. This is optional and if
+ not specified, will not parse signed cookies. If a string is provided, this
+ is used as the secret. If an array is provided, an attempt will be made to
+ unsign the cookie with each secret in order.
+- `options` an object that is passed to `cookie.parse` as the second option. See
+ [cookie](https://www.npmjs.org/package/cookie) for more information.
+ - `decode` a function to decode the value of the cookie
+
+The middleware will parse the `Cookie` header on the request and expose the
+cookie data as the property `req.cookies` and, if a `secret` was provided, as
+the property `req.signedCookies`. These properties are name value pairs of the
+cookie name to cookie value.
+
+When `secret` is provided, this module will unsign and validate any signed cookie
+values and move those name value pairs from `req.cookies` into `req.signedCookies`.
+A signed cookie is a cookie that has a value prefixed with `s:`. Signed cookies
+that fail signature validation will have the value `false` instead of the tampered
+value.
+
+In addition, this module supports special "JSON cookies". These are cookie where
+the value is prefixed with `j:`. When these values are encountered, the value will
+be exposed as the result of `JSON.parse`. If parsing fails, the original value will
+remain.
+
+### cookieParser.JSONCookie(str)
+
+Parse a cookie value as a JSON cookie. This will return the parsed JSON value
+if it was a JSON cookie, otherwise, it will return the passed value.
+
+### cookieParser.JSONCookies(cookies)
+
+Given an object, this will iterate over the keys and call `JSONCookie` on each
+value, replacing the original value with the parsed value. This returns the
+same object that was passed in.
+
+### cookieParser.signedCookie(str, secret)
+
+Parse a cookie value as a signed cookie. This will return the parsed unsigned
+value if it was a signed cookie and the signature was valid. If the value was
+not signed, the original value is returned. If the value was signed but the
+signature could not be validated, `false` is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+### cookieParser.signedCookies(cookies, secret)
+
+Given an object, this will iterate over the keys and check if any value is a
+signed cookie. If it is a signed cookie and the signature is valid, the key
+will be deleted from the object and added to the new object that is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+## Example
+
+```js
+var express = require('express');
+var cookieParser = require('cookie-parser');
+
+var app = express();
+app.use(cookieParser());
+
+app.get('/', function (req, res) {
+ // Cookies that have not been signed
+ console.log('Cookies: ', req.cookies);
+
+ // Cookies that have been signed
+ console.log('Signed Cookies: ', req.signedCookies);
+});
+
+app.listen(8080);
+
+// curl command that sends an HTTP request with two cookies
+// curl http://127.0.0.1:8080 --cookie "Cho=Kim;Greet=Hello"
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/cookie-parser/master?label=ci
+[ci-url]: https://github.com/expressjs/cookie-parser/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/cookie-parser/master
+[coveralls-url]: https://coveralls.io/r/expressjs/cookie-parser?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/cookie-parser
+[npm-url]: https://npmjs.org/package/cookie-parser
+[npm-version-image]: https://badgen.net/npm/v/cookie-parser
diff --git a/astro/src/content/resources/de/middleware/cookie-session.md b/astro/src/content/resources/de/middleware/cookie-session.md
new file mode 100644
index 0000000000..2d6d1f885b
--- /dev/null
+++ b/astro/src/content/resources/de/middleware/cookie-session.md
@@ -0,0 +1,124 @@
+---
+title: Express cookie-session middleware
+module: cookie-session
+---
+
+# cookie-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Parse `Cookie` header and populate `req.cookies` with an object keyed by the
+cookie names. Optionally you may enable signed cookie support by passing a
+`secret` string, which assigns `req.secret` so it may be used by other
+middleware.
+
+## Installation
+
+```sh
+$ npm install cookie-parser
+```
+
+## API
+
+```js
+var cookieParser = require('cookie-parser');
+```
+
+### cookieParser(secret, options)
+
+Create a new cookie parser middleware function using the given `secret` and
+`options`.
+
+- `secret` a string or array used for signing cookies. This is optional and if
+ not specified, will not parse signed cookies. If a string is provided, this
+ is used as the secret. If an array is provided, an attempt will be made to
+ unsign the cookie with each secret in order.
+- `options` an object that is passed to `cookie.parse` as the second option. See
+ [cookie](https://www.npmjs.org/package/cookie) for more information.
+ - `decode` a function to decode the value of the cookie
+
+The middleware will parse the `Cookie` header on the request and expose the
+cookie data as the property `req.cookies` and, if a `secret` was provided, as
+the property `req.signedCookies`. These properties are name value pairs of the
+cookie name to cookie value.
+
+When `secret` is provided, this module will unsign and validate any signed cookie
+values and move those name value pairs from `req.cookies` into `req.signedCookies`.
+A signed cookie is a cookie that has a value prefixed with `s:`. Signed cookies
+that fail signature validation will have the value `false` instead of the tampered
+value.
+
+In addition, this module supports special "JSON cookies". These are cookie where
+the value is prefixed with `j:`. When these values are encountered, the value will
+be exposed as the result of `JSON.parse`. If parsing fails, the original value will
+remain.
+
+### cookieParser.JSONCookie(str)
+
+Parse a cookie value as a JSON cookie. This will return the parsed JSON value
+if it was a JSON cookie, otherwise, it will return the passed value.
+
+### cookieParser.JSONCookies(cookies)
+
+Given an object, this will iterate over the keys and call `JSONCookie` on each
+value, replacing the original value with the parsed value. This returns the
+same object that was passed in.
+
+### cookieParser.signedCookie(str, secret)
+
+Parse a cookie value as a signed cookie. This will return the parsed unsigned
+value if it was a signed cookie and the signature was valid. If the value was
+not signed, the original value is returned. If the value was signed but the
+signature could not be validated, `false` is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+### cookieParser.signedCookies(cookies, secret)
+
+Given an object, this will iterate over the keys and check if any value is a
+signed cookie. If it is a signed cookie and the signature is valid, the key
+will be deleted from the object and added to the new object that is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+## Example
+
+```js
+var express = require('express');
+var cookieParser = require('cookie-parser');
+
+var app = express();
+app.use(cookieParser());
+
+app.get('/', function (req, res) {
+ // Cookies that have not been signed
+ console.log('Cookies: ', req.cookies);
+
+ // Cookies that have been signed
+ console.log('Signed Cookies: ', req.signedCookies);
+});
+
+app.listen(8080);
+
+// curl command that sends an HTTP request with two cookies
+// curl http://127.0.0.1:8080 --cookie "Cho=Kim;Greet=Hello"
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/cookie-parser/master?label=ci
+[ci-url]: https://github.com/expressjs/cookie-parser/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/cookie-parser/master
+[coveralls-url]: https://coveralls.io/r/expressjs/cookie-parser?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/cookie-parser
+[npm-url]: https://npmjs.org/package/cookie-parser
+[npm-version-image]: https://badgen.net/npm/v/cookie-parser
diff --git a/astro/src/content/resources/de/middleware/cors.md b/astro/src/content/resources/de/middleware/cors.md
new file mode 100644
index 0000000000..55d70922cb
--- /dev/null
+++ b/astro/src/content/resources/de/middleware/cors.md
@@ -0,0 +1,261 @@
+---
+title: Express cors middleware
+module: cors
+---
+
+# cors
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+CORS is a [Node.js](https://nodejs.org/en/) package for providing a [Connect](https://github.com/senchalabs/connect)/[Express](https://expressjs.com/) middleware that can be used to enable [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS) with various options.
+
+- [Installation](#installation)
+- [Usage](#usage)
+ - [Simple Usage](#simple-usage-enable-all-cors-requests)
+ - [Enable CORS for a Single Route](#enable-cors-for-a-single-route)
+ - [Configuring CORS](#configuring-cors)
+ - [Configuring CORS w/ Dynamic Origin](#configuring-cors-w-dynamic-origin)
+ - [Enabling CORS Pre-Flight](#enabling-cors-pre-flight)
+ - [Customizing CORS Settings Dynamically per Request](#customizing-cors-settings-dynamically-per-request)
+- [Configuration Options](#configuration-options)
+- [License](#license)
+- [Original Author](#original-author)
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/downloading-and-installing-packages-locally):
+
+```sh
+$ npm install cors
+```
+
+## Usage
+
+### Simple Usage (Enable _All_ CORS Requests)
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.use(cors());
+
+app.get('/products/:id', function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for all origins!' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Enable CORS for a Single Route
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.get('/products/:id', cors(), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for a Single Route' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Configuring CORS
+
+See the [configuration options](#configuration-options) for details.
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+var corsOptions = {
+ origin: 'http://example.com',
+ optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
+};
+
+app.get('/products/:id', cors(corsOptions), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for only example.com.' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Configuring CORS w/ Dynamic Origin
+
+This module supports validating the origin dynamically using a function provided
+to the `origin` option. This function will be passed a string that is the origin
+(or `undefined` if the request has no origin), and a `callback` with the signature
+`callback(error, origin)`.
+
+The `origin` argument to the callback can be any value allowed for the `origin`
+option of the middleware, except a function. See the
+[configuration options](#configuration-options) section for more information on all
+the possible value types.
+
+This function is designed to allow the dynamic loading of allowed origin(s) from
+a backing datasource, like a database.
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+var corsOptions = {
+ origin: function (origin, callback) {
+ // db.loadOrigins is an example call to load
+ // a list of origins from a backing database
+ db.loadOrigins(function (error, origins) {
+ callback(error, origins);
+ });
+ },
+};
+
+app.get('/products/:id', cors(corsOptions), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for an allowed domain.' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Enabling CORS Pre-Flight
+
+Certain CORS requests are considered 'complex' and require an initial
+`OPTIONS` request (called the "pre-flight request"). An example of a
+'complex' CORS request is one that uses an HTTP verb other than
+GET/HEAD/POST (such as DELETE) or that uses custom headers. To enable
+pre-flighting, you must add a new OPTIONS handler for the route you want
+to support:
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.options('/products/:id', cors()); // enable pre-flight request for DELETE request
+app.del('/products/:id', cors(), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for all origins!' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+You can also enable pre-flight across-the-board like so:
+
+```javascript
+app.options('*', cors()); // include before other routes
+```
+
+NOTE: When using this middleware as an application level middleware (for
+example, `app.use(cors())`), pre-flight requests are already handled for all
+routes.
+
+### Customizing CORS Settings Dynamically per Request
+
+For APIs that require different CORS configurations for specific routes or requests, you can dynamically generate CORS options based on the incoming request. The `cors` middleware allows you to achieve this by passing a function instead of static options. This function is called for each incoming request and must use the callback pattern to return the appropriate CORS options.
+
+The function accepts:
+
+1. **`req`**:
+ - The incoming request object.
+
+2. **`callback(error, corsOptions)`**:
+ - A function used to return the computed CORS options.
+ - **Arguments**:
+ - **`error`**: Pass `null` if there’s no error, or an error object to indicate a failure.
+ - **`corsOptions`**: An object specifying the CORS policy for the current request.
+
+Here’s an example that handles both public routes and restricted, credential-sensitive routes:
+
+```javascript
+var dynamicCorsOptions = function (req, callback) {
+ var corsOptions;
+ if (req.path.startsWith('/auth/connect/')) {
+ corsOptions = {
+ origin: 'http://mydomain.com', // Allow only a specific origin
+ credentials: true, // Enable cookies and credentials
+ };
+ } else {
+ corsOptions = { origin: '*' }; // Allow all origins for other routes
+ }
+ callback(null, corsOptions);
+};
+
+app.use(cors(dynamicCorsOptions));
+
+app.get('/auth/connect/twitter', function (req, res) {
+ res.send('CORS dynamically applied for Twitter authentication.');
+});
+
+app.get('/public', function (req, res) {
+ res.send('Public data with open CORS.');
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+## Configuration Options
+
+- `origin`: Configures the **Access-Control-Allow-Origin** CORS header. Possible values:
+ - `Boolean` - set `origin` to `true` to reflect the [request origin](https://datatracker.ietf.org/doc/html/draft-abarth-origin-09), as defined by `req.header('Origin')`, or set it to `false` to disable CORS.
+ - `String` - set `origin` to a specific origin. For example, if you set it to
+ - `"http://example.com"` only requests from "http://example.com" will be allowed.
+ - `"*"` for all domains to be allowed.
+ - `RegExp` - set `origin` to a regular expression pattern which will be used to test the request origin. If it's a match, the request origin will be reflected. For example the pattern `/example\.com$/` will reflect any request that is coming from an origin ending with "example.com".
+ - `Array` - set `origin` to an array of valid origins. Each origin can be a `String` or a `RegExp`. For example `["http://example1.com", /\.example2\.com$/]` will accept any request from "http://example1.com" or from a subdomain of "example2.com".
+ - `Function` - set `origin` to a function implementing some custom logic. The function takes the request origin as the first parameter and a callback (called as `callback(err, origin)`, where `origin` is a non-function value of the `origin` option) as the second.
+- `methods`: Configures the **Access-Control-Allow-Methods** CORS header. Expects a comma-delimited string (ex: 'GET,PUT,POST') or an array (ex: `['GET', 'PUT', 'POST']`).
+- `allowedHeaders`: Configures the **Access-Control-Allow-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Type,Authorization') or an array (ex: `['Content-Type', 'Authorization']`). If not specified, defaults to reflecting the headers specified in the request's **Access-Control-Request-Headers** header.
+- `exposedHeaders`: Configures the **Access-Control-Expose-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Range,X-Content-Range') or an array (ex: `['Content-Range', 'X-Content-Range']`). If not specified, no custom headers are exposed.
+- `credentials`: Configures the **Access-Control-Allow-Credentials** CORS header. Set to `true` to pass the header, otherwise it is omitted.
+- `maxAge`: Configures the **Access-Control-Max-Age** CORS header. Set to an integer to pass the header, otherwise it is omitted.
+- `preflightContinue`: Pass the CORS preflight response to the next handler.
+- `optionsSuccessStatus`: Provides a status code to use for successful `OPTIONS` requests, since some legacy browsers (IE11, various SmartTVs) choke on `204`.
+
+The default configuration is the equivalent of:
+
+```json
+{
+ "origin": "*",
+ "methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
+ "preflightContinue": false,
+ "optionsSuccessStatus": 204
+}
+```
+
+For details on the effect of each CORS header, read [this](https://web.dev/articles/cross-origin-resource-sharing) article.
+
+## License
+
+[MIT License](http://www.opensource.org/licenses/mit-license.php)
+
+## Original Author
+
+[Troy Goode](https://github.com/TroyGoode) ([troygoode@gmail.com](mailto:troygoode@gmail.com))
+
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/cors/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/cors?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/cors.svg
+[downloads-url]: https://npmjs.com/package/cors
+[github-actions-ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/cors/ci.yml?branch=master&label=ci
+[github-actions-ci-url]: https://github.com/expressjs/cors?query=workflow%3Aci
+[npm-image]: https://img.shields.io/npm/v/cors.svg
+[npm-url]: https://npmjs.com/package/cors
diff --git a/astro/src/content/resources/de/middleware/errorhandler.md b/astro/src/content/resources/de/middleware/errorhandler.md
new file mode 100644
index 0000000000..20df618320
--- /dev/null
+++ b/astro/src/content/resources/de/middleware/errorhandler.md
@@ -0,0 +1,133 @@
+---
+title: Express errorhandler middleware
+module: errorhandler
+---
+
+# errorhandler
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Development-only error handler middleware.
+
+This middleware is only intended to be used in a development environment, as
+the _full error stack traces and internal details of any object passed to this
+module_ will be sent back to the client when an error occurs.
+
+When an object is provided to Express as an error, this module will display
+as much about this object as possible, and will do so by using content negotiation
+for the response between HTML, JSON, and plain text.
+
+- When the object is a standard `Error` object, the string provided by the
+ `stack` property will be returned in HTML/text responses.
+- When the object is a non-`Error` object, the result of
+ [util.inspect](https://nodejs.org/api/util.html#util_util_inspect_object_options)
+ will be returned in HTML/text responses.
+- For JSON responses, the result will be an object with all enumerable properties
+ from the object in the response.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install errorhandler
+```
+
+## API
+
+
+
+```js
+var errorhandler = require('errorhandler');
+```
+
+### errorhandler(options)
+
+Create new middleware to handle errors and respond with content negotiation.
+
+#### Options
+
+Error handler accepts these properties in the options object.
+
+##### log
+
+Provide a function to be called with the error and a string representation of
+the error. Can be used to write the error to any desired location, or set to
+`false` to only send the error back in the response. Called as
+`log(err, str, req, res)` where `err` is the `Error` object, `str` is a string
+representation of the error, `req` is the request object and `res` is the
+response object (note, this function is invoked _after_ the response has been
+written).
+
+The default value for this option is `true` unless `process.env.NODE_ENV === 'test'`.
+
+Possible values:
+
+- `true`: Log errors using `console.error(str)`.
+- `false`: Only send the error back in the response.
+- A function: pass the error to a function for handling.
+
+## Examples
+
+### Simple example
+
+Basic example of adding this middleware as the error handler only in development
+with `connect` (`express` also can be used in this example).
+
+```js
+var connect = require('connect');
+var errorhandler = require('errorhandler');
+
+var app = connect();
+
+// assumes NODE_ENV is set by the user
+if (process.env.NODE_ENV === 'development') {
+ // only use in development
+ app.use(errorhandler());
+}
+```
+
+### Custom output location
+
+Sometimes you may want to output the errors to a different location than STDERR
+during development, like a system notification, for example.
+
+
+
+```js
+var connect = require('connect');
+var errorhandler = require('errorhandler');
+var notifier = require('node-notifier');
+
+var app = connect();
+
+// assumes NODE_ENV is set by the user
+if (process.env.NODE_ENV === 'development') {
+ // only use in development
+ app.use(errorhandler({ log: errorNotification }));
+}
+
+function errorNotification(err, str, req) {
+ var title = 'Error in ' + req.method + ' ' + req.url;
+
+ notifier.notify({
+ title: title,
+ message: str,
+ });
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/errorhandler/master
+[coveralls-url]: https://coveralls.io/r/expressjs/errorhandler?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/errorhandler
+[npm-url]: https://npmjs.org/package/errorhandler
+[npm-version-image]: https://badgen.net/npm/v/errorhandler
diff --git a/astro/src/content/resources/de/middleware/method-override.md b/astro/src/content/resources/de/middleware/method-override.md
new file mode 100644
index 0000000000..7b97ab855e
--- /dev/null
+++ b/astro/src/content/resources/de/middleware/method-override.md
@@ -0,0 +1,187 @@
+---
+title: Express method-override middleware
+module: method-override
+---
+
+# method-override
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][travis-image]][travis-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Lets you use HTTP verbs such as PUT or DELETE in places where the client doesn't support it.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install method-override
+```
+
+## API
+
+**NOTE** It is very important that this module is used **before** any module that
+needs to know the method of the request (for example, it _must_ be used prior to
+the `csurf` module).
+
+### methodOverride(getter, options)
+
+Create a new middleware function to override the `req.method` property with a new
+value. This value will be pulled from the provided `getter`.
+
+- `getter` - The getter to use to look up the overridden request method for the request. (default: `X-HTTP-Method-Override`)
+- `options.methods` - The allowed methods the original request must be in to check for a method override value. (default: `['POST']`)
+
+If the found method is supported by node.js core, then `req.method` will be set to
+this value, as if it has originally been that value. The previous `req.method`
+value will be stored in `req.originalMethod`.
+
+#### getter
+
+This is the method of getting the override value from the request. If a function is provided,
+the `req` is passed as the first argument, the `res` as the second argument and the method is
+expected to be returned. If a string is provided, the string is used to look up the method
+with the following rules:
+
+- If the string starts with `X-`, then it is treated as the name of a header and that header
+ is used for the method override. If the request contains the same header multiple times, the
+ first occurrence is used.
+- All other strings are treated as a key in the URL query string.
+
+#### options.methods
+
+This allows the specification of what methods(s) the request _MUST_ be in in order to check for
+the method override value. This defaults to only `POST` methods, which is the only method the
+override should arrive in. More methods may be specified here, but it may introduce security
+issues and cause weird behavior when requests travel through caches. This value is an array
+of methods in upper-case. `null` can be specified to allow all methods.
+
+## Examples
+
+### override using a header
+
+To use a header to override the method, specify the header name
+as a string argument to the `methodOverride` function. To then make
+the call, send a `POST` request to a URL with the overridden method
+as the value of that header. This method of using a header would
+typically be used in conjunction with `XMLHttpRequest` on implementations
+that do not support the method you are trying to use.
+
+```js
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// override with the X-HTTP-Method-Override header in the request
+app.use(methodOverride('X-HTTP-Method-Override'));
+```
+
+Example call with header override using `XMLHttpRequest`:
+
+
+
+```js
+const xhr = new XMLHttpRequest();
+xhr.onload = onload;
+xhr.open('post', '/resource', true);
+xhr.setRequestHeader('X-HTTP-Method-Override', 'DELETE');
+xhr.send();
+
+function onload() {
+ alert('got response: ' + this.responseText);
+}
+```
+
+### override using a query value
+
+To use a query string value to override the method, specify the query
+string key as a string argument to the `methodOverride` function. To
+then make the call, send a `POST` request to a URL with the overridden
+method as the value of that query string key. This method of using a
+query value would typically be used in conjunction with plain HTML
+`
+```
+
+### multiple format support
+
+```js
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// override with different headers; last one takes precedence
+app.use(methodOverride('X-HTTP-Method')); // Microsoft
+app.use(methodOverride('X-HTTP-Method-Override')); // Google/GData
+app.use(methodOverride('X-Method-Override')); // IBM
+```
+
+### custom logic
+
+You can implement any kind of custom logic with a function for the `getter`. The following
+implements the logic for looking in `req.body` that was in `method-override@1`:
+
+```js
+const bodyParser = require('body-parser');
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// NOTE: when using req.body, you must fully parse the request body
+// before you call methodOverride() in your middleware stack,
+// otherwise req.body will not be populated.
+app.use(bodyParser.urlencoded());
+app.use(
+ methodOverride(function (req, res) {
+ if (req.body && typeof req.body === 'object' && '_method' in req.body) {
+ // look in urlencoded POST bodies and delete it
+ const method = req.body._method;
+ delete req.body._method;
+ return method;
+ }
+ })
+);
+```
+
+Example call with query override using HTML `
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/method-override.svg
+[npm-url]: https://npmjs.org/package/method-override
+[travis-image]: https://img.shields.io/travis/expressjs/method-override/master.svg
+[travis-url]: https://travis-ci.org/expressjs/method-override
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/method-override/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/method-override?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/method-override.svg
+[downloads-url]: https://npmjs.org/package/method-override
diff --git a/astro/src/content/resources/de/middleware/morgan.md b/astro/src/content/resources/de/middleware/morgan.md
new file mode 100644
index 0000000000..5319d93d57
--- /dev/null
+++ b/astro/src/content/resources/de/middleware/morgan.md
@@ -0,0 +1,458 @@
+---
+title: Express morgan middleware
+module: morgan
+---
+
+# morgan
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+HTTP request logger middleware for node.js
+
+> Named after [Dexter](http://en.wikipedia.org/wiki/Dexter_Morgan), a show you should not watch until completion.
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install morgan
+```
+
+## API
+
+
+
+```js
+var morgan = require('morgan');
+```
+
+### morgan(format, options)
+
+Create a new morgan logger middleware function using the given `format` and `options`.
+The `format` argument may be a string of a predefined name (see below for the names),
+a string of a format string, or a function that will produce a log entry.
+
+The `format` function will be called with three arguments `tokens`, `req`, and `res`,
+where `tokens` is an object with all defined tokens, `req` is the HTTP request and `res`
+is the HTTP response. The function is expected to return a string that will be the log
+line, or `undefined` / `null` to skip logging.
+
+#### Using a predefined format string
+
+
+
+```js
+morgan('tiny');
+```
+
+#### Using format string of predefined tokens
+
+
+
+```js
+morgan(':method :url :status :res[content-length] - :response-time ms');
+```
+
+#### Using a custom format function
+
+
+
+```js
+morgan(function (tokens, req, res) {
+ return [
+ tokens.method(req, res),
+ tokens.url(req, res),
+ tokens.status(req, res),
+ tokens.res(req, res, 'content-length'),
+ '-',
+ tokens['response-time'](req, res),
+ 'ms',
+ ].join(' ');
+});
+```
+
+#### Options
+
+Morgan accepts these properties in the options object.
+
+##### immediate
+
+Write log line on request instead of response. This means that a requests will
+be logged even if the server crashes, _but data from the response (like the
+response code, content length, etc.) cannot be logged_.
+
+##### skip
+
+Function to determine if logging is skipped, defaults to `false`. This function
+will be called as `skip(req, res)`.
+
+
+
+```js
+// EXAMPLE: only log error responses
+morgan('combined', {
+ skip: function (req, res) {
+ return res.statusCode < 400;
+ },
+});
+```
+
+##### stream
+
+Output stream for writing log lines, defaults to `process.stdout`.
+
+#### Predefined Formats
+
+There are various pre-defined formats provided:
+
+##### combined
+
+Standard Apache combined log output.
+
+```
+:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"
+# will output
+::1 - - [27/Nov/2024:06:21:42 +0000] "GET /combined HTTP/1.1" 200 2 "-" "curl/8.7.1"
+```
+
+##### common
+
+Standard Apache common log output.
+
+```
+:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length]
+# will output
+::1 - - [27/Nov/2024:06:21:46 +0000] "GET /common HTTP/1.1" 200 2
+```
+
+##### dev
+
+Concise output colored by response status for development use. The `:status`
+token will be colored green for success codes, red for server error codes,
+yellow for client error codes, cyan for redirection codes, and uncolored
+for information codes.
+
+```
+:method :url :status :response-time ms - :res[content-length]
+# will output
+GET /dev 200 0.224 ms - 2
+```
+
+##### short
+
+Shorter than default, also including response time.
+
+```
+:remote-addr :remote-user :method :url HTTP/:http-version :status :res[content-length] - :response-time ms
+# will output
+::1 - GET /short HTTP/1.1 200 2 - 0.283 ms
+```
+
+##### tiny
+
+The minimal output.
+
+```
+:method :url :status :res[content-length] - :response-time ms
+# will output
+GET /tiny 200 2 - 0.188 ms
+```
+
+#### Tokens
+
+##### Creating new tokens
+
+To define a token, simply invoke `morgan.token()` with the name and a callback function.
+This callback function is expected to return a string value. The value returned is then
+available as ":type" in this case:
+
+
+
+```js
+morgan.token('type', function (req, res) {
+ return req.headers['content-type'];
+});
+```
+
+Calling `morgan.token()` using the same name as an existing token will overwrite that
+token definition.
+
+The token function is expected to be called with the arguments `req` and `res`, representing
+the HTTP request and HTTP response. Additionally, the token can accept further arguments of
+it's choosing to customize behavior.
+
+##### :date[format]
+
+The current date and time in UTC. The available formats are:
+
+- `clf` for the common log format (`"10/Oct/2000:13:55:36 +0000"`)
+- `iso` for the common ISO 8601 date time format (`2000-10-10T13:55:36.000Z`)
+- `web` for the common RFC 1123 date time format (`Tue, 10 Oct 2000 13:55:36 GMT`)
+
+If no format is given, then the default is `web`.
+
+##### :http-version
+
+The HTTP version of the request.
+
+##### :method
+
+The HTTP method of the request.
+
+##### :pid
+
+The process ID of the Node.js process handling the request.
+
+##### :referrer
+
+The Referrer header of the request. This will use the standard mis-spelled Referer header if exists, otherwise Referrer.
+
+##### :remote-addr
+
+The remote address of the request. This will use `req.ip`, otherwise the standard `req.connection.remoteAddress` value (socket address).
+
+##### :remote-user
+
+The user authenticated as part of Basic auth for the request.
+
+##### :req[header]
+
+The given `header` of the request. If the header is not present, the
+value will be displayed as `"-"` in the log.
+
+##### :res[header]
+
+The given `header` of the response. If the header is not present, the
+value will be displayed as `"-"` in the log.
+
+##### :response-time[digits]
+
+The time between the request coming into `morgan` and when the response
+headers are written, in milliseconds.
+
+The `digits` argument is a number that specifies the number of digits to
+include on the number, defaulting to `3`, which provides microsecond precision.
+
+##### :status
+
+The status code of the response.
+
+If the request/response cycle completes before a response was sent to the
+client (for example, the TCP socket closed prematurely by a client aborting
+the request), then the status will be empty (displayed as `"-"` in the log).
+
+##### :total-time[digits]
+
+The time between the request coming into `morgan` and when the response
+has finished being written out to the connection, in milliseconds.
+
+The `digits` argument is a number that specifies the number of digits to
+include on the number, defaulting to `3`, which provides microsecond precision.
+
+##### :url
+
+The URL of the request. This will use `req.originalUrl` if exists, otherwise `req.url`.
+
+##### :user-agent
+
+The contents of the User-Agent header of the request.
+
+### morgan.compile(format)
+
+Compile a format string into a `format` function for use by `morgan`. A format string
+is a string that represents a single log line and can utilize token syntax.
+Tokens are references by `:token-name`. If tokens accept arguments, they can
+be passed using `[]`, for example: `:token-name[pretty]` would pass the string
+`'pretty'` as an argument to the token `token-name`.
+
+The function returned from `morgan.compile` takes three arguments `tokens`, `req`, and
+`res`, where `tokens` is object with all defined tokens, `req` is the HTTP request and
+`res` is the HTTP response. The function will return a string that will be the log line,
+or `undefined` / `null` to skip logging.
+
+Normally formats are defined using `morgan.format(name, format)`, but for certain
+advanced uses, this compile function is directly available.
+
+## Examples
+
+### express/connect
+
+Sample app that will log all request in the Apache combined format to STDOUT
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+
+var app = express();
+
+app.use(morgan('combined'));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### vanilla http server
+
+Sample app that will log all request in the Apache combined format to STDOUT
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var morgan = require('morgan');
+
+// create "middleware"
+var logger = morgan('combined');
+
+http.createServer(function (req, res) {
+ var done = finalhandler(req, res);
+ logger(req, res, function (err) {
+ if (err) return done(err);
+
+ // respond to request
+ res.setHeader('content-type', 'text/plain');
+ res.end('hello, world!');
+ });
+});
+```
+
+### write logs to a file
+
+#### single file
+
+Sample app that will log all requests in the Apache combined format to the file
+`access.log`.
+
+```js
+var express = require('express');
+var fs = require('fs');
+var morgan = require('morgan');
+var path = require('path');
+
+var app = express();
+
+// create a write stream (in append mode)
+var accessLogStream = fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' });
+
+// setup the logger
+app.use(morgan('combined', { stream: accessLogStream }));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+#### log file rotation
+
+Sample app that will log all requests in the Apache combined format to one log
+file per day in the `log/` directory using the
+[rotating-file-stream module](https://www.npmjs.com/package/rotating-file-stream).
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+var path = require('path');
+var rfs = require('rotating-file-stream'); // version 2.x
+
+var app = express();
+
+// create a rotating write stream
+var accessLogStream = rfs.createStream('access.log', {
+ interval: '1d', // rotate daily
+ path: path.join(__dirname, 'log'),
+});
+
+// setup the logger
+app.use(morgan('combined', { stream: accessLogStream }));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### split / dual logging
+
+The `morgan` middleware can be used as many times as needed, enabling
+combinations like:
+
+- Log entry on request and one on response
+- Log all requests to file, but errors to console
+- ... and more!
+
+Sample app that will log all requests to a file using Apache format, but
+error responses are logged to the console:
+
+```js
+var express = require('express');
+var fs = require('fs');
+var morgan = require('morgan');
+var path = require('path');
+
+var app = express();
+
+// log only 4xx and 5xx responses to console
+app.use(
+ morgan('dev', {
+ skip: function (req, res) {
+ return res.statusCode < 400;
+ },
+ })
+);
+
+// log all requests to access.log
+app.use(
+ morgan('common', {
+ stream: fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' }),
+ })
+);
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### use custom token formats
+
+Sample app that will use custom token formats. This adds an ID to all requests and displays it using the `:id` token.
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+var uuid = require('node-uuid');
+
+morgan.token('id', function getId(req) {
+ return req.id;
+});
+
+var app = express();
+
+app.use(assignId);
+app.use(morgan(':id :method :url :response-time'));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+
+function assignId(req, res, next) {
+ req.id = uuid.v4();
+ next();
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/morgan/master?label=ci
+[ci-url]: https://github.com/expressjs/morgan/actions/workflows/ci.yml
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/morgan/master
+[coveralls-url]: https://coveralls.io/r/expressjs/morgan?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/morgan
+[npm-url]: https://npmjs.org/package/morgan
+[npm-version-image]: https://badgen.net/npm/v/morgan
diff --git a/astro/src/content/resources/de/middleware/multer.md b/astro/src/content/resources/de/middleware/multer.md
new file mode 100644
index 0000000000..326786ab3d
--- /dev/null
+++ b/astro/src/content/resources/de/middleware/multer.md
@@ -0,0 +1,352 @@
+---
+title: Express multer middleware
+module: multer
+---
+
+# Multer [![NPM Version][npm-version-image]][npm-url] [![NPM Downloads][npm-downloads-image]][npm-url] [![Build Status][ci-image]][ci-url] [![Test Coverage][test-image]][test-url] [![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+
+Multer is a node.js middleware for handling `multipart/form-data`, which is primarily used for uploading files. It is written
+on top of [busboy](https://github.com/mscdex/busboy) for maximum efficiency.
+
+**NOTE**: Multer will not process any form which is not multipart (`multipart/form-data`).
+
+## Translations
+
+This README is also available in other languages:
+
+| | |
+| ------------------------------------------------------------------------------ | --------------- |
+| [العربية](https://github.com/expressjs/multer/blob/main/doc/README-ar.md) | Arabic |
+| [简体中文](https://github.com/expressjs/multer/blob/main/doc/README-zh-cn.md) | Chinese |
+| [Français](https://github.com/expressjs/multer/blob/main/doc/README-fr.md) | French |
+| [한국어](https://github.com/expressjs/multer/blob/main/doc/README-ko.md) | Korean |
+| [Português](https://github.com/expressjs/multer/blob/main/doc/README-pt-br.md) | Portuguese (BR) |
+| [Русский язык](https://github.com/expressjs/multer/blob/main/doc/README-ru.md) | Russian |
+| [Español](https://github.com/expressjs/multer/blob/main/doc/README-es.md) | Spanish |
+| [O'zbek tili](https://github.com/expressjs/multer/blob/main/doc/README-uz.md) | Uzbek |
+| [Việt Nam](https://github.com/expressjs/multer/blob/main/doc/README-vi.md) | Vietnamese |
+
+## Installation
+
+```sh
+$ npm install multer
+```
+
+## Usage
+
+Multer adds a `body` object and a `file` or `files` object to the `request` object. The `body` object contains the values of the text fields of the form, the `file` or `files` object contains the files uploaded via the form.
+
+Basic usage example:
+
+Don't forget the `enctype="multipart/form-data"` in your form.
+
+```html
+
+```
+
+```javascript
+const express = require('express');
+const multer = require('multer');
+const upload = multer({ dest: 'uploads/' });
+
+const app = express();
+
+app.post('/profile', upload.single('avatar'), function (req, res, next) {
+ // req.file is the `avatar` file
+ // req.body will hold the text fields, if there were any
+});
+
+app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
+ // req.files is array of `photos` files
+ // req.body will contain the text fields, if there were any
+});
+
+const uploadMiddleware = upload.fields([
+ { name: 'avatar', maxCount: 1 },
+ { name: 'gallery', maxCount: 8 },
+]);
+app.post('/cool-profile', uploadMiddleware, function (req, res, next) {
+ // req.files is an object (String -> Array) where fieldname is the key, and the value is array of files
+ //
+ // e.g.
+ // req.files['avatar'][0] -> File
+ // req.files['gallery'] -> Array
+ //
+ // req.body will contain the text fields, if there were any
+});
+```
+
+In case you need to handle a text-only multipart form, you should use the `.none()` method:
+
+```javascript
+const express = require('express');
+const app = express();
+const multer = require('multer');
+const upload = multer();
+
+app.post('/profile', upload.none(), function (req, res, next) {
+ // req.body contains the text fields
+});
+```
+
+Here's an example on how multer is used in a HTML form. Take special note of the `enctype="multipart/form-data"` and `name="uploaded_file"` fields:
+
+```html
+
+```
+
+Then in your javascript file you would add these lines to access both the file and the body. It is important that you use the `name` field value from the form in your upload function. This tells multer which field on the request it should look for the files in. If these fields aren't the same in the HTML form and on your server, your upload will fail:
+
+```javascript
+const multer = require('multer');
+const upload = multer({ dest: './public/data/uploads/' });
+app.post('/stats', upload.single('uploaded_file'), function (req, res) {
+ // req.file is the name of your file in the form above, here 'uploaded_file'
+ // req.body will hold the text fields, if there were any
+ console.log(req.file, req.body);
+});
+```
+
+## API
+
+### File information
+
+Each file contains the following information:
+
+| Key | Description | Note |
+| -------------- | --------------------------------------------- | --------------- |
+| `fieldname` | Field name specified in the form |
+| `originalname` | Name of the file on the user's computer |
+| `encoding` | Encoding type of the file |
+| `mimetype` | Mime type of the file |
+| `size` | Size of the file in bytes |
+| `destination` | The folder to which the file has been saved | `DiskStorage` |
+| `filename` | The name of the file within the `destination` | `DiskStorage` |
+| `path` | The full path to the uploaded file | `DiskStorage` |
+| `buffer` | A `Buffer` of the entire file | `MemoryStorage` |
+
+### `multer(opts)`
+
+Multer accepts an options object, the most basic of which is the `dest`
+property, which tells Multer where to upload the files. In case you omit the
+options object, the files will be kept in memory and never written to disk.
+
+By default, Multer will rename the files so as to avoid naming conflicts. The
+renaming function can be customized according to your needs.
+
+The following are the options that can be passed to Multer.
+
+| Key | Description |
+| ------------------- | --------------------------------------------------------- |
+| `dest` or `storage` | Where to store the files |
+| `fileFilter` | Function to control which files are accepted |
+| `limits` | Limits of the uploaded data |
+| `preservePath` | Keep the full path of files instead of just the base name |
+
+In an average web app, only `dest` might be required, and configured as shown in
+the following example.
+
+```javascript
+const upload = multer({ dest: 'uploads/' });
+```
+
+If you want more control over your uploads, you'll want to use the `storage`
+option instead of `dest`. Multer ships with storage engines `DiskStorage`
+and `MemoryStorage`; More engines are available from third parties.
+
+#### `.single(fieldname)`
+
+Accept a single file with the name `fieldname`. The single file will be stored
+in `req.file`.
+
+#### `.array(fieldname[, maxCount])`
+
+Accept an array of files, all with the name `fieldname`. Optionally error out if
+more than `maxCount` files are uploaded. The array of files will be stored in
+`req.files`.
+
+#### `.fields(fields)`
+
+Accept a mix of files, specified by `fields`. An object with arrays of files
+will be stored in `req.files`.
+
+`fields` should be an array of objects with `name` and optionally a `maxCount`.
+Example:
+
+```javascript
+[
+ { name: 'avatar', maxCount: 1 },
+ { name: 'gallery', maxCount: 8 },
+];
+```
+
+#### `.none()`
+
+Accept only text fields. If any file upload is made, error with code
+"LIMIT_UNEXPECTED_FILE" will be issued.
+
+#### `.any()`
+
+Accepts all files that comes over the wire. An array of files will be stored in
+`req.files`.
+
+**WARNING:** Make sure that you always handle the files that a user uploads.
+Never add multer as a global middleware since a malicious user could upload
+files to a route that you didn't anticipate. Only use this function on routes
+where you are handling the uploaded files.
+
+### `storage`
+
+#### `DiskStorage`
+
+The disk storage engine gives you full control on storing files to disk.
+
+```javascript
+const storage = multer.diskStorage({
+ destination: function (req, file, cb) {
+ cb(null, '/tmp/my-uploads');
+ },
+ filename: function (req, file, cb) {
+ const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
+ cb(null, file.fieldname + '-' + uniqueSuffix);
+ },
+});
+
+const upload = multer({ storage: storage });
+```
+
+There are two options available, `destination` and `filename`. They are both
+functions that determine where the file should be stored.
+
+`destination` is used to determine within which folder the uploaded files should
+be stored. This can also be given as a `string` (e.g. `'/tmp/uploads'`). If no
+`destination` is given, the operating system's default directory for temporary
+files is used.
+
+**Note:** You are responsible for creating the directory when providing
+`destination` as a function. When passing a string, multer will make sure that
+the directory is created for you.
+
+`filename` is used to determine what the file should be named inside the folder.
+If no `filename` is given, each file will be given a random name that doesn't
+include any file extension.
+
+**Note:** Multer will not append any file extension for you, your function
+should return a filename complete with a file extension.
+
+Each function gets passed both the request (`req`) and some information about
+the file (`file`) to aid with the decision.
+
+Note that `req.body` might not have been fully populated yet. It depends on the
+order that the client transmits fields and files to the server.
+
+For understanding the calling convention used in the callback (needing to pass
+null as the first param), refer to
+[Node.js error handling](https://web.archive.org/web/20220417042018/https://www.joyent.com/node-js/production/design/errors)
+
+#### `MemoryStorage`
+
+The memory storage engine stores the files in memory as `Buffer` objects. It
+doesn't have any options.
+
+```javascript
+const storage = multer.memoryStorage();
+const upload = multer({ storage: storage });
+```
+
+When using memory storage, the file info will contain a field called
+`buffer` that contains the entire file.
+
+**WARNING**: Uploading very large files, or relatively small files in large
+numbers very quickly, can cause your application to run out of memory when
+memory storage is used.
+
+### `limits`
+
+An object specifying the size limits of the following optional properties. Multer passes this object into busboy directly, and the details of the properties can be found on [busboy's page](https://github.com/mscdex/busboy#busboy-methods).
+
+The following integer values are available:
+
+| Key | Description | Default |
+| --------------- | ----------------------------------------------------------------------- | --------- |
+| `fieldNameSize` | Max field name size | 100 bytes |
+| `fieldSize` | Max field value size (in bytes) | 1MB |
+| `fields` | Max number of non-file fields | Infinity |
+| `fileSize` | For multipart forms, the max file size (in bytes) | Infinity |
+| `files` | For multipart forms, the max number of file fields | Infinity |
+| `parts` | For multipart forms, the max number of parts (fields + files) | Infinity |
+| `headerPairs` | For multipart forms, the max number of header key=>value pairs to parse | 2000 |
+
+Specifying the limits can help protect your site against denial of service (DoS) attacks.
+
+### `fileFilter`
+
+Set this to a function to control which files should be uploaded and which
+should be skipped. The function should look like this:
+
+```javascript
+function fileFilter(req, file, cb) {
+ // The function should call `cb` with a boolean
+ // to indicate if the file should be accepted
+
+ // To reject this file pass `false`, like so:
+ cb(null, false);
+
+ // To accept the file pass `true`, like so:
+ cb(null, true);
+
+ // You can always pass an error if something goes wrong:
+ cb(new Error("I don't have a clue!"));
+}
+```
+
+## Error handling
+
+When encountering an error, Multer will delegate the error to Express. You can
+display a nice error page using [the standard express way](http://expressjs.com/guide/error-handling.html).
+
+If you want to catch errors specifically from Multer, you can call the
+middleware function by yourself. Also, if you want to catch only [the Multer errors](https://github.com/expressjs/multer/blob/main/lib/multer-error.js), you can use the `MulterError` class that is attached to the `multer` object itself (e.g. `err instanceof multer.MulterError`).
+
+```javascript
+const multer = require('multer');
+const upload = multer().single('avatar');
+
+app.post('/profile', function (req, res) {
+ upload(req, res, function (err) {
+ if (err instanceof multer.MulterError) {
+ // A Multer error occurred when uploading.
+ } else if (err) {
+ // An unknown error occurred when uploading.
+ }
+
+ // Everything went fine.
+ });
+});
+```
+
+## Custom storage engine
+
+For information on how to build your own storage engine, see [Multer Storage Engine](https://github.com/expressjs/multer/blob/main/StorageEngine.md).
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://github.com/expressjs/multer/actions/workflows/ci.yml/badge.svg
+[ci-url]: https://github.com/expressjs/multer/actions/workflows/ci.yml
+[test-url]: https://coveralls.io/r/expressjs/multer?branch=main
+[test-image]: https://badgen.net/coveralls/c/github/expressjs/multer/main
+[npm-downloads-image]: https://badgen.net/npm/dm/multer
+[npm-url]: https://npmjs.org/package/multer
+[npm-version-image]: https://badgen.net/npm/v/multer
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/multer/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer
diff --git a/astro/src/content/resources/de/middleware/overview.md b/astro/src/content/resources/de/middleware/overview.md
new file mode 100755
index 0000000000..46217759e7
--- /dev/null
+++ b/astro/src/content/resources/de/middleware/overview.md
@@ -0,0 +1,40 @@
+---
+title: Express middleware
+description: Explore a list of Express.js middleware modules maintained by the Express team and the community, including built-in middleware and popular third-party modules.
+module: mw-home
+---
+
+## Express middleware
+
+The Express middleware modules listed here are maintained by the
+[Expressjs team](https://github.com/orgs/expressjs/people).
+
+| Middleware module | Description |
+| ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
+| [body-parser](/en/resources/middleware/body-parser) | Parse HTTP request body. |
+| [compression](/en/resources/middleware/compression) | Compress HTTP responses. |
+| [cookie-parser](/en/resources/middleware/cookie-parser) | Parse cookie header and populate `req.cookies`. See also [cookies](https://github.com/jed/cookies). |
+| [cookie-session](/en/resources/middleware/cookie-session) | Establish cookie-based sessions. |
+| [cors](/en/resources/middleware/cors) | Enable cross-origin resource sharing (CORS) with various options. |
+| [errorhandler](/en/resources/middleware/errorhandler) | Development error-handling/debugging. |
+| [method-override](/en/resources/middleware/method-override) | Override HTTP methods using header. |
+| [morgan](/en/resources/middleware/morgan) | HTTP request logger. |
+| [multer](/en/resources/middleware/multer) | Handle multi-part form data. |
+| [response-time](/en/resources/middleware/response-time) | Record HTTP response time. |
+| [serve-favicon](/en/resources/middleware/serve-favicon) | Serve a favicon. |
+| [serve-index](/en/resources/middleware/serve-index) | Serve directory listing for a given path. |
+| [serve-static](/en/resources/middleware/serve-static) | Serve static files. |
+| [session](/en/resources/middleware/session) | Establish server-based sessions (development only). |
+| [timeout](/en/resources/middleware/timeout) | Set a timeout perioHTTP request processing. |
+| [vhost](/en/resources/middleware/vhost) | Create virtual domains. |
+
+## Additional middleware modules
+
+These are some additional popular middleware modules.
+
+{% include community-caveat.html %}
+
+| Middleware module | Description |
+| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
+| [helmet](https://github.com/helmetjs/helmet) | Helps secure your apps by setting various HTTP headers. |
+| [passport](https://github.com/jaredhanson/passport) | Authentication using "strategies" such as OAuth, OpenID and many others. See [passportjs.org](https://passportjs.org/) for more information. |
diff --git a/astro/src/content/resources/de/middleware/response-time.md b/astro/src/content/resources/de/middleware/response-time.md
new file mode 100644
index 0000000000..f911f480f5
--- /dev/null
+++ b/astro/src/content/resources/de/middleware/response-time.md
@@ -0,0 +1,314 @@
+---
+title: Express response-time middleware
+module: response-time
+---
+
+# compression
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+[![Funding][funding-image]][funding-url]
+
+Node.js compression middleware.
+
+The following compression codings are supported:
+
+- deflate
+- gzip
+- br (brotli)
+
+**Note** Brotli is supported only since Node.js versions v11.7.0 and v10.16.0.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```bash
+$ npm install compression
+```
+
+## API
+
+```js
+var compression = require('compression');
+```
+
+### compression([options])
+
+Returns the compression middleware using the given `options`. The middleware
+will attempt to compress response bodies for all requests that traverse through
+the middleware, based on the given `options`.
+
+This middleware will never compress responses that include a `Cache-Control`
+header with the [`no-transform` directive](https://tools.ietf.org/html/rfc7234#section-5.2.2.4),
+as compressing will transform the body.
+
+#### Options
+
+`compression()` accepts these properties in the options object. In addition to
+those listed below, [zlib](https://nodejs.org/api/zlib.html) options may be
+passed in to the options object or
+[brotli](https://nodejs.org/api/zlib.html#zlib_class_brotlioptions) options.
+
+##### chunkSize
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_CHUNK`, or `16384`.
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### filter
+
+Type: `Function`
+
+A function to decide if the response should be considered for compression.
+This function is called as `filter(req, res)` and is expected to return
+`true` to consider the response for compression, or `false` to not compress
+the response.
+
+The default filter function uses the [compressible](https://www.npmjs.com/package/compressible)
+module to determine if `res.getHeader('Content-Type')` is compressible.
+
+##### level
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_COMPRESSION`, or `-1`
+
+The level of zlib compression to apply to responses. A higher level will result
+in better compression, but will take longer to complete. A lower level will
+result in less compression, but will be much faster.
+
+This is an integer in the range of `0` (no compression) to `9` (maximum
+compression). The special value `-1` can be used to mean the "default
+compression level", which is a default compromise between speed and
+compression (currently equivalent to level 6).
+
+- `-1` Default compression level (also `zlib.constants.Z_DEFAULT_COMPRESSION`).
+- `0` No compression (also `zlib.constants.Z_NO_COMPRESSION`).
+- `1` Fastest compression (also `zlib.constants.Z_BEST_SPEED`).
+- `2`
+- `3`
+- `4`
+- `5`
+- `6` (currently what `zlib.constants.Z_DEFAULT_COMPRESSION` points to).
+- `7`
+- `8`
+- `9` Best compression (also `zlib.constants.Z_BEST_COMPRESSION`).
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### memLevel
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_MEMLEVEL`, or `8`
+
+This specifies how much memory should be allocated for the internal compression
+state and is an integer in the range of `1` (minimum level) and `9` (maximum
+level).
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### brotli
+
+Type: `Object`
+
+This specifies the options for configuring Brotli. See [Node.js documentation](https://nodejs.org/api/zlib.html#class-brotlioptions) for a complete list of available options.
+
+##### strategy
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_STRATEGY`
+
+This is used to tune the compression algorithm. This value only affects the
+compression ratio, not the correctness of the compressed output, even if it
+is not set appropriately.
+
+- `zlib.constants.Z_DEFAULT_STRATEGY` Use for normal data.
+- `zlib.constants.Z_FILTERED` Use for data produced by a filter (or predictor).
+ Filtered data consists mostly of small values with a somewhat random
+ distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect is to force more Huffman coding and less
+ string matching; it is somewhat intermediate between `zlib.constants.Z_DEFAULT_STRATEGY`
+ and `zlib.constants.Z_HUFFMAN_ONLY`.
+- `zlib.constants.Z_FIXED` Use to prevent the use of dynamic Huffman codes, allowing
+ for a simpler decoder for special applications.
+- `zlib.constants.Z_HUFFMAN_ONLY` Use to force Huffman encoding only (no string match).
+- `zlib.constants.Z_RLE` Use to limit match distances to one (run-length encoding).
+ This is designed to be almost as fast as `zlib.constants.Z_HUFFMAN_ONLY`, but give
+ better compression for PNG image data.
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### threshold
+
+Type: `Number` or `String`
+Default: `1kb`
+
+The byte threshold for the response body size before compression is considered
+for the response. This is a number of bytes or any string
+accepted by the [bytes](https://www.npmjs.com/package/bytes) module.
+
+**Note** this is only an advisory setting; if the response size cannot be determined
+at the time the response headers are written, then it is assumed the response is
+_over_ the threshold. To guarantee the response size can be determined, be sure
+set a `Content-Length` response header.
+
+##### windowBits
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_WINDOWBITS`, or `15`
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### enforceEncoding
+
+Type: `String`
+Default: `identity`
+
+This is the default encoding to use when the client does not specify an encoding in the request's [Accept-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) header.
+
+#### .filter
+
+The default `filter` function. This is used to construct a custom filter
+function that is an extension of the default function.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+app.use(compression({ filter: shouldCompress }));
+
+function shouldCompress(req, res) {
+ if (req.headers['x-no-compression']) {
+ // don't compress responses with this request header
+ return false;
+ }
+
+ // fallback to standard filter function
+ return compression.filter(req, res);
+}
+```
+
+### res.flush
+
+This module adds a `res.flush()` method to force the partially-compressed
+response to be flushed to the client.
+
+## Examples
+
+### express
+
+When using this module with express, simply `app.use` the module as
+high as you like. Requests that pass through the middleware will be compressed.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress all responses
+app.use(compression());
+
+// add all routes
+```
+
+### Node.js HTTP server
+
+```js
+var compression = require('compression')({ threshold: 0 });
+var http = require('http');
+
+function createServer(fn) {
+ return http.createServer(function (req, res) {
+ compression(req, res, function (err) {
+ if (err) {
+ res.statusCode = err.status || 500;
+ res.end(err.message);
+ return;
+ }
+
+ fn(req, res);
+ });
+ });
+}
+
+var server = createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello world!');
+});
+
+server.listen(3000, () => {
+ console.log('> Listening at http://localhost:3000');
+});
+```
+
+### Server-Sent Events
+
+Because of the nature of compression this module does not work out of the box
+with server-sent events. To compress content, a window of the output needs to
+be buffered up in order to get good compression. Typically when using server-sent
+events, there are certain block of data that need to reach the client.
+
+You can achieve this by calling `res.flush()` when you need the data written to
+actually make it to the client.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress responses
+app.use(compression());
+
+// server-sent event stream
+app.get('/events', function (req, res) {
+ res.setHeader('Content-Type', 'text/event-stream');
+ res.setHeader('Cache-Control', 'no-cache');
+
+ // send a ping approx every 2 seconds
+ var timer = setInterval(function () {
+ res.write('data: ping\n\n');
+
+ // !!! this is the important part
+ res.flush();
+ }, 2000);
+
+ res.on('close', function () {
+ clearInterval(timer);
+ });
+});
+```
+
+## Contributing
+
+The Express.js project welcomes all constructive contributions. Contributions take many forms,
+from code for bug fixes and enhancements, to additions and fixes to documentation, additional
+tests, triaging incoming pull requests and issues, and more!
+
+See the [Contributing Guide](https://github.com/expressjs/express/blob/master/Contributing.md) for more technical details on contributing.
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://badgen.net/npm/v/compression
+[npm-url]: https://npmjs.org/package/compression
+[downloads-image]: https://badgen.net/npm/dm/compression
+[downloads-url]: https://npmcharts.com/compare/compression?minimal=true
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/compression/master?label=CI
+[github-actions-ci-url]: https://github.com/expressjs/compression/actions?query=workflow%3Aci
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/compression/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/compression
+[funding-url]: https://opencollective.com/express
+[funding-image]: https://badgen.net/badge/icon/sponsor/pink?icon=github&label=Open%20Collective
diff --git a/astro/src/content/resources/de/middleware/serve-favicon.md b/astro/src/content/resources/de/middleware/serve-favicon.md
new file mode 100644
index 0000000000..7a77865c6b
--- /dev/null
+++ b/astro/src/content/resources/de/middleware/serve-favicon.md
@@ -0,0 +1,156 @@
+---
+title: Express serve-favicon middleware
+module: serve-favicon
+---
+
+# serve-index
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Linux Build Status][ci-image]][ci-url]
+[![Windows Build][appveyor-image]][appveyor-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+Serves pages that contain directory listings for a given path.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-index
+```
+
+## API
+
+```js
+var serveIndex = require('serve-index');
+```
+
+### serveIndex(path, options)
+
+Returns middlware that serves an index of the directory in the given `path`.
+
+The `path` is based off the `req.url` value, so a `req.url` of `'/some/dir`
+with a `path` of `'public'` will look at `'public/some/dir'`. If you are using
+something like `express`, you can change the URL "base" with `app.use` (see
+the express example).
+
+#### Options
+
+Serve index accepts these properties in the options object.
+
+##### filter
+
+Apply this filter function to files. Defaults to `false`. The `filter` function
+is called for each file, with the signature `filter(filename, index, files, dir)`
+where `filename` is the name of the file, `index` is the array index, `files` is
+the array of files and `dir` is the absolute path the file is located (and thus,
+the directory the listing is for).
+
+##### hidden
+
+Display hidden (dot) files. Defaults to `false`.
+
+##### icons
+
+Display icons. Defaults to `false`.
+
+##### stylesheet
+
+Optional path to a CSS stylesheet. Defaults to a built-in stylesheet.
+
+##### template
+
+Optional path to an HTML template or a function that will render a HTML
+string. Defaults to a built-in template.
+
+When given a string, the string is used as a file path to load and then the
+following tokens are replaced in templates:
+
+- `{directory}` with the name of the directory.
+- `{files}` with the HTML of an unordered list of file links.
+- `{linked-path}` with the HTML of a link to the directory.
+- `{style}` with the specified stylesheet and embedded images.
+
+When given as a function, the function is called as `template(locals, callback)`
+and it needs to invoke `callback(error, htmlString)`. The following are the
+provided locals:
+
+- `directory` is the directory being displayed (where `/` is the root).
+- `displayIcons` is a Boolean for if icons should be rendered or not.
+- `fileList` is a sorted array of files in the directory. The array contains
+ objects with the following properties:
+ - `name` is the relative name for the file.
+ - `stat` is a `fs.Stats` object for the file.
+- `path` is the full filesystem path to `directory`.
+- `style` is the default stylesheet or the contents of the `stylesheet` option.
+- `viewName` is the view name provided by the `view` option.
+
+##### view
+
+Display mode. `tiles` and `details` are available. Defaults to `tiles`.
+
+## Examples
+
+### Serve directory indexes with vanilla node.js http server
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var serveIndex = require('serve-index');
+var serveStatic = require('serve-static');
+
+// Serve directory indexes for public/ftp folder (with icons)
+var index = serveIndex('public/ftp', { icons: true });
+
+// Serve up public/ftp folder files
+var serve = serveStatic('public/ftp');
+
+// Create server
+var server = http.createServer(function onRequest(req, res) {
+ var done = finalhandler(req, res);
+ serve(req, res, function onNext(err) {
+ if (err) return done(err);
+ index(req, res, done);
+ });
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve directory indexes with express
+
+```js
+var express = require('express');
+var serveIndex = require('serve-index');
+
+var app = express();
+
+// Serve URLs like /ftp/thing as public/ftp/thing
+// The express.static serves the file contents
+// The serveIndex is this module serving the directory
+app.use('/ftp', express.static('public/ftp'), serveIndex('public/ftp', { icons: true }));
+
+// Listen
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE). The [Silk](http://www.famfamfam.com/lab/icons/silk/) icons
+are created by/copyright of [FAMFAMFAM](http://www.famfamfam.com/).
+
+[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/serve-index/master.svg?label=windows
+[appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index
+[ci-image]: https://badgen.net/github/checks/expressjs/serve-index/master?label=ci
+[ci-url]: https://github.com/expressjs/serve-index/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/serve-index/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-index?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/serve-index.svg
+[downloads-url]: https://npmjs.org/package/serve-index
+[npm-image]: https://img.shields.io/npm/v/serve-index.svg
+[npm-url]: https://npmjs.org/package/serve-index
diff --git a/astro/src/content/resources/de/middleware/serve-index.md b/astro/src/content/resources/de/middleware/serve-index.md
new file mode 100644
index 0000000000..da03cf94b2
--- /dev/null
+++ b/astro/src/content/resources/de/middleware/serve-index.md
@@ -0,0 +1,156 @@
+---
+title: Express serve-index middleware
+module: serve-index
+---
+
+# serve-index
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Linux Build Status][ci-image]][ci-url]
+[![Windows Build][appveyor-image]][appveyor-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+Serves pages that contain directory listings for a given path.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-index
+```
+
+## API
+
+```js
+var serveIndex = require('serve-index');
+```
+
+### serveIndex(path, options)
+
+Returns middlware that serves an index of the directory in the given `path`.
+
+The `path` is based off the `req.url` value, so a `req.url` of `'/some/dir`
+with a `path` of `'public'` will look at `'public/some/dir'`. If you are using
+something like `express`, you can change the URL "base" with `app.use` (see
+the express example).
+
+#### Options
+
+Serve index accepts these properties in the options object.
+
+##### filter
+
+Apply this filter function to files. Defaults to `false`. The `filter` function
+is called for each file, with the signature `filter(filename, index, files, dir)`
+where `filename` is the name of the file, `index` is the array index, `files` is
+the array of files and `dir` is the absolute path the file is located (and thus,
+the directory the listing is for).
+
+##### hidden
+
+Display hidden (dot) files. Defaults to `false`.
+
+##### icons
+
+Display icons. Defaults to `false`.
+
+##### stylesheet
+
+Optional path to a CSS stylesheet. Defaults to a built-in stylesheet.
+
+##### template
+
+Optional path to an HTML template or a function that will render a HTML
+string. Defaults to a built-in template.
+
+When given a string, the string is used as a file path to load and then the
+following tokens are replaced in templates:
+
+- `{directory}` with the name of the directory.
+- `{files}` with the HTML of an unordered list of file links.
+- `{linked-path}` with the HTML of a link to the directory.
+- `{style}` with the specified stylesheet and embedded images.
+
+When given as a function, the function is called as `template(locals, callback)`
+and it needs to invoke `callback(error, htmlString)`. The following are the
+provided locals:
+
+- `directory` is the directory being displayed (where `/` is the root).
+- `displayIcons` is a Boolean for if icons should be rendered or not.
+- `fileList` is a sorted array of files in the directory. The array contains
+ objects with the following properties:
+ - `name` is the relative name for the file.
+ - `stat` is a `fs.Stats` object for the file.
+- `path` is the full filesystem path to `directory`.
+- `style` is the default stylesheet or the contents of the `stylesheet` option.
+- `viewName` is the view name provided by the `view` option.
+
+##### view
+
+Display mode. `tiles` and `details` are available. Defaults to `tiles`.
+
+## Examples
+
+### Serve directory indexes with vanilla node.js http server
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var serveIndex = require('serve-index');
+var serveStatic = require('serve-static');
+
+// Serve directory indexes for public/ftp folder (with icons)
+var index = serveIndex('public/ftp', { icons: true });
+
+// Serve up public/ftp folder files
+var serve = serveStatic('public/ftp');
+
+// Create server
+var server = http.createServer(function onRequest(req, res) {
+ var done = finalhandler(req, res);
+ serve(req, res, function onNext(err) {
+ if (err) return done(err);
+ index(req, res, done);
+ });
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve directory indexes with express
+
+```js
+var express = require('express');
+var serveIndex = require('serve-index');
+
+var app = express();
+
+// Serve URLs like /ftp/thing as public/ftp/thing
+// The express.static serves the file contents
+// The serveIndex is this module serving the directory
+app.use('/ftp', express.static('public/ftp'), serveIndex('public/ftp', { icons: true }));
+
+// Listen
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE). The [Silk](http://www.famfamfam.com/lab/icons/silk/) icons
+are created by/copyright of [FAMFAMFAM](http://www.famfamfam.com/).
+
+[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/serve-index/master.svg?label=windows
+[appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index
+[ci-image]: https://badgen.net/github/checks/expressjs/serve-index/master?label=ci
+[ci-url]: https://github.com/expressjs/serve-index/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/serve-index/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-index?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/serve-index.svg
+[downloads-url]: https://npmjs.org/package/serve-index
+[npm-image]: https://img.shields.io/npm/v/serve-index.svg
+[npm-url]: https://npmjs.org/package/serve-index
diff --git a/astro/src/content/resources/de/middleware/serve-static.md b/astro/src/content/resources/de/middleware/serve-static.md
new file mode 100644
index 0000000000..b048165d7b
--- /dev/null
+++ b/astro/src/content/resources/de/middleware/serve-static.md
@@ -0,0 +1,260 @@
+---
+title: Express serve-static middleware
+module: serve-static
+---
+
+# serve-static
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![CI][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-static
+```
+
+## API
+
+```js
+const serveStatic = require('serve-static');
+```
+
+### serveStatic(root, options)
+
+Create a new middleware function to serve files from within a given root
+directory. The file to serve will be determined by combining `req.url`
+with the provided root directory. When a file is not found, instead of
+sending a 404 response, this module will instead call `next()` to move on
+to the next middleware, allowing for stacking and fall-backs.
+
+#### Options
+
+##### acceptRanges
+
+Enable or disable accepting ranged requests, defaults to true.
+Disabling this will not send `Accept-Ranges` and ignore the contents
+of the `Range` request header.
+
+##### cacheControl
+
+Enable or disable setting `Cache-Control` response header, defaults to
+true. Disabling this will ignore the `immutable` and `maxAge` options.
+
+##### dotfiles
+
+Set how "dotfiles" are treated when encountered. A dotfile is a file
+or directory that begins with a dot ("."). Note this check is done on
+the path itself without checking if the path actually exists on the
+disk. If `root` is specified, only the dotfiles above the root are
+checked (i.e. the root itself can be within a dotfile when set
+to "deny").
+
+- `'allow'` No special treatment for dotfiles.
+- `'deny'` Deny a request for a dotfile and 403/`next()`.
+- `'ignore'` Pretend like the dotfile does not exist and 404/`next()`.
+
+The default value is `'ignore'`.
+
+##### etag
+
+Enable or disable etag generation, defaults to true.
+
+##### extensions
+
+Set file extension fallbacks. When set, if a file is not found, the given
+extensions will be added to the file name and search for. The first that
+exists will be served. Example: `['html', 'htm']`.
+
+The default value is `false`.
+
+##### fallthrough
+
+Set the middleware to have client errors fall-through as just unhandled
+requests, otherwise forward a client error. The difference is that client
+errors like a bad request or a request to a non-existent file will cause
+this middleware to simply `next()` to your next middleware when this value
+is `true`. When this value is `false`, these errors (even 404s), will invoke
+`next(err)`.
+
+Typically `true` is desired such that multiple physical directories can be
+mapped to the same web address or for routes to fill in non-existent files.
+
+The value `false` can be used if this middleware is mounted at a path that
+is designed to be strictly a single file system directory, which allows for
+short-circuiting 404s for less overhead. This middleware will also reply to
+all methods.
+
+The default value is `true`.
+
+##### immutable
+
+Enable or disable the `immutable` directive in the `Cache-Control` response
+header, defaults to `false`. If set to `true`, the `maxAge` option should
+also be specified to enable caching. The `immutable` directive will prevent
+supported clients from making conditional requests during the life of the
+`maxAge` option to check if the file has changed.
+
+##### index
+
+By default this module will send "index.html" files in response to a request
+on a directory. To disable this set `false` or to supply a new index pass a
+string or an array in preferred order.
+
+##### lastModified
+
+Enable or disable `Last-Modified` header, defaults to true. Uses the file
+system's last modified value.
+
+##### maxAge
+
+Provide a max-age in milliseconds for http caching, defaults to 0. This
+can also be a string accepted by the [ms](https://www.npmjs.org/package/ms#readme)
+module.
+
+##### redirect
+
+Redirect to trailing "/" when the pathname is a dir. Defaults to `true`.
+
+##### setHeaders
+
+Function to set custom headers on response. Alterations to the headers need to
+occur synchronously. The function is called as `fn(res, path, stat)`, where
+the arguments are:
+
+- `res` the response object
+- `path` the file path that is being sent
+- `stat` the stat object of the file that is being sent
+
+## Examples
+
+### Serve files with vanilla node.js http server
+
+```js
+const finalhandler = require('finalhandler');
+const http = require('http');
+const serveStatic = require('serve-static');
+
+// Serve up public/ftp folder
+const serve = serveStatic('public/ftp', { index: ['index.html', 'index.htm'] });
+
+// Create server
+const server = http.createServer((req, res) => {
+ serve(req, res, finalhandler(req, res));
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve all files as downloads
+
+```js
+const contentDisposition = require('content-disposition');
+const finalhandler = require('finalhandler');
+const http = require('http');
+const serveStatic = require('serve-static');
+
+// Serve up public/ftp folder
+const serve = serveStatic('public/ftp', {
+ index: false,
+ setHeaders: setHeaders,
+});
+
+// Set header to force download
+function setHeaders(res, path) {
+ res.setHeader('Content-Disposition', contentDisposition(path));
+}
+
+// Create server
+const server = http.createServer((req, res) => {
+ serve(req, res, finalhandler(req, res));
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serving using express
+
+#### Simple
+
+This is a simple example of using Express.
+
+```js
+const express = require('express');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(serveStatic('public/ftp', { index: ['default.html', 'default.htm'] }));
+app.listen(3000);
+```
+
+#### Multiple roots
+
+This example shows a simple way to search through multiple directories.
+Files are searched for in `public-optimized/` first, then `public/` second
+as a fallback.
+
+```js
+const express = require('express');
+const path = require('path');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(serveStatic(path.join(__dirname, 'public-optimized')));
+app.use(serveStatic(path.join(__dirname, 'public')));
+app.listen(3000);
+```
+
+#### Different settings for paths
+
+This example shows how to set a different max age depending on the served
+file. In this example, HTML files are not cached, while everything else
+is for 1 day.
+
+```js
+const express = require('express');
+const path = require('path');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(
+ serveStatic(path.join(__dirname, 'public'), {
+ maxAge: '1d',
+ setHeaders: setCustomCacheControl,
+ })
+);
+
+app.listen(3000);
+
+function setCustomCacheControl(res, file) {
+ if (path.extname(file) === '.html') {
+ // Custom Cache-Control for HTML files
+ res.setHeader('Cache-Control', 'public, max-age=0');
+ }
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/serve-static/master
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-static?branch=master
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/serve-static/master?label=linux
+[github-actions-ci-url]: https://github.com/expressjs/serve-static/actions/workflows/ci.yml
+[node-image]: https://badgen.net/npm/node/serve-static
+[node-url]: https://nodejs.org/en/download/
+[npm-downloads-image]: https://badgen.net/npm/dm/serve-static
+[npm-url]: https://npmjs.org/package/serve-static
+[npm-version-image]: https://badgen.net/npm/v/serve-static
diff --git a/astro/src/content/resources/de/middleware/session.md b/astro/src/content/resources/de/middleware/session.md
new file mode 100644
index 0000000000..90f3837a42
--- /dev/null
+++ b/astro/src/content/resources/de/middleware/session.md
@@ -0,0 +1,1046 @@
+---
+title: Express session middleware
+module: session
+---
+
+# express-session
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][node-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install express-session
+```
+
+## API
+
+```js
+var session = require('express-session');
+```
+
+### session(options)
+
+Create a session middleware with the given `options`.
+
+**Note** Session data is _not_ saved in the cookie itself, just the session ID.
+Session data is stored server-side.
+
+**Note** Since version 1.5.0, the [`cookie-parser` middleware](https://www.npmjs.com/package/cookie-parser)
+no longer needs to be used for this module to work. This module now directly reads
+and writes cookies on `req`/`res`. Using `cookie-parser` may result in issues
+if the `secret` is not the same between this module and `cookie-parser`.
+
+**Warning** The default server-side session storage, `MemoryStore`, is _purposely_
+not designed for a production environment. It will leak memory under most
+conditions, does not scale past a single process, and is meant for debugging and
+developing.
+
+For a list of stores, see [compatible session stores](#compatible-session-stores).
+
+#### Options
+
+`express-session` accepts these properties in the options object.
+
+##### cookie
+
+Settings object for the session ID cookie. The default value is
+`{ path: '/', httpOnly: true, secure: false, maxAge: null }`.
+
+The following are options that can be set in this object.
+
+##### cookie.domain
+
+Specifies the value for the `Domain` `Set-Cookie` attribute. By default, no domain
+is set, and most clients will consider the cookie to apply to only the current
+domain.
+
+##### cookie.expires
+
+Specifies the `Date` object to be the value for the `Expires` `Set-Cookie` attribute.
+By default, no expiration is set, and most clients will consider this a
+"non-persistent cookie" and will delete it on a condition like exiting a web browser
+application.
+
+**Note** If both `expires` and `maxAge` are set in the options, then the last one
+defined in the object is what is used.
+
+**Note** The `expires` option should not be set directly; instead only use the `maxAge`
+option.
+
+##### cookie.httpOnly
+
+Specifies the `boolean` value for the `HttpOnly` `Set-Cookie` attribute. When truthy,
+the `HttpOnly` attribute is set, otherwise it is not. By default, the `HttpOnly`
+attribute is set.
+
+**Note** be careful when setting this to `true`, as compliant clients will not allow
+client-side JavaScript to see the cookie in `document.cookie`.
+
+##### cookie.maxAge
+
+Specifies the `number` (in milliseconds) to use when calculating the `Expires`
+`Set-Cookie` attribute. This is done by taking the current server time and adding
+`maxAge` milliseconds to the value to calculate an `Expires` datetime. By default,
+no maximum age is set.
+
+**Note** If both `expires` and `maxAge` are set in the options, then the last one
+defined in the object is what is used.
+
+##### cookie.partitioned
+
+Specifies the `boolean` value for the [`Partitioned` `Set-Cookie`](rfc-cutler-httpbis-partitioned-cookies)
+attribute. When truthy, the `Partitioned` attribute is set, otherwise it is not.
+By default, the `Partitioned` attribute is not set.
+
+**Note** This is an attribute that has not yet been fully standardized, and may
+change in the future. This also means many clients may ignore this attribute until
+they understand it.
+
+More information about can be found in [the proposal](https://github.com/privacycg/CHIPS).
+
+##### cookie.path
+
+Specifies the value for the `Path` `Set-Cookie`. By default, this is set to `'/'`, which
+is the root path of the domain.
+
+##### cookie.priority
+
+Specifies the `string` to be the value for the [`Priority` `Set-Cookie` attribute][rfc-west-cookie-priority-00-4.1].
+
+- `'low'` will set the `Priority` attribute to `Low`.
+- `'medium'` will set the `Priority` attribute to `Medium`, the default priority when not set.
+- `'high'` will set the `Priority` attribute to `High`.
+
+More information about the different priority levels can be found in
+[the specification][rfc-west-cookie-priority-00-4.1].
+
+**Note** This is an attribute that has not yet been fully standardized, and may change in the future.
+This also means many clients may ignore this attribute until they understand it.
+
+##### cookie.sameSite
+
+Specifies the `boolean` or `string` to be the value for the `SameSite` `Set-Cookie` attribute.
+By default, this is `false`.
+
+- `true` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
+- `false` will not set the `SameSite` attribute.
+- `'lax'` will set the `SameSite` attribute to `Lax` for lax same site enforcement.
+- `'none'` will set the `SameSite` attribute to `None` for an explicit cross-site cookie.
+- `'strict'` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
+
+More information about the different enforcement levels can be found in
+[the specification][rfc-6265bis-03-4.1.2.7].
+
+**Note** This is an attribute that has not yet been fully standardized, and may change in
+the future. This also means many clients may ignore this attribute until they understand it.
+
+**Note** There is a [draft spec](https://tools.ietf.org/html/draft-west-cookie-incrementalism-01)
+that requires that the `Secure` attribute be set to `true` when the `SameSite` attribute has been
+set to `'none'`. Some web browsers or other clients may be adopting this specification.
+
+##### cookie.secure
+
+Specifies the `boolean` value for the `Secure` `Set-Cookie` attribute. When truthy,
+the `Secure` attribute is set, otherwise it is not. By default, the `Secure`
+attribute is not set.
+
+**Note** be careful when setting this to `true`, as compliant clients will not send
+the cookie back to the server in the future if the browser does not have an HTTPS
+connection.
+
+Please note that `secure: true` is a **recommended** option. However, it requires
+an https-enabled website, i.e., HTTPS is necessary for secure cookies. If `secure`
+is set, and you access your site over HTTP, the cookie will not be set. If you
+have your node.js behind a proxy and are using `secure: true`, you need to set
+"trust proxy" in express:
+
+```js
+var app = express();
+app.set('trust proxy', 1); // trust first proxy
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ cookie: { secure: true },
+ })
+);
+```
+
+For using secure cookies in production, but allowing for testing in development,
+the following is an example of enabling this setup based on `NODE_ENV` in express:
+
+```js
+var app = express();
+var sess = {
+ secret: 'keyboard cat',
+ cookie: {},
+};
+
+if (app.get('env') === 'production') {
+ app.set('trust proxy', 1); // trust first proxy
+ sess.cookie.secure = true; // serve secure cookies
+}
+
+app.use(session(sess));
+```
+
+The `cookie.secure` option can also be set to the special value `'auto'` to have
+this setting automatically match the determined security of the connection. Be
+careful when using this setting if the site is available both as HTTP and HTTPS,
+as once the cookie is set on HTTPS, it will no longer be visible over HTTP. This
+is useful when the Express `"trust proxy"` setting is properly setup to simplify
+development vs production configuration.
+
+##### genid
+
+Function to call to generate a new session ID. Provide a function that returns
+a string that will be used as a session ID. The function is given `req` as the
+first argument if you want to use some value attached to `req` when generating
+the ID.
+
+The default value is a function which uses the `uid-safe` library to generate IDs.
+
+**NOTE** be careful to generate unique IDs so your sessions do not conflict.
+
+```js
+app.use(
+ session({
+ genid: function (req) {
+ return genuuid(); // use UUIDs for session IDs
+ },
+ secret: 'keyboard cat',
+ })
+);
+```
+
+##### name
+
+The name of the session ID cookie to set in the response (and read from in the
+request).
+
+The default value is `'connect.sid'`.
+
+**Note** if you have multiple apps running on the same hostname (this is just
+the name, i.e. `localhost` or `127.0.0.1`; different schemes and ports do not
+name a different hostname), then you need to separate the session cookies from
+each other. The simplest method is to simply set different `name`s per app.
+
+##### proxy
+
+Trust the reverse proxy when setting secure cookies (via the "X-Forwarded-Proto"
+header).
+
+The default value is `undefined`.
+
+- `true` The "X-Forwarded-Proto" header will be used.
+- `false` All headers are ignored and the connection is considered secure only
+ if there is a direct TLS/SSL connection.
+- `undefined` Uses the "trust proxy" setting from express
+
+##### resave
+
+Forces the session to be saved back to the session store, even if the session
+was never modified during the request. Depending on your store this may be
+necessary, but it can also create race conditions where a client makes two
+parallel requests to your server and changes made to the session in one
+request may get overwritten when the other request ends, even if it made no
+changes (this behavior also depends on what store you're using).
+
+The default value is `true`, but using the default has been deprecated,
+as the default will change in the future. Please research into this setting
+and choose what is appropriate to your use-case. Typically, you'll want
+`false`.
+
+How do I know if this is necessary for my store? The best way to know is to
+check with your store if it implements the `touch` method. If it does, then
+you can safely set `resave: false`. If it does not implement the `touch`
+method and your store sets an expiration date on stored sessions, then you
+likely need `resave: true`.
+
+##### rolling
+
+Force the session identifier cookie to be set on every response. The expiration
+is reset to the original [`maxAge`](#cookiemaxage), resetting the expiration
+countdown.
+
+The default value is `false`.
+
+With this enabled, the session identifier cookie will expire in
+[`maxAge`](#cookiemaxage) since the last response was sent instead of in
+[`maxAge`](#cookiemaxage) since the session was last modified by the server.
+
+This is typically used in conjunction with short, non-session-length
+[`maxAge`](#cookiemaxage) values to provide a quick timeout of the session data
+with reduced potential of it occurring during on going server interactions.
+
+**Note** When this option is set to `true` but the `saveUninitialized` option is
+set to `false`, the cookie will not be set on a response with an uninitialized
+session. This option only modifies the behavior when an existing session was
+loaded for the request.
+
+##### saveUninitialized
+
+Forces a session that is "uninitialized" to be saved to the store. A session is
+uninitialized when it is new but not modified. Choosing `false` is useful for
+implementing login sessions, reducing server storage usage, or complying with
+laws that require permission before setting a cookie. Choosing `false` will also
+help with race conditions where a client makes multiple parallel requests
+without a session.
+
+The default value is `true`, but using the default has been deprecated, as the
+default will change in the future. Please research into this setting and
+choose what is appropriate to your use-case.
+
+**Note** if you are using Session in conjunction with PassportJS, Passport
+will add an empty Passport object to the session for use after a user is
+authenticated, which will be treated as a modification to the session, causing
+it to be saved. _This has been fixed in PassportJS 0.3.0_
+
+##### secret
+
+**Required option**
+
+This is the secret used to sign the session ID cookie. The secret can be any type
+of value that is supported by Node.js `crypto.createHmac` (like a string or a
+`Buffer`). This can be either a single secret, or an array of multiple secrets. If
+an array of secrets is provided, only the first element will be used to sign the
+session ID cookie, while all the elements will be considered when verifying the
+signature in requests. The secret itself should be not easily parsed by a human and
+would best be a random set of characters. A best practice may include:
+
+- The use of environment variables to store the secret, ensuring the secret itself
+ does not exist in your repository.
+- Periodic updates of the secret, while ensuring the previous secret is in the
+ array.
+
+Using a secret that cannot be guessed will reduce the ability to hijack a session to
+only guessing the session ID (as determined by the `genid` option).
+
+Changing the secret value will invalidate all existing sessions. In order to rotate
+the secret without invalidating sessions, provide an array of secrets, with the new
+secret as first element of the array, and including previous secrets as the later
+elements.
+
+**Note** HMAC-256 is used to sign the session ID. For this reason, the secret should
+contain at least 32 bytes of entropy.
+
+##### store
+
+The session store instance, defaults to a new `MemoryStore` instance.
+
+##### unset
+
+Control the result of unsetting `req.session` (through `delete`, setting to `null`,
+etc.).
+
+The default value is `'keep'`.
+
+- `'destroy'` The session will be destroyed (deleted) when the response ends.
+- `'keep'` The session in the store will be kept, but modifications made during
+ the request are ignored and not saved.
+
+### req.session
+
+To store or access session data, simply use the request property `req.session`,
+which is (generally) serialized as JSON by the store, so nested objects
+are typically fine. For example below is a user-specific view counter:
+
+```js
+// Use the session middleware
+app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 } }));
+
+// Access the session as req.session
+app.get('/', function (req, res, next) {
+ if (req.session.views) {
+ req.session.views++;
+ res.setHeader('Content-Type', 'text/html');
+ res.write('views: ' + req.session.views + '
');
+ res.write('expires in: ' + req.session.cookie.maxAge / 1000 + 's
');
+ res.end();
+ } else {
+ req.session.views = 1;
+ res.end('welcome to the session demo. refresh!');
+ }
+});
+```
+
+#### Session.regenerate(callback)
+
+To regenerate the session simply invoke the method. Once complete,
+a new SID and `Session` instance will be initialized at `req.session`
+and the `callback` will be invoked.
+
+```js
+req.session.regenerate(function (err) {
+ // will have a new session here
+});
+```
+
+#### Session.destroy(callback)
+
+Destroys the session and will unset the `req.session` property.
+Once complete, the `callback` will be invoked.
+
+```js
+req.session.destroy(function (err) {
+ // cannot access session here
+});
+```
+
+#### Session.reload(callback)
+
+Reloads the session data from the store and re-populates the
+`req.session` object. Once complete, the `callback` will be invoked.
+
+```js
+req.session.reload(function (err) {
+ // session updated
+});
+```
+
+#### Session.save(callback)
+
+Save the session back to the store, replacing the contents on the store with the
+contents in memory (though a store may do something else--consult the store's
+documentation for exact behavior).
+
+This method is automatically called at the end of the HTTP response if the
+session data has been altered (though this behavior can be altered with various
+options in the middleware constructor). Because of this, typically this method
+does not need to be called.
+
+There are some cases where it is useful to call this method, for example,
+redirects, long-lived requests or in WebSockets.
+
+```js
+req.session.save(function (err) {
+ // session saved
+});
+```
+
+#### Session.touch()
+
+Updates the `.maxAge` property. Typically this is
+not necessary to call, as the session middleware does this for you.
+
+### req.session.id
+
+Each session has a unique ID associated with it. This property is an
+alias of [`req.sessionID`](#reqsessionid-1) and cannot be modified.
+It has been added to make the session ID accessible from the `session`
+object.
+
+### req.session.cookie
+
+Each session has a unique cookie object accompany it. This allows
+you to alter the session cookie per visitor. For example we can
+set `req.session.cookie.expires` to `false` to enable the cookie
+to remain for only the duration of the user-agent.
+
+#### Cookie.maxAge
+
+Alternatively `req.session.cookie.maxAge` will return the time
+remaining in milliseconds, which we may also re-assign a new value
+to adjust the `.expires` property appropriately. The following
+are essentially equivalent
+
+```js
+var hour = 3600000;
+req.session.cookie.expires = new Date(Date.now() + hour);
+req.session.cookie.maxAge = hour;
+```
+
+For example when `maxAge` is set to `60000` (one minute), and 30 seconds
+has elapsed it will return `30000` until the current request has completed,
+at which time `req.session.touch()` is called to reset
+`req.session.cookie.maxAge` to its original value.
+
+```js
+req.session.cookie.maxAge; // => 30000
+```
+
+#### Cookie.originalMaxAge
+
+The `req.session.cookie.originalMaxAge` property returns the original
+`maxAge` (time-to-live), in milliseconds, of the session cookie.
+
+### req.sessionID
+
+To get the ID of the loaded session, access the request property
+`req.sessionID`. This is simply a read-only value set when a session
+is loaded/created.
+
+## Session Store Implementation
+
+Every session store _must_ be an `EventEmitter` and implement specific
+methods. The following methods are the list of **required**, **recommended**,
+and **optional**.
+
+- Required methods are ones that this module will always call on the store.
+- Recommended methods are ones that this module will call on the store if
+ available.
+- Optional methods are ones this module does not call at all, but helps
+ present uniform stores to users.
+
+For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo.
+
+### store.all(callback)
+
+**Optional**
+
+This optional method is used to get all sessions in the store as an array. The
+`callback` should be called as `callback(error, sessions)`.
+
+### store.destroy(sid, callback)
+
+**Required**
+
+This required method is used to destroy/delete a session from the store given
+a session ID (`sid`). The `callback` should be called as `callback(error)` once
+the session is destroyed.
+
+### store.clear(callback)
+
+**Optional**
+
+This optional method is used to delete all sessions from the store. The
+`callback` should be called as `callback(error)` once the store is cleared.
+
+### store.length(callback)
+
+**Optional**
+
+This optional method is used to get the count of all sessions in the store.
+The `callback` should be called as `callback(error, len)`.
+
+### store.get(sid, callback)
+
+**Required**
+
+This required method is used to get a session from the store given a session
+ID (`sid`). The `callback` should be called as `callback(error, session)`.
+
+The `session` argument should be a session if found, otherwise `null` or
+`undefined` if the session was not found (and there was no error). A special
+case is made when `error.code === 'ENOENT'` to act like `callback(null, null)`.
+
+### store.set(sid, session, callback)
+
+**Required**
+
+This required method is used to upsert a session into the store given a
+session ID (`sid`) and session (`session`) object. The callback should be
+called as `callback(error)` once the session has been set in the store.
+
+### store.touch(sid, session, callback)
+
+**Recommended**
+
+This recommended method is used to "touch" a given session given a
+session ID (`sid`) and session (`session`) object. The `callback` should be
+called as `callback(error)` once the session has been touched.
+
+This is primarily used when the store will automatically delete idle sessions
+and this method is used to signal to the store the given session is active,
+potentially resetting the idle timer.
+
+## Compatible Session Stores
+
+The following modules implement a session store that is compatible with this
+module. Please make a PR to add additional modules :)
+
+[![★][aerospike-session-store-image] aerospike-session-store][aerospike-session-store-url] A session store using [Aerospike](http://www.aerospike.com/).
+
+[aerospike-session-store-url]: https://www.npmjs.com/package/aerospike-session-store
+[aerospike-session-store-image]: https://badgen.net/github/stars/aerospike/aerospike-session-store-expressjs?label=%E2%98%85
+
+[![★][better-sqlite3-session-store-image] better-sqlite3-session-store][better-sqlite3-session-store-url] A session store based on [better-sqlite3](https://github.com/JoshuaWise/better-sqlite3).
+
+[better-sqlite3-session-store-url]: https://www.npmjs.com/package/better-sqlite3-session-store
+[better-sqlite3-session-store-image]: https://badgen.net/github/stars/timdaub/better-sqlite3-session-store?label=%E2%98%85
+
+[![★][cassandra-store-image] cassandra-store][cassandra-store-url] An Apache Cassandra-based session store.
+
+[cassandra-store-url]: https://www.npmjs.com/package/cassandra-store
+[cassandra-store-image]: https://badgen.net/github/stars/webcc/cassandra-store?label=%E2%98%85
+
+[![★][cluster-store-image] cluster-store][cluster-store-url] A wrapper for using in-process / embedded
+stores - such as SQLite (via knex), leveldb, files, or memory - with node cluster (desirable for Raspberry Pi 2
+and other multi-core embedded devices).
+
+[cluster-store-url]: https://www.npmjs.com/package/cluster-store
+[cluster-store-image]: https://badgen.net/github/stars/coolaj86/cluster-store?label=%E2%98%85
+
+[![★][connect-arango-image] connect-arango][connect-arango-url] An ArangoDB-based session store.
+
+[connect-arango-url]: https://www.npmjs.com/package/connect-arango
+[connect-arango-image]: https://badgen.net/github/stars/AlexanderArvidsson/connect-arango?label=%E2%98%85
+
+[![★][connect-azuretables-image] connect-azuretables][connect-azuretables-url] An [Azure Table Storage](https://azure.microsoft.com/en-gb/services/storage/tables/)-based session store.
+
+[connect-azuretables-url]: https://www.npmjs.com/package/connect-azuretables
+[connect-azuretables-image]: https://badgen.net/github/stars/mike-goodwin/connect-azuretables?label=%E2%98%85
+
+[![★][connect-cloudant-store-image] connect-cloudant-store][connect-cloudant-store-url] An [IBM Cloudant](https://cloudant.com/)-based session store.
+
+[connect-cloudant-store-url]: https://www.npmjs.com/package/connect-cloudant-store
+[connect-cloudant-store-image]: https://badgen.net/github/stars/adriantanasa/connect-cloudant-store?label=%E2%98%85
+
+[![★][connect-cosmosdb-image] connect-cosmosdb][connect-cosmosdb-url] An Azure [Cosmos DB](https://azure.microsoft.com/en-us/products/cosmos-db/)-based session store.
+
+[connect-cosmosdb-url]: https://www.npmjs.com/package/connect-cosmosdb
+[connect-cosmosdb-image]: https://badgen.net/github/stars/thekillingspree/connect-cosmosdb?label=%E2%98%85
+
+[![★][connect-couchbase-image] connect-couchbase][connect-couchbase-url] A [couchbase](http://www.couchbase.com/)-based session store.
+
+[connect-couchbase-url]: https://www.npmjs.com/package/connect-couchbase
+[connect-couchbase-image]: https://badgen.net/github/stars/christophermina/connect-couchbase?label=%E2%98%85
+
+[![★][connect-datacache-image] connect-datacache][connect-datacache-url] An [IBM Bluemix Data Cache](http://www.ibm.com/cloud-computing/bluemix/)-based session store.
+
+[connect-datacache-url]: https://www.npmjs.com/package/connect-datacache
+[connect-datacache-image]: https://badgen.net/github/stars/adriantanasa/connect-datacache?label=%E2%98%85
+
+[![★][@google-cloud/connect-datastore-image] @google-cloud/connect-datastore][@google-cloud/connect-datastore-url] A [Google Cloud Datastore](https://cloud.google.com/datastore/docs/concepts/overview)-based session store.
+
+[@google-cloud/connect-datastore-url]: https://www.npmjs.com/package/@google-cloud/connect-datastore
+[@google-cloud/connect-datastore-image]: https://badgen.net/github/stars/GoogleCloudPlatform/cloud-datastore-session-node?label=%E2%98%85
+
+[![★][connect-db2-image] connect-db2][connect-db2-url] An IBM DB2-based session store built using [ibm_db](https://www.npmjs.com/package/ibm_db) module.
+
+[connect-db2-url]: https://www.npmjs.com/package/connect-db2
+[connect-db2-image]: https://badgen.net/github/stars/wallali/connect-db2?label=%E2%98%85
+
+[![★][connect-dynamodb-image] connect-dynamodb][connect-dynamodb-url] A DynamoDB-based session store.
+
+[connect-dynamodb-url]: https://www.npmjs.com/package/connect-dynamodb
+[connect-dynamodb-image]: https://badgen.net/github/stars/ca98am79/connect-dynamodb?label=%E2%98%85
+
+[![★][@google-cloud/connect-firestore-image] @google-cloud/connect-firestore][@google-cloud/connect-firestore-url] A [Google Cloud Firestore](https://cloud.google.com/firestore/docs/overview)-based session store.
+
+[@google-cloud/connect-firestore-url]: https://www.npmjs.com/package/@google-cloud/connect-firestore
+[@google-cloud/connect-firestore-image]: https://badgen.net/github/stars/googleapis/nodejs-firestore-session?label=%E2%98%85
+
+[![★][connect-hazelcast-image] connect-hazelcast][connect-hazelcast-url] Hazelcast session store for Connect and Express.
+
+[connect-hazelcast-url]: https://www.npmjs.com/package/connect-hazelcast
+[connect-hazelcast-image]: https://badgen.net/github/stars/huseyinbabal/connect-hazelcast?label=%E2%98%85
+
+[![★][connect-loki-image] connect-loki][connect-loki-url] A Loki.js-based session store.
+
+[connect-loki-url]: https://www.npmjs.com/package/connect-loki
+[connect-loki-image]: https://badgen.net/github/stars/Requarks/connect-loki?label=%E2%98%85
+
+[![★][connect-lowdb-image] connect-lowdb][connect-lowdb-url] A lowdb-based session store.
+
+[connect-lowdb-url]: https://www.npmjs.com/package/connect-lowdb
+[connect-lowdb-image]: https://badgen.net/github/stars/travishorn/connect-lowdb?label=%E2%98%85
+
+[![★][connect-memcached-image] connect-memcached][connect-memcached-url] A memcached-based session store.
+
+[connect-memcached-url]: https://www.npmjs.com/package/connect-memcached
+[connect-memcached-image]: https://badgen.net/github/stars/balor/connect-memcached?label=%E2%98%85
+
+[![★][connect-memjs-image] connect-memjs][connect-memjs-url] A memcached-based session store using
+[memjs](https://www.npmjs.com/package/memjs) as the memcached client.
+
+[connect-memjs-url]: https://www.npmjs.com/package/connect-memjs
+[connect-memjs-image]: https://badgen.net/github/stars/liamdon/connect-memjs?label=%E2%98%85
+
+[![★][connect-ml-image] connect-ml][connect-ml-url] A MarkLogic Server-based session store.
+
+[connect-ml-url]: https://www.npmjs.com/package/connect-ml
+[connect-ml-image]: https://badgen.net/github/stars/bluetorch/connect-ml?label=%E2%98%85
+
+[![★][connect-monetdb-image] connect-monetdb][connect-monetdb-url] A MonetDB-based session store.
+
+[connect-monetdb-url]: https://www.npmjs.com/package/connect-monetdb
+[connect-monetdb-image]: https://badgen.net/github/stars/MonetDB/npm-connect-monetdb?label=%E2%98%85
+
+[![★][connect-mongo-image] connect-mongo][connect-mongo-url] A MongoDB-based session store.
+
+[connect-mongo-url]: https://www.npmjs.com/package/connect-mongo
+[connect-mongo-image]: https://badgen.net/github/stars/kcbanner/connect-mongo?label=%E2%98%85
+
+[![★][connect-mongodb-session-image] connect-mongodb-session][connect-mongodb-session-url] Lightweight MongoDB-based session store built and maintained by MongoDB.
+
+[connect-mongodb-session-url]: https://www.npmjs.com/package/connect-mongodb-session
+[connect-mongodb-session-image]: https://badgen.net/github/stars/mongodb-js/connect-mongodb-session?label=%E2%98%85
+
+[![★][connect-mssql-v2-image] connect-mssql-v2][connect-mssql-v2-url] A Microsoft SQL Server-based session store based on [connect-mssql](https://www.npmjs.com/package/connect-mssql).
+
+[connect-mssql-v2-url]: https://www.npmjs.com/package/connect-mssql-v2
+[connect-mssql-v2-image]: https://badgen.net/github/stars/jluboff/connect-mssql-v2?label=%E2%98%85
+
+[![★][connect-neo4j-image] connect-neo4j][connect-neo4j-url] A [Neo4j](https://neo4j.com)-based session store.
+
+[connect-neo4j-url]: https://www.npmjs.com/package/connect-neo4j
+[connect-neo4j-image]: https://badgen.net/github/stars/MaxAndersson/connect-neo4j?label=%E2%98%85
+
+[![★][connect-ottoman-image] connect-ottoman][connect-ottoman-url] A [couchbase ottoman](http://www.couchbase.com/)-based session store.
+
+[connect-ottoman-url]: https://www.npmjs.com/package/connect-ottoman
+[connect-ottoman-image]: https://badgen.net/github/stars/noiissyboy/connect-ottoman?label=%E2%98%85
+
+[![★][connect-pg-simple-image] connect-pg-simple][connect-pg-simple-url] A PostgreSQL-based session store.
+
+[connect-pg-simple-url]: https://www.npmjs.com/package/connect-pg-simple
+[connect-pg-simple-image]: https://badgen.net/github/stars/voxpelli/node-connect-pg-simple?label=%E2%98%85
+
+[![★][connect-redis-image] connect-redis][connect-redis-url] A Redis-based session store.
+
+[connect-redis-url]: https://www.npmjs.com/package/connect-redis
+[connect-redis-image]: https://badgen.net/github/stars/tj/connect-redis?label=%E2%98%85
+
+[![★][connect-session-firebase-image] connect-session-firebase][connect-session-firebase-url] A session store based on the [Firebase Realtime Database](https://firebase.google.com/docs/database/)
+
+[connect-session-firebase-url]: https://www.npmjs.com/package/connect-session-firebase
+[connect-session-firebase-image]: https://badgen.net/github/stars/benweier/connect-session-firebase?label=%E2%98%85
+
+[![★][connect-session-knex-image] connect-session-knex][connect-session-knex-url] A session store using
+[Knex.js](http://knexjs.org/), which is a SQL query builder for PostgreSQL, MySQL, MariaDB, SQLite3, and Oracle.
+
+[connect-session-knex-url]: https://www.npmjs.com/package/connect-session-knex
+[connect-session-knex-image]: https://badgen.net/github/stars/llambda/connect-session-knex?label=%E2%98%85
+
+[![★][connect-session-sequelize-image] connect-session-sequelize][connect-session-sequelize-url] A session store using
+[Sequelize.js](http://sequelizejs.com/), which is a Node.js / io.js ORM for PostgreSQL, MySQL, SQLite and MSSQL.
+
+[connect-session-sequelize-url]: https://www.npmjs.com/package/connect-session-sequelize
+[connect-session-sequelize-image]: https://badgen.net/github/stars/mweibel/connect-session-sequelize?label=%E2%98%85
+
+[![★][connect-sqlite3-image] connect-sqlite3][connect-sqlite3-url] A [SQLite3](https://github.com/mapbox/node-sqlite3) session store modeled after the TJ's `connect-redis` store.
+
+[connect-sqlite3-url]: https://www.npmjs.com/package/connect-sqlite3
+[connect-sqlite3-image]: https://badgen.net/github/stars/rawberg/connect-sqlite3?label=%E2%98%85
+
+[![★][connect-typeorm-image] connect-typeorm][connect-typeorm-url] A [TypeORM](https://github.com/typeorm/typeorm)-based session store.
+
+[connect-typeorm-url]: https://www.npmjs.com/package/connect-typeorm
+[connect-typeorm-image]: https://badgen.net/github/stars/makepost/connect-typeorm?label=%E2%98%85
+
+[![★][couchdb-expression-image] couchdb-expression][couchdb-expression-url] A [CouchDB](https://couchdb.apache.org/)-based session store.
+
+[couchdb-expression-url]: https://www.npmjs.com/package/couchdb-expression
+[couchdb-expression-image]: https://badgen.net/github/stars/tkshnwesper/couchdb-expression?label=%E2%98%85
+
+[![★][dynamodb-store-image] dynamodb-store][dynamodb-store-url] A DynamoDB-based session store.
+
+[dynamodb-store-url]: https://www.npmjs.com/package/dynamodb-store
+[dynamodb-store-image]: https://badgen.net/github/stars/rafaelrpinto/dynamodb-store?label=%E2%98%85
+
+[![★][dynamodb-store-v3-image] dynamodb-store-v3][dynamodb-store-v3-url] Implementation of a session store using DynamoDB backed by the [AWS SDK for JavaScript v3](https://github.com/aws/aws-sdk-js-v3).
+
+[dynamodb-store-v3-url]: https://www.npmjs.com/package/dynamodb-store-v3
+[dynamodb-store-v3-image]: https://badgen.net/github/stars/FryDay/dynamodb-store-v3?label=%E2%98%85
+
+[![★][express-etcd-image] express-etcd][express-etcd-url] An [etcd](https://github.com/stianeikeland/node-etcd) based session store.
+
+[express-etcd-url]: https://www.npmjs.com/package/express-etcd
+[express-etcd-image]: https://badgen.net/github/stars/gildean/express-etcd?label=%E2%98%85
+
+[![★][express-mysql-session-image] express-mysql-session][express-mysql-session-url] A session store using native
+[MySQL](https://www.mysql.com/) via the [node-mysql](https://github.com/felixge/node-mysql) module.
+
+[express-mysql-session-url]: https://www.npmjs.com/package/express-mysql-session
+[express-mysql-session-image]: https://badgen.net/github/stars/chill117/express-mysql-session?label=%E2%98%85
+
+[![★][express-nedb-session-image] express-nedb-session][express-nedb-session-url] A NeDB-based session store.
+
+[express-nedb-session-url]: https://www.npmjs.com/package/express-nedb-session
+[express-nedb-session-image]: https://badgen.net/github/stars/louischatriot/express-nedb-session?label=%E2%98%85
+
+[![★][express-oracle-session-image] express-oracle-session][express-oracle-session-url] A session store using native
+[oracle](https://www.oracle.com/) via the [node-oracledb](https://www.npmjs.com/package/oracledb) module.
+
+[express-oracle-session-url]: https://www.npmjs.com/package/express-oracle-session
+[express-oracle-session-image]: https://badgen.net/github/stars/slumber86/express-oracle-session?label=%E2%98%85
+
+[![★][express-session-cache-manager-image] express-session-cache-manager][express-session-cache-manager-url]
+A store that implements [cache-manager](https://www.npmjs.com/package/cache-manager), which supports
+a [variety of storage types](https://www.npmjs.com/package/cache-manager#store-engines).
+
+[express-session-cache-manager-url]: https://www.npmjs.com/package/express-session-cache-manager
+[express-session-cache-manager-image]: https://badgen.net/github/stars/theogravity/express-session-cache-manager?label=%E2%98%85
+
+[![★][express-session-etcd3-image] express-session-etcd3][express-session-etcd3-url] An [etcd3](https://github.com/mixer/etcd3) based session store.
+
+[express-session-etcd3-url]: https://www.npmjs.com/package/express-session-etcd3
+[express-session-etcd3-image]: https://badgen.net/github/stars/willgm/express-session-etcd3?label=%E2%98%85
+
+[![★][express-session-level-image] express-session-level][express-session-level-url] A [LevelDB](https://github.com/Level/levelup) based session store.
+
+[express-session-level-url]: https://www.npmjs.com/package/express-session-level
+[express-session-level-image]: https://badgen.net/github/stars/tgohn/express-session-level?label=%E2%98%85
+
+[![★][express-session-rsdb-image] express-session-rsdb][express-session-rsdb-url] Session store based on Rocket-Store: A very simple, super fast and yet powerful, flat file database.
+
+[express-session-rsdb-url]: https://www.npmjs.com/package/express-session-rsdb
+[express-session-rsdb-image]: https://badgen.net/github/stars/paragi/express-session-rsdb?label=%E2%98%85
+
+[![★][express-sessions-image] express-sessions][express-sessions-url] A session store supporting both MongoDB and Redis.
+
+[express-sessions-url]: https://www.npmjs.com/package/express-sessions
+[express-sessions-image]: https://badgen.net/github/stars/konteck/express-sessions?label=%E2%98%85
+
+[![★][firestore-store-image] firestore-store][firestore-store-url] A [Firestore](https://github.com/hendrysadrak/firestore-store)-based session store.
+
+[firestore-store-url]: https://www.npmjs.com/package/firestore-store
+[firestore-store-image]: https://badgen.net/github/stars/hendrysadrak/firestore-store?label=%E2%98%85
+
+[![★][fortune-session-image] fortune-session][fortune-session-url] A [Fortune.js](https://github.com/fortunejs/fortune)
+based session store. Supports all backends supported by Fortune (MongoDB, Redis, Postgres, NeDB).
+
+[fortune-session-url]: https://www.npmjs.com/package/fortune-session
+[fortune-session-image]: https://badgen.net/github/stars/aliceklipper/fortune-session?label=%E2%98%85
+
+[![★][hazelcast-store-image] hazelcast-store][hazelcast-store-url] A Hazelcast-based session store built on the [Hazelcast Node Client](https://www.npmjs.com/package/hazelcast-client).
+
+[hazelcast-store-url]: https://www.npmjs.com/package/hazelcast-store
+[hazelcast-store-image]: https://badgen.net/github/stars/jackspaniel/hazelcast-store?label=%E2%98%85
+
+[![★][level-session-store-image] level-session-store][level-session-store-url] A LevelDB-based session store.
+
+[level-session-store-url]: https://www.npmjs.com/package/level-session-store
+[level-session-store-image]: https://badgen.net/github/stars/toddself/level-session-store?label=%E2%98%85
+
+[![★][lowdb-session-store-image] lowdb-session-store][lowdb-session-store-url] A [lowdb](https://www.npmjs.com/package/lowdb)-based session store.
+
+[lowdb-session-store-url]: https://www.npmjs.com/package/lowdb-session-store
+[lowdb-session-store-image]: https://badgen.net/github/stars/fhellwig/lowdb-session-store?label=%E2%98%85
+
+[![★][medea-session-store-image] medea-session-store][medea-session-store-url] A Medea-based session store.
+
+[medea-session-store-url]: https://www.npmjs.com/package/medea-session-store
+[medea-session-store-image]: https://badgen.net/github/stars/BenjaminVadant/medea-session-store?label=%E2%98%85
+
+[![★][memorystore-image] memorystore][memorystore-url] A memory session store made for production.
+
+[memorystore-url]: https://www.npmjs.com/package/memorystore
+[memorystore-image]: https://badgen.net/github/stars/roccomuso/memorystore?label=%E2%98%85
+
+[![★][mssql-session-store-image] mssql-session-store][mssql-session-store-url] A SQL Server-based session store.
+
+[mssql-session-store-url]: https://www.npmjs.com/package/mssql-session-store
+[mssql-session-store-image]: https://badgen.net/github/stars/jwathen/mssql-session-store?label=%E2%98%85
+
+[![★][nedb-session-store-image] nedb-session-store][nedb-session-store-url] An alternate NeDB-based (either in-memory or file-persisted) session store.
+
+[nedb-session-store-url]: https://www.npmjs.com/package/nedb-session-store
+[nedb-session-store-image]: https://badgen.net/github/stars/JamesMGreene/nedb-session-store?label=%E2%98%85
+
+[![★][@quixo3/prisma-session-store-image] @quixo3/prisma-session-store][@quixo3/prisma-session-store-url] A session store for the [Prisma Framework](https://www.prisma.io).
+
+[@quixo3/prisma-session-store-url]: https://www.npmjs.com/package/@quixo3/prisma-session-store
+[@quixo3/prisma-session-store-image]: https://badgen.net/github/stars/kleydon/prisma-session-store?label=%E2%98%85
+
+[![★][restsession-image] restsession][restsession-url] Store sessions utilizing a RESTful API
+
+[restsession-url]: https://www.npmjs.com/package/restsession
+[restsession-image]: https://badgen.net/github/stars/jankal/restsession?label=%E2%98%85
+
+[![★][sequelstore-connect-image] sequelstore-connect][sequelstore-connect-url] A session store using [Sequelize.js](http://sequelizejs.com/).
+
+[sequelstore-connect-url]: https://www.npmjs.com/package/sequelstore-connect
+[sequelstore-connect-image]: https://badgen.net/github/stars/MattMcFarland/sequelstore-connect?label=%E2%98%85
+
+[![★][session-file-store-image] session-file-store][session-file-store-url] A file system-based session store.
+
+[session-file-store-url]: https://www.npmjs.com/package/session-file-store
+[session-file-store-image]: https://badgen.net/github/stars/valery-barysok/session-file-store?label=%E2%98%85
+
+[![★][session-pouchdb-store-image] session-pouchdb-store][session-pouchdb-store-url] Session store for PouchDB / CouchDB. Accepts embedded, custom, or remote PouchDB instance and realtime synchronization.
+
+[session-pouchdb-store-url]: https://www.npmjs.com/package/session-pouchdb-store
+[session-pouchdb-store-image]: https://badgen.net/github/stars/solzimer/session-pouchdb-store?label=%E2%98%85
+
+[![★][@cyclic.sh/session-store-image] @cyclic.sh/session-store][@cyclic.sh/session-store-url] A DynamoDB-based session store for [Cyclic.sh](https://www.cyclic.sh/) apps.
+
+[@cyclic.sh/session-store-url]: https://www.npmjs.com/package/@cyclic.sh/session-store
+[@cyclic.sh/session-store-image]: https://badgen.net/github/stars/cyclic-software/session-store?label=%E2%98%85
+
+[![★][@databunker/session-store-image] @databunker/session-store][@databunker/session-store-url] A [Databunker](https://databunker.org/)-based encrypted session store.
+
+[@databunker/session-store-url]: https://www.npmjs.com/package/@databunker/session-store
+[@databunker/session-store-image]: https://badgen.net/github/stars/securitybunker/databunker-session-store?label=%E2%98%85
+
+[![★][sessionstore-image] sessionstore][sessionstore-url] A session store that works with various databases.
+
+[sessionstore-url]: https://www.npmjs.com/package/sessionstore
+[sessionstore-image]: https://badgen.net/github/stars/adrai/sessionstore?label=%E2%98%85
+
+[![★][tch-nedb-session-image] tch-nedb-session][tch-nedb-session-url] A file system session store based on NeDB.
+
+[tch-nedb-session-url]: https://www.npmjs.com/package/tch-nedb-session
+[tch-nedb-session-image]: https://badgen.net/github/stars/tomaschyly/NeDBSession?label=%E2%98%85
+
+## Examples
+
+### View counter
+
+A simple example using `express-session` to store page views for a user.
+
+```js
+var express = require('express');
+var parseurl = require('parseurl');
+var session = require('express-session');
+
+var app = express();
+
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ })
+);
+
+app.use(function (req, res, next) {
+ if (!req.session.views) {
+ req.session.views = {};
+ }
+
+ // get the url pathname
+ var pathname = parseurl(req).pathname;
+
+ // count the views
+ req.session.views[pathname] = (req.session.views[pathname] || 0) + 1;
+
+ next();
+});
+
+app.get('/foo', function (req, res, next) {
+ res.send('you viewed this page ' + req.session.views['/foo'] + ' times');
+});
+
+app.get('/bar', function (req, res, next) {
+ res.send('you viewed this page ' + req.session.views['/bar'] + ' times');
+});
+
+app.listen(3000);
+```
+
+### User login
+
+A simple example using `express-session` to keep a user log in session.
+
+```js
+var escapeHtml = require('escape-html');
+var express = require('express');
+var session = require('express-session');
+
+var app = express();
+
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ })
+);
+
+// middleware to test if authenticated
+function isAuthenticated(req, res, next) {
+ if (req.session.user) next();
+ else next('route');
+}
+
+app.get('/', isAuthenticated, function (req, res) {
+ // this is only called when there is an authentication user due to isAuthenticated
+ res.send('hello, ' + escapeHtml(req.session.user) + '!' + ' Logout ');
+});
+
+app.get('/', function (req, res) {
+ res.send(
+ ''
+ );
+});
+
+app.post('/login', express.urlencoded({ extended: false }), function (req, res) {
+ // login logic to validate req.body.user and req.body.pass
+ // would be implemented here. for this example any combo works
+
+ // regenerate the session, which is good practice to help
+ // guard against forms of session fixation
+ req.session.regenerate(function (err) {
+ if (err) next(err);
+
+ // store user information in session, typically a user id
+ req.session.user = req.body.user;
+
+ // save the session before redirection to ensure page
+ // load does not happen before session is saved
+ req.session.save(function (err) {
+ if (err) return next(err);
+ res.redirect('/');
+ });
+ });
+});
+
+app.get('/logout', function (req, res, next) {
+ // logout logic
+
+ // clear the user from the session object and save.
+ // this will ensure that re-using the old session id
+ // does not have a logged in user
+ req.session.user = null;
+ req.session.save(function (err) {
+ if (err) next(err);
+
+ // regenerate the session, which is good practice to help
+ // guard against forms of session fixation
+ req.session.regenerate(function (err) {
+ if (err) next(err);
+ res.redirect('/');
+ });
+ });
+});
+
+app.listen(3000);
+```
+
+## Debugging
+
+This module uses the [debug](https://www.npmjs.com/package/debug) module
+internally to log information about session operations.
+
+To see all the internal logs, set the `DEBUG` environment variable to
+`express-session` when launching your app (`npm start`, in this example):
+
+```sh
+$ DEBUG=express-session npm start
+```
+
+On Windows, use the corresponding command;
+
+```sh
+> set DEBUG=express-session & npm start
+```
+
+## License
+
+[MIT](LICENSE)
+
+[rfc-6265bis-03-4.1.2.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7
+[rfc-cutler-httpbis-partitioned-cookies]: https://tools.ietf.org/html/draft-cutler-httpbis-partitioned-cookies/
+[rfc-west-cookie-priority-00-4.1]: https://tools.ietf.org/html/draft-west-cookie-priority-00#section-4.1
+[ci-image]: https://badgen.net/github/checks/expressjs/session/master?label=ci
+[ci-url]: https://github.com/expressjs/session/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/session/master
+[coveralls-url]: https://coveralls.io/r/expressjs/session?branch=master
+[node-url]: https://nodejs.org/en/download
+[npm-downloads-image]: https://badgen.net/npm/dm/express-session
+[npm-url]: https://npmjs.org/package/express-session
+[npm-version-image]: https://badgen.net/npm/v/express-session
diff --git a/astro/src/content/resources/de/middleware/timeout.md b/astro/src/content/resources/de/middleware/timeout.md
new file mode 100644
index 0000000000..f6057aedfd
--- /dev/null
+++ b/astro/src/content/resources/de/middleware/timeout.md
@@ -0,0 +1,176 @@
+---
+title: Express timeout middleware
+module: timeout
+---
+
+# connect-timeout
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][travis-image]][travis-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Times out a request in the Connect/Express application framework.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install connect-timeout
+```
+
+## API
+
+**NOTE** This module is not recommend as a "top-level" middleware (i.e.
+`app.use(timeout('5s'))`) unless you take precautions to halt your own
+middleware processing. See [as top-level middleware](#as-top-level-middleware)
+for how to use as a top-level middleware.
+
+While the library will emit a 'timeout' event when requests exceed the given
+timeout, node will continue processing the slow request until it terminates.
+Slow requests will continue to use CPU and memory, even if you are returning
+a HTTP response in the timeout callback. For better control over CPU/memory,
+you may need to find the events that are taking a long time (3rd party HTTP
+requests, disk I/O, database calls) and find a way to cancel them, and/or
+close the attached sockets.
+
+### timeout(time, [options])
+
+Returns middleware that times out in `time` milliseconds. `time` can also
+be a string accepted by the [ms](https://www.npmjs.org/package/ms#readme)
+module. On timeout, `req` will emit `"timeout"`.
+
+#### Options
+
+The `timeout` function takes an optional `options` object that may contain
+any of the following keys:
+
+##### respond
+
+Controls if this module will "respond" in the form of forwarding an error.
+If `true`, the timeout error is passed to `next()` so that you may customize
+the response behavior. This error has a `.timeout` property as well as
+`.status == 503`. This defaults to `true`.
+
+### req.clearTimeout()
+
+Clears the timeout on the request. The timeout is completely removed and
+will not fire for this request in the future.
+
+### req.timedout
+
+`true` if timeout fired; `false` otherwise.
+
+## Examples
+
+### as top-level middleware
+
+Because of the way middleware processing works, once this module
+passes the request to the next middleware (which it has to do in order
+for you to do work), it can no longer stop the flow, so you must take
+care to check if the request has timedout before you continue to act
+on the request.
+
+```javascript
+var bodyParser = require('body-parser');
+var cookieParser = require('cookie-parser');
+var express = require('express');
+var timeout = require('connect-timeout');
+
+// example of using this top-level; note the use of haltOnTimedout
+// after every middleware; it will stop the request flow on a timeout
+var app = express();
+app.use(timeout('5s'));
+app.use(bodyParser());
+app.use(haltOnTimedout);
+app.use(cookieParser());
+app.use(haltOnTimedout);
+
+// Add your routes here, etc.
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+app.listen(3000);
+```
+
+### express 3.x
+
+```javascript
+var express = require('express');
+var bodyParser = require('body-parser');
+var timeout = require('connect-timeout');
+
+var app = express();
+app.post('/save', timeout('5s'), bodyParser.json(), haltOnTimedout, function (req, res, next) {
+ savePost(req.body, function (err, id) {
+ if (err) return next(err);
+ if (req.timedout) return;
+ res.send('saved as id ' + id);
+ });
+});
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+function savePost(post, cb) {
+ setTimeout(
+ function () {
+ cb(null, (Math.random() * 40000) >>> 0);
+ },
+ (Math.random() * 7000) >>> 0
+ );
+}
+
+app.listen(3000);
+```
+
+### connect
+
+```javascript
+var bodyParser = require('body-parser');
+var connect = require('connect');
+var timeout = require('connect-timeout');
+
+var app = connect();
+app.use('/save', timeout('5s'), bodyParser.json(), haltOnTimedout, function (req, res, next) {
+ savePost(req.body, function (err, id) {
+ if (err) return next(err);
+ if (req.timedout) return;
+ res.send('saved as id ' + id);
+ });
+});
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+function savePost(post, cb) {
+ setTimeout(
+ function () {
+ cb(null, (Math.random() * 40000) >>> 0);
+ },
+ (Math.random() * 7000) >>> 0
+ );
+}
+
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/connect-timeout.svg
+[npm-url]: https://npmjs.org/package/connect-timeout
+[travis-image]: https://img.shields.io/travis/expressjs/timeout/master.svg
+[travis-url]: https://travis-ci.org/expressjs/timeout
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/timeout/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/timeout?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/connect-timeout.svg
+[downloads-url]: https://npmjs.org/package/connect-timeout
diff --git a/astro/src/content/resources/de/middleware/vhost.md b/astro/src/content/resources/de/middleware/vhost.md
new file mode 100644
index 0000000000..72f49d7f93
--- /dev/null
+++ b/astro/src/content/resources/de/middleware/vhost.md
@@ -0,0 +1,174 @@
+---
+title: Express vhost middleware
+module: vhost
+---
+
+# vhost
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Install
+
+```sh
+$ npm install vhost
+```
+
+## API
+
+```js
+var vhost = require('vhost');
+```
+
+### vhost(hostname, handle)
+
+Create a new middleware function to hand off request to `handle` when the incoming
+host for the request matches `hostname`. The function is called as
+`handle(req, res, next)`, like a standard middleware.
+
+`hostname` can be a string or a RegExp object. When `hostname` is a string it can
+contain `*` to match 1 or more characters in that section of the hostname. When
+`hostname` is a RegExp, it will be forced to case-insensitive (since hostnames are)
+and will be forced to match based on the start and end of the hostname.
+
+When host is matched and the request is sent down to a vhost handler, the `req.vhost`
+property will be populated with an object. This object will have numeric properties
+corresponding to each wildcard (or capture group if RegExp object provided) and the
+`hostname` that was matched.
+
+```js
+var connect = require('connect');
+var vhost = require('vhost');
+var app = connect();
+
+app.use(
+ vhost('*.*.example.com', function handle(req, res, next) {
+ // for match of "foo.bar.example.com:8080" against "*.*.example.com":
+ console.dir(req.vhost.host); // => 'foo.bar.example.com:8080'
+ console.dir(req.vhost.hostname); // => 'foo.bar.example.com'
+ console.dir(req.vhost.length); // => 2
+ console.dir(req.vhost[0]); // => 'foo'
+ console.dir(req.vhost[1]); // => 'bar'
+ })
+);
+```
+
+## Examples
+
+### using with connect for static serving
+
+```js
+var connect = require('connect');
+var serveStatic = require('serve-static');
+var vhost = require('vhost');
+
+var mailapp = connect();
+
+// add middlewares to mailapp for mail.example.com
+
+// create app to serve static files on subdomain
+var staticapp = connect();
+staticapp.use(serveStatic('public'));
+
+// create main app
+var app = connect();
+
+// add vhost routing to main app for mail
+app.use(vhost('mail.example.com', mailapp));
+
+// route static assets for "assets-*" subdomain to get
+// around max host connections limit on browsers
+app.use(vhost('assets-*.example.com', staticapp));
+
+// add middlewares and main usage to app
+
+app.listen(3000);
+```
+
+### using with connect for user subdomains
+
+```js
+var connect = require('connect');
+var serveStatic = require('serve-static');
+var vhost = require('vhost');
+
+var mainapp = connect();
+
+// add middlewares to mainapp for the main web site
+
+// create app that will server user content from public/{username}/
+var userapp = connect();
+
+userapp.use(function (req, res, next) {
+ var username = req.vhost[0]; // username is the "*"
+
+ // pretend request was for /{username}/* for file serving
+ req.originalUrl = req.url;
+ req.url = '/' + username + req.url;
+
+ next();
+});
+userapp.use(serveStatic('public'));
+
+// create main app
+var app = connect();
+
+// add vhost routing for main app
+app.use(vhost('userpages.local', mainapp));
+app.use(vhost('www.userpages.local', mainapp));
+
+// listen on all subdomains for user pages
+app.use(vhost('*.userpages.local', userapp));
+
+app.listen(3000);
+```
+
+### using with any generic request handler
+
+```js
+var connect = require('connect');
+var http = require('http');
+var vhost = require('vhost');
+
+// create main app
+var app = connect();
+
+app.use(
+ vhost('mail.example.com', function (req, res) {
+ // handle req + res belonging to mail.example.com
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello from mail!');
+ })
+);
+
+// an external api server in any framework
+var httpServer = http.createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello from the api!');
+});
+
+app.use(
+ vhost('api.example.com', function (req, res) {
+ // handle req + res belonging to api.example.com
+ // pass the request to a standard Node.js HTTP server
+ httpServer.emit('request', req, res);
+ })
+);
+
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/vhost.svg
+[npm-url]: https://npmjs.org/package/vhost
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/vhost/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/vhost
+[downloads-image]: https://img.shields.io/npm/dm/vhost.svg
+[downloads-url]: https://npmjs.org/package/vhost
+[github-actions-ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/vhost/ci.yml?branch=master&label=ci
+[github-actions-ci-url]: https://github.com/expressjs/vhost/actions/workflows/ci.yml
diff --git a/astro/src/content/resources/de/utils.md b/astro/src/content/resources/de/utils.md
new file mode 100644
index 0000000000..546b2f09b4
--- /dev/null
+++ b/astro/src/content/resources/de/utils.md
@@ -0,0 +1,22 @@
+---
+title: Express utilities
+description: Discover utility modules related to Express.js and Node.js, including tools for cookies, CSRF protection, URL parsing, routing, and more to enhance your applications.
+---
+
+## Express utility functions
+
+The [pillarjs](https://github.com/pillarjs) GitHub organization contains a number of modules
+for utility functions that may be generally useful.
+
+| Utility modules | Description |
+| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| [cookies](https://www.npmjs.com/package/cookies) | Get and set HTTP(S) cookies that can be signed to prevent tampering, using Keygrip. Can be used with the Node.js HTTP library or as Express middleware. |
+| [csrf](https://www.npmjs.com/package/csrf) | Contains the logic behind CSRF token creation and verification. Use this module to create custom CSRF middleware. |
+| [finalhandler](https://www.npmjs.com/package/finalhandler) | Function to invoke as the final step to respond to HTTP request. |
+| [parseurl](https://www.npmjs.com/package/parseurl) | Parse a URL with caching. |
+| [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) | Turn an Express-style path string such as ``/user/:name` into a regular expression. |
+| [resolve-path](https://www.npmjs.com/package/resolve-path) | Resolves a relative path against a root path with validation. |
+| [router](https://www.npmjs.com/package/router) | Simple middleware-style router. |
+| [send](https://www.npmjs.com/package/send) | Library for streaming files as a HTTP response, with support for partial responses (ranges), conditional-GET negotiation, and granular events. |
+
+For additional low-level HTTP-related modules, see [jshttp](https://github.com/jshttp).
diff --git a/astro/src/content/resources/en/community.md b/astro/src/content/resources/en/community.md
new file mode 100755
index 0000000000..e40d97e421
--- /dev/null
+++ b/astro/src/content/resources/en/community.md
@@ -0,0 +1,70 @@
+---
+title: Express community
+description: Connect with the Express.js community, learn about the technical committee, find resources, explore community-contributed modules, and get involved in discussions.
+---
+
+# Community
+
+## Technical committee
+
+The Express technical committee meets online every two weeks (as needed) to discuss development and maintenance of Express,
+and other issues relevant to the Express project. Each meeting is typically announced in an
+[expressjs/discussions issue](https://github.com/expressjs/discussions/issues) with a link to join or view the meeting, which is
+open to all observers.
+
+The meetings are recorded; for a list of the recordings, see the [Express.js YouTube channel](https://www.youtube.com/channel/UCYjxjAeH6TRik9Iwy5nXw7g).
+
+Members of the Express technical committee are:
+
+**Active:**
+
+- [@blakeembrey](https://github.com/blakeembrey) - Blake Embrey
+- [@crandmck](https://github.com/crandmck) - Rand McKinney
+- [@LinusU](https://github.com/LinusU) - Linus Unnebäck
+- [@ulisesgascon](https://github.com/ulisesGascon) - Ulises Gascón
+- [@sheplu](https://github.com/sheplu) - Jean Burellier
+- [@wesleytodd](https://github.com/wesleytodd) - Wes Todd
+- [@jonchurch](https://github.com/jonchurch) - Jon Church
+- [@ctcpip](https://github.com/ctcpip/) - Chris de Almeida
+
+**Inactive:**
+
+- [@dougwilson](https://github.com/dougwilson) - Douglas Wilson
+- [@hacksparrow](https://github.com/hacksparrow) - Hage Yaapa
+- [@jonathanong](https://github.com/jonathanong) - jongleberry
+- [@niftylettuce](https://github.com/niftylettuce) - niftylettuce
+- [@troygoode](https://github.com/troygoode) - Troy Goode
+
+## Express is made of many modules
+
+Our vibrant community has created a large variety of extensions,
+[middleware modules](/en/resources/middleware) and higher-level frameworks.
+
+Additionally, the Express community maintains modules in these two GitHub orgs:
+
+- [jshttp](https://github.com/jshttp) modules providing useful utility functions; see [Utility modules](/en/resources/utils).
+- [pillarjs](https://github.com/pillarjs): low-level modules that Express uses internally.
+
+To keep up with what is going on in the whole community, check out the [ExpressJS StatusBoard](https://expressjs.github.io/statusboard/).
+
+## Issues
+
+If you've come across what you think is a bug, or just want to make
+a feature request open a ticket in the [issue queue](https://github.com/expressjs/express/issues).
+
+## Examples
+
+View dozens of Express application [examples](https://github.com/expressjs/express/tree/master/examples)
+in the repository covering everything from API design and authentication to template engine integration.
+
+## Github Discussions
+
+The [GitHub Discussions](https://github.com/expressjs/discussions) section is an excellent space to engage in conversations about the development and maintenance of Express, as well as to share ideas and discuss topics related to its usage.
+
+# Branding of Express.js
+
+## Express.js Logo
+
+Express is a project of the OpenJS Foundation. Please review the [trademark policy](https://trademark-policy.openjsf.org/) for information about permissible use of Express.js logos and marks.
+
+
diff --git a/astro/src/content/resources/en/contributing.md b/astro/src/content/resources/en/contributing.md
new file mode 100644
index 0000000000..82c6b8fed7
--- /dev/null
+++ b/astro/src/content/resources/en/contributing.md
@@ -0,0 +1,482 @@
+---
+title: Contributing to Express
+description: Find out how to contribute to Express.js, including guidelines for reporting issues, submitting pull requests, becoming a collaborator, and understanding security policies.
+---
+
+# Contributing to Express
+
+### Looking to contribute to Expressjs.com? Click [here](#expressjs-website-contributing).
+
+Express and the other projects in the [expressjs organization on GitHub](https://github.com/expressjs) are projects of the [OpenJs Foundation](https://openjsf.org/).
+These projects are governed under the general policies and guidelines of the Node.js Foundation along with the additional guidelines below.
+
+- [Technical committee](#technical-committee)
+- [Community contributing guide](#community-contributing-guide)
+- [Collaborator's guide](#collaborators-guide)
+- [Security policies and procedures](#security-policies-and-procedures)
+
+## Technical committee
+
+The Express technical committee consists of active project members, and guides development and maintenance of the Express project. For more information, see [Express Community - Technical committee](/en/resources/community/#technical-committee).
+
+## Community contributing guide
+
+
+
+The goal of this document is to create a contribution process that:
+
+- Encourages new contributions.
+- Encourages contributors to remain involved.
+- Avoids unnecessary processes and bureaucracy whenever possible.
+- Creates a transparent decision making process that makes it clear how
+ contributors can be involved in decision making.
+
+### Vocabulary
+
+- A **Contributor** is any individual creating or commenting on an issue or pull request.
+- A **Committer** is a subset of contributors who have been given write access to the repository.
+- A **Project Captain** is the lead maintainer of a repository.
+- A **TC (Technical Committee)** is a group of committers representing the required technical
+ expertise to resolve rare disputes.
+- A **Triager** is a subset of contributors who have been given triage access to the repository.
+
+### Logging Issues
+
+Log an issue for any question or problem you might have. When in doubt, log an issue, and
+any additional policies about what to include will be provided in the responses. The only
+exception is security disclosures which should be sent privately.
+
+Committers may direct you to another repository, ask for additional clarifications, and
+add appropriate metadata before the issue is addressed.
+
+Please be courteous and respectful. Every participant is expected to follow the
+project's Code of Conduct.
+
+### Contributions
+
+Any change to resources in this repository must be through pull requests. This applies to all changes
+to documentation, code, binary files, etc. Even long term committers and TC members must use
+pull requests.
+
+No pull request can be merged without being reviewed.
+
+For non-trivial contributions, pull requests should sit for at least 36 hours to ensure that
+contributors in other timezones have time to review. Consideration should also be given to
+weekends and other holiday periods to ensure active committers all have reasonable time to
+become involved in the discussion and review process if they wish.
+
+The default for each contribution is that it is accepted once no committer has an objection.
+During a review, committers may also request that a specific contributor who is most versed in a
+particular area gives a "LGTM" before the PR can be merged. There is no additional "sign off"
+process for contributions to land. Once all issues brought by committers are addressed it can
+be landed by any committer.
+
+In the case of an objection being raised in a pull request by another committer, all involved
+committers should seek to arrive at a consensus by way of addressing concerns being expressed
+by discussion, compromise on the proposed change, or withdrawal of the proposed change.
+
+If a contribution is controversial and committers cannot agree about how to get it to land
+or if it should land then it should be escalated to the TC. TC members should regularly
+discuss pending contributions in order to find a resolution. It is expected that only a
+small minority of issues be brought to the TC for resolution and that discussion and
+compromise among committers be the default resolution mechanism.
+
+### Becoming a Triager
+
+Anyone can become a triager! Read more about the process of being a triager in
+[the triage process document](https://github.com/expressjs/discussions/blob/master/Triager-Guide.md).
+
+Currently, any existing [organization member](https://github.com/orgs/expressjs/people) can nominate
+a new triager. If you are interested in becoming a triager, our best advice is to actively participate
+in the community by helping triaging issues and pull requests. As well we recommend
+to engage in other community activities like attending the TC meetings, and participating in the Slack
+discussions. If you feel ready and have been helping triage some issues, reach out to an active member of the organization to ask if they'd
+be willing to support you. If they agree, they can create a pull request to formalize your nomination. In the case of an objection to the nomination, the triage team is responsible for working with the individuals involved and finding a resolution.
+
+You can also reach out to any of the [organization members](https://github.com/orgs/expressjs/people)
+if you have questions or need guidance.
+
+### Becoming a Committer
+
+All contributors who have landed significant and valuable contributions should be onboarded in a timely manner,
+and added as a committer, and be given write access to the repository.
+
+Committers are expected to follow this policy and continue to send pull requests, go through
+proper review, and have other committers merge their pull requests.
+
+### TC Process
+
+The TC uses a "consensus seeking" process for issues that are escalated to the TC.
+The group tries to find a resolution that has no open objections among TC members.
+If a consensus cannot be reached that has no objections then a majority wins vote
+is called. It is also expected that the majority of decisions made by the TC are via
+a consensus seeking process and that voting is only used as a last-resort.
+
+Resolution may involve returning the issue to project captains with suggestions on
+how to move forward towards a consensus. It is not expected that a meeting of the TC
+will resolve all issues on its agenda during that meeting and may prefer to continue
+the discussion happening among the project captains.
+
+Members can be added to the TC at any time. Any TC member can nominate another committer
+to the TC and the TC uses its standard consensus seeking process to evaluate whether or
+not to add this new member. The TC will consist of a minimum of 3 active members and a
+maximum of 10. If the TC should drop below 5 members the active TC members should nominate
+someone new. If a TC member is stepping down, they are encouraged (but not required) to
+nominate someone to take their place.
+
+TC members will be added as admin's on the Github orgs, npm orgs, and other resources as
+necessary to be effective in the role.
+
+To remain "active" a TC member should have participation within the last 12 months and miss
+no more than six consecutive TC meetings. Our goal is to increase participation, not punish
+people for any lack of participation, this guideline should be only be used as such
+(replace an inactive member with a new active one, for example). Members who do not meet this
+are expected to step down. If A TC member does not step down, an issue can be opened in the
+discussions repo to move them to inactive status. TC members who step down or are removed due
+to inactivity will be moved into inactive status.
+
+Inactive status members can become active members by self nomination if the TC is not already
+larger than the maximum of 10. They will also be given preference if, while at max size, an
+active member steps down.
+
+### Project Captains
+
+The Express TC can designate captains for individual projects/repos in the
+organizations. These captains are responsible for being the primary
+day-to-day maintainers of the repo on a technical and community front.
+Repo captains are empowered with repo ownership and package publication rights.
+When there are conflicts, especially on topics that effect the Express project
+at large, captains are responsible to raise it up to the TC and drive
+those conflicts to resolution. Captains are also responsible for making sure
+community members follow the community guidelines, maintaining the repo
+and the published package, as well as in providing user support.
+
+Like TC members, Repo captains are a subset of committers.
+
+To become a captain for a project the candidate is expected to participate in that
+project for at least 6 months as a committer prior to the request. They should have
+helped with code contributions as well as triaging issues. They are also required to
+have 2FA enabled on both their GitHub and npm accounts.
+
+Any TC member or an existing captain on the **same** repo can nominate another committer
+to the captain role. To do so, they should submit a PR to this document, updating the
+**Active Project Captains** section (while maintaining the sort order) with the project
+name, the nominee's GitHub handle, and their npm username (if different).
+
+- Repos can have as many captains as make sense for the scope of work.
+- A TC member or an existing repo captain **on the same project** can nominate a new captain.
+ Repo captains from other projects should not nominate captains for a different project.
+
+The PR will require at least 2 approvals from TC members and 2 weeks hold time to allow
+for comment and/or dissent. When the PR is merged, a TC member will add them to the
+proper GitHub/npm groups.
+
+#### Active Projects and Captains
+
+The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members)
+
+#### Current Initiative Captains
+
+The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains)
+
+### Inactivity and Emeritus Policy for Any Role
+
+To support the health and continuity of the project, all individuals holding a role within the community (such as Triager, Committer, WG member, Project Captain, or TC member) are encouraged to maintain active participation.
+
+Inactivity is defined as the absence of meaningful involvement in the project—such as contributions, code reviews, triage, meeting attendance, or discussion participation—for a continuous period of 6 months.
+
+#### Exceptions
+
+Anyone may request a temporary leave from active participation due to personal or professional reasons. In such cases, the individual should inform the relevant team or the Technical Committee (TC). During this time, the inactivity policy is paused, and the individual will not be flagged as inactive.
+
+#### Inactivity Process
+
+- If someone is deemed inactive, the individual may be transitioned to an emeritus role that reflects their past contributions. A best effort will be made to inform them that this has occurred. They may request to be reinstated when they are ready to be active again.
+- The emeritus status helps preserve a clear record of contributors who have meaningfully shaped the project over time.
+
+#### Accountability
+
+- The Technical Committee (TC) and the respective captains of each package/team are responsible for assessing activity levels and enacting this policy fairly and transparently, in coordination with other relevant teams.
+- In case of disagreement, the situation can be discussed and resolved by consensus within the TC or appropriate team.
+
+### Developer's Certificate of Origin 1.1
+
+```text
+By making a contribution to this project, I certify that:
+
+ (a) The contribution was created in whole or in part by me and I
+ have the right to submit it under the open source license
+ indicated in the file; or
+
+ (b) The contribution is based upon previous work that, to the best
+ of my knowledge, is covered under an appropriate open source
+ license and I have the right under that license to submit that
+ work with modifications, whether created in whole or in part
+ by me, under the same open source license (unless I am
+ permitted to submit under a different license), as indicated
+ in the file; or
+
+ (c) The contribution was provided directly to me by some other
+ person who certified (a), (b) or (c) and I have not modified
+ it.
+
+ (d) I understand and agree that this project and the contribution
+ are public and that a record of the contribution (including all
+ personal information I submit with it, including my sign-off) is
+ maintained indefinitely and may be redistributed consistent with
+ this project or the open source license(s) involved.
+```
+
+## Collaborator's guide
+
+
+
+### Website Issues
+
+Open issues for the expressjs.com website in https://github.com/expressjs/expressjs.com.
+
+For issues in other Express managed repos (everything in `expressjs`, `pillarjs` or `jshttp` other than `expressjs/express`), be sure to check their contributing guide and open issues and PRs in the appropriate repository.
+
+### PRs and Code contributions
+
+- Tests must pass.
+- Follow the [JavaScript Standard Style](https://standardjs.com/) and `npm run lint`.
+- If you fix a bug, add a test.
+
+### Branches
+
+Use the `master` branch for bug fixes or minor work that is intended for the
+current release stream.
+
+Use the correspondingly named branch, e.g. `6.x`, for anything intended for
+a future release of Express.
+
+### Steps for contributing
+
+1. Create an issue for the
+ bug you want to fix or the feature that you want to add.
+2. Create your own fork on GitHub, then
+ checkout your fork.
+3. Write your code in your local copy. It's good practice to create a branch for
+ each new issue you work on, although not compulsory.
+4. To run the test suite, first install the dependencies by running `npm install`,
+ then run `npm test`.
+5. Ensure your code is linted by running `npm run lint` -- fix any issue you
+ see listed.
+6. If the tests pass, you can commit your changes to your fork and then create
+ a pull request from there. Make sure to reference your issue from the pull
+ request comments by including the issue number e.g. `#123`.
+
+### Issues which are questions
+
+We will typically close any vague issues or questions that are specific to some
+app you are writing. Please double check the docs and other references before
+being trigger happy with posting a question issue.
+
+Things that will help get your question issue looked at:
+
+- Full and runnable JS code.
+- Clear description of the problem or unexpected behavior.
+- Clear description of the expected result.
+- Steps you have taken to debug it yourself.
+
+If you post a question and do not outline the above items or make it easy for
+us to understand and reproduce your issue, it will be closed.
+
+If your question meets all of the above requirements but you do not believe it needs to be looked at
+by the maintainers
+(for example, if you are just looking for community input) please open it as a discussion topic instead
+of an issue. If you
+are unsure and open an issue, we may move it to discussions if we triage them and decide they do
+not need high
+visibility or maintainer input.
+
+## Security Policies and Procedures
+
+
+
+This document outlines security procedures and general policies for the Express
+project.
+
+- [Reporting a Bug](#reporting-a-bug)
+- [Disclosure Policy](#disclosure-policy)
+- [Comments on this Policy](#comments-on-this-policy)
+
+### Reporting a Bug
+
+The Express team and community take all security bugs in Express seriously.
+Thank you for improving the security of Express. We appreciate your efforts and
+responsible disclosure and will make every effort to acknowledge your
+contributions.
+
+Report security bugs by emailing `express-security@lists.openjsf.org`.
+
+To ensure the timely response to your report, please ensure that the entirety
+of the report is contained within the email body and not solely behind a web
+link or an attachment.
+
+The lead maintainer will acknowledge your email within 48 hours, and will send a
+more detailed response within 48 hours indicating the next steps in handling
+your report. After the initial reply to your report, the security team will
+endeavor to keep you informed of the progress towards a fix and full
+announcement, and may ask for additional information or guidance.
+
+Report security bugs in third-party modules to the person or team maintaining
+the module.
+
+### Pre-release Versions
+
+Alpha and Beta releases are unstable and **not suitable for production use**.
+Vulnerabilities found in pre-releases should be reported according to the [Reporting a Bug](#reporting-a-bug) section.
+Due to the unstable nature of the branch it is not guaranteed that any fixes will be released in the next pre-release.
+
+### Disclosure Policy
+
+When the security team receives a security bug report, they will assign it to a
+primary handler. This person will coordinate the fix and release process,
+involving the following steps:
+
+- Confirm the problem and determine the affected versions.
+- Audit code to find any potential similar problems.
+- Prepare fixes for all releases still under maintenance. These fixes will be
+ released as fast as possible to npm.
+
+### The Express Threat Model
+
+We are currently working on a new version of the security model, the most updated version can be found [here](https://github.com/expressjs/security-wg/blob/main/docs/ThreatModel.md)
+
+### Comments on this Policy
+
+If you have suggestions on how this process could be improved please submit a
+pull request.
+
+---
+
+# Contributing to Expressjs.com {#expressjs-website-contributing}
+
+
+
+### The Official Documentation of the Express.js Framework
+
+This is the contribution documentation for the [expressjs.com](https://github.com/expressjs/expressjs.com) website.
+
+#### Need some ideas? These are some typical issues.
+
+1. **Website issues**: If you see anything on the site that could use a tune-up, think about how to fix it.
+ - Display or screen sizing problems
+ - Mobile responsiveness issues
+ - Missing or broken accessibility features
+ - Website outages
+ - Broken links
+ - Page structure or user interface enhancements
+
+2. **Content Issues**: Fix anything related to site content or typos.
+ - Spelling errors
+ - Incorrect/outdated Express.js documentation
+ - Missing content
+
+3. **Translation Issues**: Fix any translation errors or contribute new content.
+ - Fix spelling errors
+ - Fix incorrect/poorly translated words
+ - Check out the [Contributing translations](#contributing-translations) section below for a contributing guide.
+
+#### Want to work on a backlog issue?
+
+We often have bugs or enhancements that need work. You can find these under our repo's [Issues tab](https://github.com/expressjs/expressjs.com/issues). Check out the tags to find something that's a good match for you.
+
+#### Have an idea? Found a bug?
+
+If you've found a bug or a typo, or if you have an idea for an enhancement, you can:
+
+- Submit a [new issue](https://github.com/expressjs/expressjs.com/issues/new/choose) on our repo. Do this for larger proposals, or if you'd like to discuss or get feedback first.
+
+- Make a [GitHub pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). If you have already done work, and it's ready to go, feel free to send it our way.
+
+## Getting Started
+
+The steps below will guide you through the Expressjs.com contribution process.
+
+#### Step 1: (OPTIONAL) Open a New Issue
+
+So you've found a problem that you want to fix, or have a site enhancement you want to make.
+
+1. If you want to get feedback or discuss, open a discussion [issue](https://github.com/expressjs/expressjs.com/issues/new/choose) prior to starting work. This is not required, but encouraged for larger proposals.
+ - While we highly encourage this step, it is only for submissions proposing significant change. It helps us to clarify and focus the work, and ensure it aligns with overall project priorities.
+ - For submissions proposing minor improvements or corrections, this is not needed. You can skip this step.
+ - When opening an issue please give it a title and fill in the description section. The more details you provide, the more feedback we can give.
+
+2. After receiving your issue the Express.js documentation team will respond with feedback. We read every submission and always try to respond quickly with feedback.
+ - For submissions proposing significant change, we encourage you to follow the review process before starting work.
+
+#### Step 2: Get the Application Code Base
+
+Clone the repo and get the code:
+
+```sh
+git clone https://github.com/expressjs/expressjs.com.git
+```
+
+After you've got the code you're ready to start making your changes!
+
+But just in case you need a little extra explanation, this section below outlines the main sections of the code base, where most changes are likely to be made.
+
+**Markdown Page Files**:
+
+- These files render to html and make up the individual pages of the site. Most of the site's documentation text content is written in `md` files.
+- Change these to make changes to individual pages' content/text or markup.
+- Each language has its own complete set of pages, located under their respective language directories - all the Spanish markdown content is found in the `es` directory, for example.
+
+**Includes Partials and Layout Templates**
+
+- `_includes` are partials that are imported and reused across multiple pages.
+ - These are used to import text content for reuse across pages, such as the API documentation, e.g., `_includes > api > en > 5x`, which is included in every language.
+ - These are used to include the page components that make up site-wide user interface and periphery structure, e.g., Header, Footer, etc.
+- `_layouts` are the templates used to wrap the site's individual pages.
+ - These are used to display the structure of the site's periphery, such as the header and footer, and for injecting and displaying individual markdown pages inside the `content` tag.
+
+**Blog Markdown Files**
+
+- These files make up the individual blog posts. If you want to contribute a blog post please
+ follow the specific instructions for [How to write a blog post.](https://expressjs.com/en/blog/write-post)
+- Located under the `_posts` directory.
+
+**CSS or Javascript**
+
+- All css and js files are kept in `css` and `js` folders on the project root.
+
+The Express.js website is built using [Jekyll](https://jekyllrb.com/) and is hosted on [GitHub Pages](https://pages.github.com/).
+
+#### Step 3: Running the Application
+
+Now you'll need a way to see your changes, which means you'll need a running version of the application. You have two options.
+
+1. **Run Locally**: This gets the local version of the application up and running on your machine. Follow our [Local Setup Guide](https://github.com/expressjs/expressjs.com?tab=readme-ov-file#build-the-website-locally) to use this option.
+ - This is the recommended option for moderate to complex work.
+
+2. **Run using Deploy Preview**: Use this option if you don't want to bother with a local installation. Part of our continuous integration pipeline includes [Netlify Deploy Preview](https://docs.netlify.com/deploy/deploy-types/deploy-previews/).
+ 1. To use this you'll need to get your changes online - after you've made your first commit on your feature branch, make a _draft_ pull request.
+ 2. After the build steps are complete, you'll have access to a **Deploy Preview** tab that will run your changes on the web, rebuilding after each commit is pushed.
+ 3. After you are completely done your work, and it's ready for review, remove the draft status on your pull request and submit your work.
+
+## Contributing translations
+
+We use Crowdin to manage our translations in multiple languages and achieve automatic translation with artificial intelligence. Since these translations can be inefficient in some cases, we need help from the community to provide accurate and helpful translations.
+
+The documentation is translated into these languages:
+
+- Chinese Simplified (`zh-cn`)
+- Chinese Traditional (`zh-tw`)
+- English (`en`)
+- French (`fr`)
+- German (`de`)
+- Italian (`it`)
+- Japanese (`ja`)
+- Korean (`ko`)
+- Brazilian Portuguese (`pt-br`)
+- Spanish (`es`)
+
+### How to translate
+
+1. Request to join the Express.js Website project on [Crowdin](https://express.crowdin.com/website)
+2. [Select the language you want to translate](https://support.crowdin.com/for-translators/#starting-translation)
+3. [Start translating](https://support.crowdin.com/online-editor/)
diff --git a/astro/src/content/resources/en/glossary.md b/astro/src/content/resources/en/glossary.md
new file mode 100755
index 0000000000..8b45bf01eb
--- /dev/null
+++ b/astro/src/content/resources/en/glossary.md
@@ -0,0 +1,62 @@
+---
+title: Express glossary
+description: A comprehensive glossary of terms related to Express.js, Node.js, middleware, routing, and other key concepts to help you understand and use Express effectively.
+---
+
+# Glossary
+
+### application
+
+In general, one or more programs that are designed to carry out operations for a specific purpose. In the context of Express, a program that uses the Express API running on the Node.js platform. Might also refer to an [app object](/en/api#express).
+
+### API
+
+Application programming interface. Spell out the abbreviation when it is first used.
+
+### Express
+
+A fast, un-opinionated, minimalist web framework for Node.js applications. In general, "Express" is preferred to "Express.js," though the latter is acceptable.
+
+### libuv
+
+A multi-platform support library which focuses on asynchronous I/O, primarily developed for use by Node.js.
+
+### middleware
+
+A function that is invoked by the Express routing layer before the final request handler, and thus sits in the middle between a raw request and the final intended route. A few fine points of terminology around middleware:
+
+- `var foo = require('middleware')` is called _requiring_ or _using_ a Node.js module. Then the statement `var mw = foo()` typically returns the middleware.
+- `app.use(mw)` is called _adding the middleware to the global processing stack_.
+- `app.get('/foo', mw, function (req, res) { ... })` is called _adding the middleware to the "GET /foo" processing stack_.
+
+### Node.js
+
+A software platform that is used to build scalable network applications. Node.js uses JavaScript as its scripting language, and achieves high throughput via non-blocking I/O and a single-threaded event loop. See [nodejs.org](https://nodejs.org/en/). **Usage note**: Initially, "Node.js," thereafter "Node".
+
+### open-source, open source
+
+When used as an adjective, hyphenate; for example: "This is open-source software." See [Open-source software on Wikipedia](http://en.wikipedia.org/wiki/Open-source_software).
+
+{% capture english-rules %}
+
+Although it is common not to hyphenate this term, we are using the standard English rules for hyphenating a compound adjective.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=english-rules %}
+
+### request
+
+An HTTP request. A client submits an HTTP request message to a server, which returns a response. The request must use one of several [request methods](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods) such as GET, POST, and so on.
+
+### response
+
+An HTTP response. A server returns an HTTP response message to the client. The response contains completion status information about the request and might also contain requested content in its message body.
+
+### route
+
+Part of a URL that identifies a resource. For example, in `http://foo.com/products/id`, "/products/id" is the route.
+
+### router
+
+See [router](/en/api#router) in the API reference.
diff --git a/astro/src/content/resources/en/middleware/body-parser.md b/astro/src/content/resources/en/middleware/body-parser.md
new file mode 100644
index 0000000000..e82649a95c
--- /dev/null
+++ b/astro/src/content/resources/en/middleware/body-parser.md
@@ -0,0 +1,498 @@
+---
+title: Express body-parser middleware
+module: body-parser
+---
+
+# body-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+
+Node.js body parsing middleware.
+
+Parse incoming request bodies in a middleware before your handlers, available
+under the `req.body` property.
+
+**Note** As `req.body`'s shape is based on user-controlled input, all
+properties and values in this object are untrusted and should be validated
+before trusting. For example, `req.body.foo.toString()` may fail in multiple
+ways, for example the `foo` property may not be there or may not be a string,
+and `toString` may not be a function and instead a string or other user input.
+
+[Learn about the anatomy of an HTTP transaction in Node.js](https://nodejs.org/en/learn/http/anatomy-of-an-http-transaction).
+
+_This does not handle multipart bodies_, due to their complex and typically
+large nature. For multipart bodies, you may be interested in the following
+modules:
+
+- [busboy](https://www.npmjs.com/package/busboy#readme) and
+ [connect-busboy](https://www.npmjs.com/package/connect-busboy#readme)
+- [multiparty](https://www.npmjs.com/package/multiparty#readme) and
+ [connect-multiparty](https://www.npmjs.com/package/connect-multiparty#readme)
+- [formidable](https://www.npmjs.com/package/formidable#readme)
+- [multer](https://www.npmjs.com/package/multer#readme)
+
+This module provides the following parsers:
+
+- [JSON body parser](#bodyparserjsonoptions)
+- [Raw body parser](#bodyparserrawoptions)
+- [Text body parser](#bodyparsertextoptions)
+- [URL-encoded form body parser](#bodyparserurlencodedoptions)
+
+Other body parsers you might be interested in:
+
+- [body](https://www.npmjs.com/package/body#readme)
+- [co-body](https://www.npmjs.com/package/co-body#readme)
+
+## Installation
+
+```sh
+$ npm install body-parser
+```
+
+## API
+
+```js
+const bodyParser = require('body-parser');
+```
+
+The `bodyParser` object exposes various factories to create middlewares. All
+middlewares will populate the `req.body` property with the parsed body when
+the `Content-Type` request header matches the `type` option.
+
+The various errors returned by this module are described in the
+[errors section](#errors).
+
+### bodyParser.json([options])
+
+Returns middleware that only parses `json` and only looks at requests where
+the `Content-Type` header matches the `type` option. This parser accepts any
+Unicode encoding of the body and supports automatic inflation of `gzip`,
+`br` (brotli) and `deflate` encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`).
+
+#### Options
+
+The `json` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### defaultCharset
+
+Specify the default character set for the json content if the charset is not
+specified in the `Content-Type` header of the request. Defaults to `utf-8`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### reviver
+
+The `reviver` option is passed directly to `JSON.parse` as the second
+argument. You can find more information on this argument
+[in the MDN documentation about JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Example.3A_Using_the_reviver_parameter).
+
+##### strict
+
+When set to `true`, will only accept arrays and objects; when `false` will
+accept anything `JSON.parse` accepts. Defaults to `true`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not a
+function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `json`), a mime type (like `application/json`), or
+a mime type with a wildcard (like `*/*` or `*/json`). If a function, the `type`
+option is called as `fn(req)` and the request is parsed if it returns a truthy
+value. Defaults to `application/json`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.raw([options])
+
+Returns middleware that parses all bodies as a `Buffer` and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser supports automatic inflation of `gzip`, `br` (brotli) and `deflate`
+encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This will be a `Buffer` object
+of the body.
+
+#### Options
+
+The `raw` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function.
+If not a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this
+can be an extension name (like `bin`), a mime type (like
+`application/octet-stream`), or a mime type with a wildcard (like `*/*` or
+`application/*`). If a function, the `type` option is called as `fn(req)`
+and the request is parsed if it returns a truthy value. Defaults to
+`application/octet-stream`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.text([options])
+
+Returns middleware that parses all bodies as a string and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser supports automatic inflation of `gzip`, `br` (brotli) and `deflate`
+encodings.
+
+A new `body` string containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This will be a string of the
+body.
+
+#### Options
+
+The `text` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### defaultCharset
+
+Specify the default character set for the text content if the charset is not
+specified in the `Content-Type` header of the request. Defaults to `utf-8`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not
+a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `txt`), a mime type (like `text/plain`), or a mime
+type with a wildcard (like `*/*` or `text/*`). If a function, the `type`
+option is called as `fn(req)` and the request is parsed if it returns a
+truthy value. Defaults to `text/plain`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.urlencoded([options])
+
+Returns middleware that only parses `urlencoded` bodies and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser accepts only UTF-8 encoding of the body and supports automatic
+inflation of `gzip`, `br` (brotli) and `deflate` encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This object will contain
+key-value pairs, where the value can be a string or array (when `extended` is
+`false`), or any type (when `extended` is `true`).
+
+#### Options
+
+The `urlencoded` function takes an optional `options` object that may contain
+any of the following keys:
+
+##### extended
+
+The "extended" syntax allows for rich objects and arrays to be encoded into the
+URL-encoded format, allowing for a JSON-like experience with URL-encoded. For
+more information, please [see the qs
+library](https://www.npmjs.com/package/qs#readme).
+
+Defaults to `false`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### parameterLimit
+
+The `parameterLimit` option controls the maximum number of parameters that
+are allowed in the URL-encoded data. If a request contains more parameters
+than this value, a 413 will be returned to the client. Defaults to `1000`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not
+a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `urlencoded`), a mime type (like
+`application/x-www-form-urlencoded`), or a mime type with a wildcard (like
+`*/x-www-form-urlencoded`). If a function, the `type` option is called as
+`fn(req)` and the request is parsed if it returns a truthy value. Defaults
+to `application/x-www-form-urlencoded`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+##### defaultCharset
+
+The default charset to parse as, if not specified in content-type. Must be
+either `utf-8` or `iso-8859-1`. Defaults to `utf-8`.
+
+##### charsetSentinel
+
+Whether to let the value of the `utf8` parameter take precedence as the charset
+selector. It requires the form to contain a parameter named `utf8` with a value
+of `✓`. Defaults to `false`.
+
+##### interpretNumericEntities
+
+Whether to decode numeric entities such as `☺` when parsing an iso-8859-1
+form. Defaults to `false`.
+
+##### depth
+
+The `depth` option is used to configure the maximum depth of the `qs` library when `extended` is `true`. This allows you to limit the amount of keys that are parsed and can be useful to prevent certain types of abuse. Defaults to `32`. It is recommended to keep this value as low as possible.
+
+## Errors
+
+The middlewares provided by this module create errors using the
+[`http-errors` module](https://www.npmjs.com/package/http-errors). The errors
+will typically have a `status`/`statusCode` property that contains the suggested
+HTTP response code, an `expose` property to determine if the `message` property
+should be displayed to the client, a `type` property to determine the type of
+error without matching against the `message`, and a `body` property containing
+the read body, if available.
+
+The following are the common errors created, though any error can come through
+for various reasons.
+
+### content encoding unsupported
+
+This error will occur when the request had a `Content-Encoding` header that
+contained an encoding but the "inflation" option was set to `false`. The
+`status` property is set to `415`, the `type` property is set to
+`'encoding.unsupported'`, and the `charset` property will be set to the
+encoding that is unsupported.
+
+### entity parse failed
+
+This error will occur when the request contained an entity that could not be
+parsed by the middleware. The `status` property is set to `400`, the `type`
+property is set to `'entity.parse.failed'`, and the `body` property is set to
+the entity value that failed parsing.
+
+### entity verify failed
+
+This error will occur when the request contained an entity that could not be
+failed verification by the defined `verify` option. The `status` property is
+set to `403`, the `type` property is set to `'entity.verify.failed'`, and the
+`body` property is set to the entity value that failed verification.
+
+### request aborted
+
+This error will occur when the request is aborted by the client before reading
+the body has finished. The `received` property will be set to the number of
+bytes received before the request was aborted and the `expected` property is
+set to the number of expected bytes. The `status` property is set to `400`
+and `type` property is set to `'request.aborted'`.
+
+### request entity too large
+
+This error will occur when the request body's size is larger than the "limit"
+option. The `limit` property will be set to the byte limit and the `length`
+property will be set to the request body's length. The `status` property is
+set to `413` and the `type` property is set to `'entity.too.large'`.
+
+### request size did not match content length
+
+This error will occur when the request's length did not match the length from
+the `Content-Length` header. This typically occurs when the request is malformed,
+typically when the `Content-Length` header was calculated based on characters
+instead of bytes. The `status` property is set to `400` and the `type` property
+is set to `'request.size.invalid'`.
+
+### stream encoding should not be set
+
+This error will occur when something called the `req.setEncoding` method prior
+to this middleware. This module operates directly on bytes only and you cannot
+call `req.setEncoding` when using this module. The `status` property is set to
+`500` and the `type` property is set to `'stream.encoding.set'`.
+
+### stream is not readable
+
+This error will occur when the request is no longer readable when this middleware
+attempts to read it. This typically means something other than a middleware from
+this module read the request body already and the middleware was also configured to
+read the same request. The `status` property is set to `500` and the `type`
+property is set to `'stream.not.readable'`.
+
+### too many parameters
+
+This error will occur when the content of the request exceeds the configured
+`parameterLimit` for the `urlencoded` parser. The `status` property is set to
+`413` and the `type` property is set to `'parameters.too.many'`.
+
+### unsupported charset "BOGUS"
+
+This error will occur when the request had a charset parameter in the
+`Content-Type` header, but the `iconv-lite` module does not support it OR the
+parser does not support it. The charset is contained in the message as well
+as in the `charset` property. The `status` property is set to `415`, the
+`type` property is set to `'charset.unsupported'`, and the `charset` property
+is set to the charset that is unsupported.
+
+### unsupported content encoding "bogus"
+
+This error will occur when the request had a `Content-Encoding` header that
+contained an unsupported encoding. The encoding is contained in the message
+as well as in the `encoding` property. The `status` property is set to `415`,
+the `type` property is set to `'encoding.unsupported'`, and the `encoding`
+property is set to the encoding that is unsupported.
+
+### The input exceeded the depth
+
+This error occurs when using `bodyParser.urlencoded` with the `extended` property set to `true` and the input exceeds the configured `depth` option. The `status` property is set to `400`. It is recommended to review the `depth` option and evaluate if it requires a higher value. When the `depth` option is set to `32` (default value), the error will not be thrown.
+
+## Examples
+
+### Express/Connect top-level generic
+
+This example demonstrates adding a generic JSON and URL-encoded parser as a
+top-level middleware, which will parse the bodies of all incoming requests.
+This is the simplest setup.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// parse application/x-www-form-urlencoded
+app.use(bodyParser.urlencoded());
+
+// parse application/json
+app.use(bodyParser.json());
+
+app.use(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.write('you posted:\n');
+ res.end(String(JSON.stringify(req.body, null, 2)));
+});
+```
+
+### Express route-specific
+
+This example demonstrates adding body parsers specifically to the routes that
+need them. In general, this is the most recommended way to use body-parser with
+Express.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// create application/json parser
+const jsonParser = bodyParser.json();
+
+// create application/x-www-form-urlencoded parser
+const urlencodedParser = bodyParser.urlencoded();
+
+// POST /login gets urlencoded bodies
+app.post('/login', urlencodedParser, function (req, res) {
+ if (!req.body || !req.body.username) res.sendStatus(400);
+ res.send('welcome, ' + req.body.username);
+});
+
+// POST /api/users gets JSON bodies
+app.post('/api/users', jsonParser, function (req, res) {
+ if (!req.body) res.sendStatus(400);
+ // create user in req.body
+});
+```
+
+### Change accepted type for parsers
+
+All the parsers accept a `type` option which allows you to change the
+`Content-Type` that the middleware will parse.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// parse various different custom JSON types as JSON
+app.use(bodyParser.json({ type: 'application/*+json' }));
+
+// parse some custom thing into a Buffer
+app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }));
+
+// parse an HTML body into a string
+app.use(bodyParser.text({ type: 'text/html' }));
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/body-parser/ci.yml?branch=master&label=ci
+[ci-url]: https://github.com/expressjs/body-parser/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coverallsCoverage/github/expressjs/body-parser?branch=master
+[coveralls-url]: https://coveralls.io/r/expressjs/body-parser?branch=master
+[npm-downloads-image]: https://img.shields.io/npm/dm/body-parser
+[npm-url]: https://npmjs.com/package/body-parser
+[npm-version-image]: https://img.shields.io/npm/v/body-parser
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/body-parser/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/body-parser
diff --git a/astro/src/content/resources/en/middleware/compression.md b/astro/src/content/resources/en/middleware/compression.md
new file mode 100644
index 0000000000..6ac63fcb7a
--- /dev/null
+++ b/astro/src/content/resources/en/middleware/compression.md
@@ -0,0 +1,314 @@
+---
+title: Express compression middleware
+module: compression
+---
+
+# compression
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+[![Funding][funding-image]][funding-url]
+
+Node.js compression middleware.
+
+The following compression codings are supported:
+
+- deflate
+- gzip
+- br (brotli)
+
+**Note** Brotli is supported only since Node.js versions v11.7.0 and v10.16.0.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```bash
+$ npm install compression
+```
+
+## API
+
+```js
+var compression = require('compression');
+```
+
+### compression([options])
+
+Returns the compression middleware using the given `options`. The middleware
+will attempt to compress response bodies for all requests that traverse through
+the middleware, based on the given `options`.
+
+This middleware will never compress responses that include a `Cache-Control`
+header with the [`no-transform` directive](https://tools.ietf.org/html/rfc7234#section-5.2.2.4),
+as compressing will transform the body.
+
+#### Options
+
+`compression()` accepts these properties in the options object. In addition to
+those listed below, [zlib](https://nodejs.org/api/zlib.html) options may be
+passed in to the options object or
+[brotli](https://nodejs.org/api/zlib.html#zlib_class_brotlioptions) options.
+
+##### chunkSize
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_CHUNK`, or `16384`.
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### filter
+
+Type: `Function`
+
+A function to decide if the response should be considered for compression.
+This function is called as `filter(req, res)` and is expected to return
+`true` to consider the response for compression, or `false` to not compress
+the response.
+
+The default filter function uses the [compressible](https://www.npmjs.com/package/compressible)
+module to determine if `res.getHeader('Content-Type')` is compressible.
+
+##### level
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_COMPRESSION`, or `-1`
+
+The level of zlib compression to apply to responses. A higher level will result
+in better compression, but will take longer to complete. A lower level will
+result in less compression, but will be much faster.
+
+This is an integer in the range of `0` (no compression) to `9` (maximum
+compression). The special value `-1` can be used to mean the "default
+compression level", which is a default compromise between speed and
+compression (currently equivalent to level 6).
+
+- `-1` Default compression level (also `zlib.constants.Z_DEFAULT_COMPRESSION`).
+- `0` No compression (also `zlib.constants.Z_NO_COMPRESSION`).
+- `1` Fastest compression (also `zlib.constants.Z_BEST_SPEED`).
+- `2`
+- `3`
+- `4`
+- `5`
+- `6` (currently what `zlib.constants.Z_DEFAULT_COMPRESSION` points to).
+- `7`
+- `8`
+- `9` Best compression (also `zlib.constants.Z_BEST_COMPRESSION`).
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### memLevel
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_MEMLEVEL`, or `8`
+
+This specifies how much memory should be allocated for the internal compression
+state and is an integer in the range of `1` (minimum level) and `9` (maximum
+level).
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### brotli
+
+Type: `Object`
+
+This specifies the options for configuring Brotli. See [Node.js documentation](https://nodejs.org/api/zlib.html#class-brotlioptions) for a complete list of available options.
+
+##### strategy
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_STRATEGY`
+
+This is used to tune the compression algorithm. This value only affects the
+compression ratio, not the correctness of the compressed output, even if it
+is not set appropriately.
+
+- `zlib.constants.Z_DEFAULT_STRATEGY` Use for normal data.
+- `zlib.constants.Z_FILTERED` Use for data produced by a filter (or predictor).
+ Filtered data consists mostly of small values with a somewhat random
+ distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect is to force more Huffman coding and less
+ string matching; it is somewhat intermediate between `zlib.constants.Z_DEFAULT_STRATEGY`
+ and `zlib.constants.Z_HUFFMAN_ONLY`.
+- `zlib.constants.Z_FIXED` Use to prevent the use of dynamic Huffman codes, allowing
+ for a simpler decoder for special applications.
+- `zlib.constants.Z_HUFFMAN_ONLY` Use to force Huffman encoding only (no string match).
+- `zlib.constants.Z_RLE` Use to limit match distances to one (run-length encoding).
+ This is designed to be almost as fast as `zlib.constants.Z_HUFFMAN_ONLY`, but give
+ better compression for PNG image data.
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### threshold
+
+Type: `Number` or `String`
+Default: `1kb`
+
+The byte threshold for the response body size before compression is considered
+for the response. This is a number of bytes or any string
+accepted by the [bytes](https://www.npmjs.com/package/bytes) module.
+
+**Note** this is only an advisory setting; if the response size cannot be determined
+at the time the response headers are written, then it is assumed the response is
+_over_ the threshold. To guarantee the response size can be determined, be sure
+set a `Content-Length` response header.
+
+##### windowBits
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_WINDOWBITS`, or `15`
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### enforceEncoding
+
+Type: `String`
+Default: `identity`
+
+This is the default encoding to use when the client does not specify an encoding in the request's [Accept-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) header.
+
+#### .filter
+
+The default `filter` function. This is used to construct a custom filter
+function that is an extension of the default function.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+app.use(compression({ filter: shouldCompress }));
+
+function shouldCompress(req, res) {
+ if (req.headers['x-no-compression']) {
+ // don't compress responses with this request header
+ return false;
+ }
+
+ // fallback to standard filter function
+ return compression.filter(req, res);
+}
+```
+
+### res.flush
+
+This module adds a `res.flush()` method to force the partially-compressed
+response to be flushed to the client.
+
+## Examples
+
+### express
+
+When using this module with express, simply `app.use` the module as
+high as you like. Requests that pass through the middleware will be compressed.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress all responses
+app.use(compression());
+
+// add all routes
+```
+
+### Node.js HTTP server
+
+```js
+var compression = require('compression')({ threshold: 0 });
+var http = require('http');
+
+function createServer(fn) {
+ return http.createServer(function (req, res) {
+ compression(req, res, function (err) {
+ if (err) {
+ res.statusCode = err.status || 500;
+ res.end(err.message);
+ return;
+ }
+
+ fn(req, res);
+ });
+ });
+}
+
+var server = createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello world!');
+});
+
+server.listen(3000, () => {
+ console.log('> Listening at http://localhost:3000');
+});
+```
+
+### Server-Sent Events
+
+Because of the nature of compression this module does not work out of the box
+with server-sent events. To compress content, a window of the output needs to
+be buffered up in order to get good compression. Typically when using server-sent
+events, there are certain block of data that need to reach the client.
+
+You can achieve this by calling `res.flush()` when you need the data written to
+actually make it to the client.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress responses
+app.use(compression());
+
+// server-sent event stream
+app.get('/events', function (req, res) {
+ res.setHeader('Content-Type', 'text/event-stream');
+ res.setHeader('Cache-Control', 'no-cache');
+
+ // send a ping approx every 2 seconds
+ var timer = setInterval(function () {
+ res.write('data: ping\n\n');
+
+ // !!! this is the important part
+ res.flush();
+ }, 2000);
+
+ res.on('close', function () {
+ clearInterval(timer);
+ });
+});
+```
+
+## Contributing
+
+The Express.js project welcomes all constructive contributions. Contributions take many forms,
+from code for bug fixes and enhancements, to additions and fixes to documentation, additional
+tests, triaging incoming pull requests and issues, and more!
+
+See the [Contributing Guide](https://github.com/expressjs/express/blob/master/Contributing.md) for more technical details on contributing.
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://badgen.net/npm/v/compression
+[npm-url]: https://npmjs.org/package/compression
+[downloads-image]: https://badgen.net/npm/dm/compression
+[downloads-url]: https://npmcharts.com/compare/compression?minimal=true
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/compression/master?label=CI
+[github-actions-ci-url]: https://github.com/expressjs/compression/actions?query=workflow%3Aci
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/compression/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/compression
+[funding-url]: https://opencollective.com/express
+[funding-image]: https://badgen.net/badge/icon/sponsor/pink?icon=github&label=Open%20Collective
diff --git a/astro/src/content/resources/en/middleware/cookie-parser.md b/astro/src/content/resources/en/middleware/cookie-parser.md
new file mode 100644
index 0000000000..2a59496387
--- /dev/null
+++ b/astro/src/content/resources/en/middleware/cookie-parser.md
@@ -0,0 +1,124 @@
+---
+title: Express cookie-parser middleware
+module: cookie-parser
+---
+
+# cookie-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Parse `Cookie` header and populate `req.cookies` with an object keyed by the
+cookie names. Optionally you may enable signed cookie support by passing a
+`secret` string, which assigns `req.secret` so it may be used by other
+middleware.
+
+## Installation
+
+```sh
+$ npm install cookie-parser
+```
+
+## API
+
+```js
+var cookieParser = require('cookie-parser');
+```
+
+### cookieParser(secret, options)
+
+Create a new cookie parser middleware function using the given `secret` and
+`options`.
+
+- `secret` a string or array used for signing cookies. This is optional and if
+ not specified, will not parse signed cookies. If a string is provided, this
+ is used as the secret. If an array is provided, an attempt will be made to
+ unsign the cookie with each secret in order.
+- `options` an object that is passed to `cookie.parse` as the second option. See
+ [cookie](https://www.npmjs.org/package/cookie) for more information.
+ - `decode` a function to decode the value of the cookie
+
+The middleware will parse the `Cookie` header on the request and expose the
+cookie data as the property `req.cookies` and, if a `secret` was provided, as
+the property `req.signedCookies`. These properties are name value pairs of the
+cookie name to cookie value.
+
+When `secret` is provided, this module will unsign and validate any signed cookie
+values and move those name value pairs from `req.cookies` into `req.signedCookies`.
+A signed cookie is a cookie that has a value prefixed with `s:`. Signed cookies
+that fail signature validation will have the value `false` instead of the tampered
+value.
+
+In addition, this module supports special "JSON cookies". These are cookie where
+the value is prefixed with `j:`. When these values are encountered, the value will
+be exposed as the result of `JSON.parse`. If parsing fails, the original value will
+remain.
+
+### cookieParser.JSONCookie(str)
+
+Parse a cookie value as a JSON cookie. This will return the parsed JSON value
+if it was a JSON cookie, otherwise, it will return the passed value.
+
+### cookieParser.JSONCookies(cookies)
+
+Given an object, this will iterate over the keys and call `JSONCookie` on each
+value, replacing the original value with the parsed value. This returns the
+same object that was passed in.
+
+### cookieParser.signedCookie(str, secret)
+
+Parse a cookie value as a signed cookie. This will return the parsed unsigned
+value if it was a signed cookie and the signature was valid. If the value was
+not signed, the original value is returned. If the value was signed but the
+signature could not be validated, `false` is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+### cookieParser.signedCookies(cookies, secret)
+
+Given an object, this will iterate over the keys and check if any value is a
+signed cookie. If it is a signed cookie and the signature is valid, the key
+will be deleted from the object and added to the new object that is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+## Example
+
+```js
+var express = require('express');
+var cookieParser = require('cookie-parser');
+
+var app = express();
+app.use(cookieParser());
+
+app.get('/', function (req, res) {
+ // Cookies that have not been signed
+ console.log('Cookies: ', req.cookies);
+
+ // Cookies that have been signed
+ console.log('Signed Cookies: ', req.signedCookies);
+});
+
+app.listen(8080);
+
+// curl command that sends an HTTP request with two cookies
+// curl http://127.0.0.1:8080 --cookie "Cho=Kim;Greet=Hello"
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/cookie-parser/master?label=ci
+[ci-url]: https://github.com/expressjs/cookie-parser/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/cookie-parser/master
+[coveralls-url]: https://coveralls.io/r/expressjs/cookie-parser?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/cookie-parser
+[npm-url]: https://npmjs.org/package/cookie-parser
+[npm-version-image]: https://badgen.net/npm/v/cookie-parser
diff --git a/astro/src/content/resources/en/middleware/cookie-session.md b/astro/src/content/resources/en/middleware/cookie-session.md
new file mode 100644
index 0000000000..2d6d1f885b
--- /dev/null
+++ b/astro/src/content/resources/en/middleware/cookie-session.md
@@ -0,0 +1,124 @@
+---
+title: Express cookie-session middleware
+module: cookie-session
+---
+
+# cookie-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Parse `Cookie` header and populate `req.cookies` with an object keyed by the
+cookie names. Optionally you may enable signed cookie support by passing a
+`secret` string, which assigns `req.secret` so it may be used by other
+middleware.
+
+## Installation
+
+```sh
+$ npm install cookie-parser
+```
+
+## API
+
+```js
+var cookieParser = require('cookie-parser');
+```
+
+### cookieParser(secret, options)
+
+Create a new cookie parser middleware function using the given `secret` and
+`options`.
+
+- `secret` a string or array used for signing cookies. This is optional and if
+ not specified, will not parse signed cookies. If a string is provided, this
+ is used as the secret. If an array is provided, an attempt will be made to
+ unsign the cookie with each secret in order.
+- `options` an object that is passed to `cookie.parse` as the second option. See
+ [cookie](https://www.npmjs.org/package/cookie) for more information.
+ - `decode` a function to decode the value of the cookie
+
+The middleware will parse the `Cookie` header on the request and expose the
+cookie data as the property `req.cookies` and, if a `secret` was provided, as
+the property `req.signedCookies`. These properties are name value pairs of the
+cookie name to cookie value.
+
+When `secret` is provided, this module will unsign and validate any signed cookie
+values and move those name value pairs from `req.cookies` into `req.signedCookies`.
+A signed cookie is a cookie that has a value prefixed with `s:`. Signed cookies
+that fail signature validation will have the value `false` instead of the tampered
+value.
+
+In addition, this module supports special "JSON cookies". These are cookie where
+the value is prefixed with `j:`. When these values are encountered, the value will
+be exposed as the result of `JSON.parse`. If parsing fails, the original value will
+remain.
+
+### cookieParser.JSONCookie(str)
+
+Parse a cookie value as a JSON cookie. This will return the parsed JSON value
+if it was a JSON cookie, otherwise, it will return the passed value.
+
+### cookieParser.JSONCookies(cookies)
+
+Given an object, this will iterate over the keys and call `JSONCookie` on each
+value, replacing the original value with the parsed value. This returns the
+same object that was passed in.
+
+### cookieParser.signedCookie(str, secret)
+
+Parse a cookie value as a signed cookie. This will return the parsed unsigned
+value if it was a signed cookie and the signature was valid. If the value was
+not signed, the original value is returned. If the value was signed but the
+signature could not be validated, `false` is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+### cookieParser.signedCookies(cookies, secret)
+
+Given an object, this will iterate over the keys and check if any value is a
+signed cookie. If it is a signed cookie and the signature is valid, the key
+will be deleted from the object and added to the new object that is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+## Example
+
+```js
+var express = require('express');
+var cookieParser = require('cookie-parser');
+
+var app = express();
+app.use(cookieParser());
+
+app.get('/', function (req, res) {
+ // Cookies that have not been signed
+ console.log('Cookies: ', req.cookies);
+
+ // Cookies that have been signed
+ console.log('Signed Cookies: ', req.signedCookies);
+});
+
+app.listen(8080);
+
+// curl command that sends an HTTP request with two cookies
+// curl http://127.0.0.1:8080 --cookie "Cho=Kim;Greet=Hello"
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/cookie-parser/master?label=ci
+[ci-url]: https://github.com/expressjs/cookie-parser/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/cookie-parser/master
+[coveralls-url]: https://coveralls.io/r/expressjs/cookie-parser?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/cookie-parser
+[npm-url]: https://npmjs.org/package/cookie-parser
+[npm-version-image]: https://badgen.net/npm/v/cookie-parser
diff --git a/astro/src/content/resources/en/middleware/cors.md b/astro/src/content/resources/en/middleware/cors.md
new file mode 100644
index 0000000000..55d70922cb
--- /dev/null
+++ b/astro/src/content/resources/en/middleware/cors.md
@@ -0,0 +1,261 @@
+---
+title: Express cors middleware
+module: cors
+---
+
+# cors
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+CORS is a [Node.js](https://nodejs.org/en/) package for providing a [Connect](https://github.com/senchalabs/connect)/[Express](https://expressjs.com/) middleware that can be used to enable [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS) with various options.
+
+- [Installation](#installation)
+- [Usage](#usage)
+ - [Simple Usage](#simple-usage-enable-all-cors-requests)
+ - [Enable CORS for a Single Route](#enable-cors-for-a-single-route)
+ - [Configuring CORS](#configuring-cors)
+ - [Configuring CORS w/ Dynamic Origin](#configuring-cors-w-dynamic-origin)
+ - [Enabling CORS Pre-Flight](#enabling-cors-pre-flight)
+ - [Customizing CORS Settings Dynamically per Request](#customizing-cors-settings-dynamically-per-request)
+- [Configuration Options](#configuration-options)
+- [License](#license)
+- [Original Author](#original-author)
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/downloading-and-installing-packages-locally):
+
+```sh
+$ npm install cors
+```
+
+## Usage
+
+### Simple Usage (Enable _All_ CORS Requests)
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.use(cors());
+
+app.get('/products/:id', function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for all origins!' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Enable CORS for a Single Route
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.get('/products/:id', cors(), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for a Single Route' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Configuring CORS
+
+See the [configuration options](#configuration-options) for details.
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+var corsOptions = {
+ origin: 'http://example.com',
+ optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
+};
+
+app.get('/products/:id', cors(corsOptions), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for only example.com.' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Configuring CORS w/ Dynamic Origin
+
+This module supports validating the origin dynamically using a function provided
+to the `origin` option. This function will be passed a string that is the origin
+(or `undefined` if the request has no origin), and a `callback` with the signature
+`callback(error, origin)`.
+
+The `origin` argument to the callback can be any value allowed for the `origin`
+option of the middleware, except a function. See the
+[configuration options](#configuration-options) section for more information on all
+the possible value types.
+
+This function is designed to allow the dynamic loading of allowed origin(s) from
+a backing datasource, like a database.
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+var corsOptions = {
+ origin: function (origin, callback) {
+ // db.loadOrigins is an example call to load
+ // a list of origins from a backing database
+ db.loadOrigins(function (error, origins) {
+ callback(error, origins);
+ });
+ },
+};
+
+app.get('/products/:id', cors(corsOptions), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for an allowed domain.' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Enabling CORS Pre-Flight
+
+Certain CORS requests are considered 'complex' and require an initial
+`OPTIONS` request (called the "pre-flight request"). An example of a
+'complex' CORS request is one that uses an HTTP verb other than
+GET/HEAD/POST (such as DELETE) or that uses custom headers. To enable
+pre-flighting, you must add a new OPTIONS handler for the route you want
+to support:
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.options('/products/:id', cors()); // enable pre-flight request for DELETE request
+app.del('/products/:id', cors(), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for all origins!' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+You can also enable pre-flight across-the-board like so:
+
+```javascript
+app.options('*', cors()); // include before other routes
+```
+
+NOTE: When using this middleware as an application level middleware (for
+example, `app.use(cors())`), pre-flight requests are already handled for all
+routes.
+
+### Customizing CORS Settings Dynamically per Request
+
+For APIs that require different CORS configurations for specific routes or requests, you can dynamically generate CORS options based on the incoming request. The `cors` middleware allows you to achieve this by passing a function instead of static options. This function is called for each incoming request and must use the callback pattern to return the appropriate CORS options.
+
+The function accepts:
+
+1. **`req`**:
+ - The incoming request object.
+
+2. **`callback(error, corsOptions)`**:
+ - A function used to return the computed CORS options.
+ - **Arguments**:
+ - **`error`**: Pass `null` if there’s no error, or an error object to indicate a failure.
+ - **`corsOptions`**: An object specifying the CORS policy for the current request.
+
+Here’s an example that handles both public routes and restricted, credential-sensitive routes:
+
+```javascript
+var dynamicCorsOptions = function (req, callback) {
+ var corsOptions;
+ if (req.path.startsWith('/auth/connect/')) {
+ corsOptions = {
+ origin: 'http://mydomain.com', // Allow only a specific origin
+ credentials: true, // Enable cookies and credentials
+ };
+ } else {
+ corsOptions = { origin: '*' }; // Allow all origins for other routes
+ }
+ callback(null, corsOptions);
+};
+
+app.use(cors(dynamicCorsOptions));
+
+app.get('/auth/connect/twitter', function (req, res) {
+ res.send('CORS dynamically applied for Twitter authentication.');
+});
+
+app.get('/public', function (req, res) {
+ res.send('Public data with open CORS.');
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+## Configuration Options
+
+- `origin`: Configures the **Access-Control-Allow-Origin** CORS header. Possible values:
+ - `Boolean` - set `origin` to `true` to reflect the [request origin](https://datatracker.ietf.org/doc/html/draft-abarth-origin-09), as defined by `req.header('Origin')`, or set it to `false` to disable CORS.
+ - `String` - set `origin` to a specific origin. For example, if you set it to
+ - `"http://example.com"` only requests from "http://example.com" will be allowed.
+ - `"*"` for all domains to be allowed.
+ - `RegExp` - set `origin` to a regular expression pattern which will be used to test the request origin. If it's a match, the request origin will be reflected. For example the pattern `/example\.com$/` will reflect any request that is coming from an origin ending with "example.com".
+ - `Array` - set `origin` to an array of valid origins. Each origin can be a `String` or a `RegExp`. For example `["http://example1.com", /\.example2\.com$/]` will accept any request from "http://example1.com" or from a subdomain of "example2.com".
+ - `Function` - set `origin` to a function implementing some custom logic. The function takes the request origin as the first parameter and a callback (called as `callback(err, origin)`, where `origin` is a non-function value of the `origin` option) as the second.
+- `methods`: Configures the **Access-Control-Allow-Methods** CORS header. Expects a comma-delimited string (ex: 'GET,PUT,POST') or an array (ex: `['GET', 'PUT', 'POST']`).
+- `allowedHeaders`: Configures the **Access-Control-Allow-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Type,Authorization') or an array (ex: `['Content-Type', 'Authorization']`). If not specified, defaults to reflecting the headers specified in the request's **Access-Control-Request-Headers** header.
+- `exposedHeaders`: Configures the **Access-Control-Expose-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Range,X-Content-Range') or an array (ex: `['Content-Range', 'X-Content-Range']`). If not specified, no custom headers are exposed.
+- `credentials`: Configures the **Access-Control-Allow-Credentials** CORS header. Set to `true` to pass the header, otherwise it is omitted.
+- `maxAge`: Configures the **Access-Control-Max-Age** CORS header. Set to an integer to pass the header, otherwise it is omitted.
+- `preflightContinue`: Pass the CORS preflight response to the next handler.
+- `optionsSuccessStatus`: Provides a status code to use for successful `OPTIONS` requests, since some legacy browsers (IE11, various SmartTVs) choke on `204`.
+
+The default configuration is the equivalent of:
+
+```json
+{
+ "origin": "*",
+ "methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
+ "preflightContinue": false,
+ "optionsSuccessStatus": 204
+}
+```
+
+For details on the effect of each CORS header, read [this](https://web.dev/articles/cross-origin-resource-sharing) article.
+
+## License
+
+[MIT License](http://www.opensource.org/licenses/mit-license.php)
+
+## Original Author
+
+[Troy Goode](https://github.com/TroyGoode) ([troygoode@gmail.com](mailto:troygoode@gmail.com))
+
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/cors/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/cors?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/cors.svg
+[downloads-url]: https://npmjs.com/package/cors
+[github-actions-ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/cors/ci.yml?branch=master&label=ci
+[github-actions-ci-url]: https://github.com/expressjs/cors?query=workflow%3Aci
+[npm-image]: https://img.shields.io/npm/v/cors.svg
+[npm-url]: https://npmjs.com/package/cors
diff --git a/astro/src/content/resources/en/middleware/errorhandler.md b/astro/src/content/resources/en/middleware/errorhandler.md
new file mode 100644
index 0000000000..20df618320
--- /dev/null
+++ b/astro/src/content/resources/en/middleware/errorhandler.md
@@ -0,0 +1,133 @@
+---
+title: Express errorhandler middleware
+module: errorhandler
+---
+
+# errorhandler
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Development-only error handler middleware.
+
+This middleware is only intended to be used in a development environment, as
+the _full error stack traces and internal details of any object passed to this
+module_ will be sent back to the client when an error occurs.
+
+When an object is provided to Express as an error, this module will display
+as much about this object as possible, and will do so by using content negotiation
+for the response between HTML, JSON, and plain text.
+
+- When the object is a standard `Error` object, the string provided by the
+ `stack` property will be returned in HTML/text responses.
+- When the object is a non-`Error` object, the result of
+ [util.inspect](https://nodejs.org/api/util.html#util_util_inspect_object_options)
+ will be returned in HTML/text responses.
+- For JSON responses, the result will be an object with all enumerable properties
+ from the object in the response.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install errorhandler
+```
+
+## API
+
+
+
+```js
+var errorhandler = require('errorhandler');
+```
+
+### errorhandler(options)
+
+Create new middleware to handle errors and respond with content negotiation.
+
+#### Options
+
+Error handler accepts these properties in the options object.
+
+##### log
+
+Provide a function to be called with the error and a string representation of
+the error. Can be used to write the error to any desired location, or set to
+`false` to only send the error back in the response. Called as
+`log(err, str, req, res)` where `err` is the `Error` object, `str` is a string
+representation of the error, `req` is the request object and `res` is the
+response object (note, this function is invoked _after_ the response has been
+written).
+
+The default value for this option is `true` unless `process.env.NODE_ENV === 'test'`.
+
+Possible values:
+
+- `true`: Log errors using `console.error(str)`.
+- `false`: Only send the error back in the response.
+- A function: pass the error to a function for handling.
+
+## Examples
+
+### Simple example
+
+Basic example of adding this middleware as the error handler only in development
+with `connect` (`express` also can be used in this example).
+
+```js
+var connect = require('connect');
+var errorhandler = require('errorhandler');
+
+var app = connect();
+
+// assumes NODE_ENV is set by the user
+if (process.env.NODE_ENV === 'development') {
+ // only use in development
+ app.use(errorhandler());
+}
+```
+
+### Custom output location
+
+Sometimes you may want to output the errors to a different location than STDERR
+during development, like a system notification, for example.
+
+
+
+```js
+var connect = require('connect');
+var errorhandler = require('errorhandler');
+var notifier = require('node-notifier');
+
+var app = connect();
+
+// assumes NODE_ENV is set by the user
+if (process.env.NODE_ENV === 'development') {
+ // only use in development
+ app.use(errorhandler({ log: errorNotification }));
+}
+
+function errorNotification(err, str, req) {
+ var title = 'Error in ' + req.method + ' ' + req.url;
+
+ notifier.notify({
+ title: title,
+ message: str,
+ });
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/errorhandler/master
+[coveralls-url]: https://coveralls.io/r/expressjs/errorhandler?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/errorhandler
+[npm-url]: https://npmjs.org/package/errorhandler
+[npm-version-image]: https://badgen.net/npm/v/errorhandler
diff --git a/astro/src/content/resources/en/middleware/method-override.md b/astro/src/content/resources/en/middleware/method-override.md
new file mode 100644
index 0000000000..7b97ab855e
--- /dev/null
+++ b/astro/src/content/resources/en/middleware/method-override.md
@@ -0,0 +1,187 @@
+---
+title: Express method-override middleware
+module: method-override
+---
+
+# method-override
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][travis-image]][travis-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Lets you use HTTP verbs such as PUT or DELETE in places where the client doesn't support it.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install method-override
+```
+
+## API
+
+**NOTE** It is very important that this module is used **before** any module that
+needs to know the method of the request (for example, it _must_ be used prior to
+the `csurf` module).
+
+### methodOverride(getter, options)
+
+Create a new middleware function to override the `req.method` property with a new
+value. This value will be pulled from the provided `getter`.
+
+- `getter` - The getter to use to look up the overridden request method for the request. (default: `X-HTTP-Method-Override`)
+- `options.methods` - The allowed methods the original request must be in to check for a method override value. (default: `['POST']`)
+
+If the found method is supported by node.js core, then `req.method` will be set to
+this value, as if it has originally been that value. The previous `req.method`
+value will be stored in `req.originalMethod`.
+
+#### getter
+
+This is the method of getting the override value from the request. If a function is provided,
+the `req` is passed as the first argument, the `res` as the second argument and the method is
+expected to be returned. If a string is provided, the string is used to look up the method
+with the following rules:
+
+- If the string starts with `X-`, then it is treated as the name of a header and that header
+ is used for the method override. If the request contains the same header multiple times, the
+ first occurrence is used.
+- All other strings are treated as a key in the URL query string.
+
+#### options.methods
+
+This allows the specification of what methods(s) the request _MUST_ be in in order to check for
+the method override value. This defaults to only `POST` methods, which is the only method the
+override should arrive in. More methods may be specified here, but it may introduce security
+issues and cause weird behavior when requests travel through caches. This value is an array
+of methods in upper-case. `null` can be specified to allow all methods.
+
+## Examples
+
+### override using a header
+
+To use a header to override the method, specify the header name
+as a string argument to the `methodOverride` function. To then make
+the call, send a `POST` request to a URL with the overridden method
+as the value of that header. This method of using a header would
+typically be used in conjunction with `XMLHttpRequest` on implementations
+that do not support the method you are trying to use.
+
+```js
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// override with the X-HTTP-Method-Override header in the request
+app.use(methodOverride('X-HTTP-Method-Override'));
+```
+
+Example call with header override using `XMLHttpRequest`:
+
+
+
+```js
+const xhr = new XMLHttpRequest();
+xhr.onload = onload;
+xhr.open('post', '/resource', true);
+xhr.setRequestHeader('X-HTTP-Method-Override', 'DELETE');
+xhr.send();
+
+function onload() {
+ alert('got response: ' + this.responseText);
+}
+```
+
+### override using a query value
+
+To use a query string value to override the method, specify the query
+string key as a string argument to the `methodOverride` function. To
+then make the call, send a `POST` request to a URL with the overridden
+method as the value of that query string key. This method of using a
+query value would typically be used in conjunction with plain HTML
+`
+```
+
+### multiple format support
+
+```js
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// override with different headers; last one takes precedence
+app.use(methodOverride('X-HTTP-Method')); // Microsoft
+app.use(methodOverride('X-HTTP-Method-Override')); // Google/GData
+app.use(methodOverride('X-Method-Override')); // IBM
+```
+
+### custom logic
+
+You can implement any kind of custom logic with a function for the `getter`. The following
+implements the logic for looking in `req.body` that was in `method-override@1`:
+
+```js
+const bodyParser = require('body-parser');
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// NOTE: when using req.body, you must fully parse the request body
+// before you call methodOverride() in your middleware stack,
+// otherwise req.body will not be populated.
+app.use(bodyParser.urlencoded());
+app.use(
+ methodOverride(function (req, res) {
+ if (req.body && typeof req.body === 'object' && '_method' in req.body) {
+ // look in urlencoded POST bodies and delete it
+ const method = req.body._method;
+ delete req.body._method;
+ return method;
+ }
+ })
+);
+```
+
+Example call with query override using HTML `
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/method-override.svg
+[npm-url]: https://npmjs.org/package/method-override
+[travis-image]: https://img.shields.io/travis/expressjs/method-override/master.svg
+[travis-url]: https://travis-ci.org/expressjs/method-override
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/method-override/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/method-override?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/method-override.svg
+[downloads-url]: https://npmjs.org/package/method-override
diff --git a/astro/src/content/resources/en/middleware/morgan.md b/astro/src/content/resources/en/middleware/morgan.md
new file mode 100644
index 0000000000..5319d93d57
--- /dev/null
+++ b/astro/src/content/resources/en/middleware/morgan.md
@@ -0,0 +1,458 @@
+---
+title: Express morgan middleware
+module: morgan
+---
+
+# morgan
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+HTTP request logger middleware for node.js
+
+> Named after [Dexter](http://en.wikipedia.org/wiki/Dexter_Morgan), a show you should not watch until completion.
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install morgan
+```
+
+## API
+
+
+
+```js
+var morgan = require('morgan');
+```
+
+### morgan(format, options)
+
+Create a new morgan logger middleware function using the given `format` and `options`.
+The `format` argument may be a string of a predefined name (see below for the names),
+a string of a format string, or a function that will produce a log entry.
+
+The `format` function will be called with three arguments `tokens`, `req`, and `res`,
+where `tokens` is an object with all defined tokens, `req` is the HTTP request and `res`
+is the HTTP response. The function is expected to return a string that will be the log
+line, or `undefined` / `null` to skip logging.
+
+#### Using a predefined format string
+
+
+
+```js
+morgan('tiny');
+```
+
+#### Using format string of predefined tokens
+
+
+
+```js
+morgan(':method :url :status :res[content-length] - :response-time ms');
+```
+
+#### Using a custom format function
+
+
+
+```js
+morgan(function (tokens, req, res) {
+ return [
+ tokens.method(req, res),
+ tokens.url(req, res),
+ tokens.status(req, res),
+ tokens.res(req, res, 'content-length'),
+ '-',
+ tokens['response-time'](req, res),
+ 'ms',
+ ].join(' ');
+});
+```
+
+#### Options
+
+Morgan accepts these properties in the options object.
+
+##### immediate
+
+Write log line on request instead of response. This means that a requests will
+be logged even if the server crashes, _but data from the response (like the
+response code, content length, etc.) cannot be logged_.
+
+##### skip
+
+Function to determine if logging is skipped, defaults to `false`. This function
+will be called as `skip(req, res)`.
+
+
+
+```js
+// EXAMPLE: only log error responses
+morgan('combined', {
+ skip: function (req, res) {
+ return res.statusCode < 400;
+ },
+});
+```
+
+##### stream
+
+Output stream for writing log lines, defaults to `process.stdout`.
+
+#### Predefined Formats
+
+There are various pre-defined formats provided:
+
+##### combined
+
+Standard Apache combined log output.
+
+```
+:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"
+# will output
+::1 - - [27/Nov/2024:06:21:42 +0000] "GET /combined HTTP/1.1" 200 2 "-" "curl/8.7.1"
+```
+
+##### common
+
+Standard Apache common log output.
+
+```
+:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length]
+# will output
+::1 - - [27/Nov/2024:06:21:46 +0000] "GET /common HTTP/1.1" 200 2
+```
+
+##### dev
+
+Concise output colored by response status for development use. The `:status`
+token will be colored green for success codes, red for server error codes,
+yellow for client error codes, cyan for redirection codes, and uncolored
+for information codes.
+
+```
+:method :url :status :response-time ms - :res[content-length]
+# will output
+GET /dev 200 0.224 ms - 2
+```
+
+##### short
+
+Shorter than default, also including response time.
+
+```
+:remote-addr :remote-user :method :url HTTP/:http-version :status :res[content-length] - :response-time ms
+# will output
+::1 - GET /short HTTP/1.1 200 2 - 0.283 ms
+```
+
+##### tiny
+
+The minimal output.
+
+```
+:method :url :status :res[content-length] - :response-time ms
+# will output
+GET /tiny 200 2 - 0.188 ms
+```
+
+#### Tokens
+
+##### Creating new tokens
+
+To define a token, simply invoke `morgan.token()` with the name and a callback function.
+This callback function is expected to return a string value. The value returned is then
+available as ":type" in this case:
+
+
+
+```js
+morgan.token('type', function (req, res) {
+ return req.headers['content-type'];
+});
+```
+
+Calling `morgan.token()` using the same name as an existing token will overwrite that
+token definition.
+
+The token function is expected to be called with the arguments `req` and `res`, representing
+the HTTP request and HTTP response. Additionally, the token can accept further arguments of
+it's choosing to customize behavior.
+
+##### :date[format]
+
+The current date and time in UTC. The available formats are:
+
+- `clf` for the common log format (`"10/Oct/2000:13:55:36 +0000"`)
+- `iso` for the common ISO 8601 date time format (`2000-10-10T13:55:36.000Z`)
+- `web` for the common RFC 1123 date time format (`Tue, 10 Oct 2000 13:55:36 GMT`)
+
+If no format is given, then the default is `web`.
+
+##### :http-version
+
+The HTTP version of the request.
+
+##### :method
+
+The HTTP method of the request.
+
+##### :pid
+
+The process ID of the Node.js process handling the request.
+
+##### :referrer
+
+The Referrer header of the request. This will use the standard mis-spelled Referer header if exists, otherwise Referrer.
+
+##### :remote-addr
+
+The remote address of the request. This will use `req.ip`, otherwise the standard `req.connection.remoteAddress` value (socket address).
+
+##### :remote-user
+
+The user authenticated as part of Basic auth for the request.
+
+##### :req[header]
+
+The given `header` of the request. If the header is not present, the
+value will be displayed as `"-"` in the log.
+
+##### :res[header]
+
+The given `header` of the response. If the header is not present, the
+value will be displayed as `"-"` in the log.
+
+##### :response-time[digits]
+
+The time between the request coming into `morgan` and when the response
+headers are written, in milliseconds.
+
+The `digits` argument is a number that specifies the number of digits to
+include on the number, defaulting to `3`, which provides microsecond precision.
+
+##### :status
+
+The status code of the response.
+
+If the request/response cycle completes before a response was sent to the
+client (for example, the TCP socket closed prematurely by a client aborting
+the request), then the status will be empty (displayed as `"-"` in the log).
+
+##### :total-time[digits]
+
+The time between the request coming into `morgan` and when the response
+has finished being written out to the connection, in milliseconds.
+
+The `digits` argument is a number that specifies the number of digits to
+include on the number, defaulting to `3`, which provides microsecond precision.
+
+##### :url
+
+The URL of the request. This will use `req.originalUrl` if exists, otherwise `req.url`.
+
+##### :user-agent
+
+The contents of the User-Agent header of the request.
+
+### morgan.compile(format)
+
+Compile a format string into a `format` function for use by `morgan`. A format string
+is a string that represents a single log line and can utilize token syntax.
+Tokens are references by `:token-name`. If tokens accept arguments, they can
+be passed using `[]`, for example: `:token-name[pretty]` would pass the string
+`'pretty'` as an argument to the token `token-name`.
+
+The function returned from `morgan.compile` takes three arguments `tokens`, `req`, and
+`res`, where `tokens` is object with all defined tokens, `req` is the HTTP request and
+`res` is the HTTP response. The function will return a string that will be the log line,
+or `undefined` / `null` to skip logging.
+
+Normally formats are defined using `morgan.format(name, format)`, but for certain
+advanced uses, this compile function is directly available.
+
+## Examples
+
+### express/connect
+
+Sample app that will log all request in the Apache combined format to STDOUT
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+
+var app = express();
+
+app.use(morgan('combined'));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### vanilla http server
+
+Sample app that will log all request in the Apache combined format to STDOUT
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var morgan = require('morgan');
+
+// create "middleware"
+var logger = morgan('combined');
+
+http.createServer(function (req, res) {
+ var done = finalhandler(req, res);
+ logger(req, res, function (err) {
+ if (err) return done(err);
+
+ // respond to request
+ res.setHeader('content-type', 'text/plain');
+ res.end('hello, world!');
+ });
+});
+```
+
+### write logs to a file
+
+#### single file
+
+Sample app that will log all requests in the Apache combined format to the file
+`access.log`.
+
+```js
+var express = require('express');
+var fs = require('fs');
+var morgan = require('morgan');
+var path = require('path');
+
+var app = express();
+
+// create a write stream (in append mode)
+var accessLogStream = fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' });
+
+// setup the logger
+app.use(morgan('combined', { stream: accessLogStream }));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+#### log file rotation
+
+Sample app that will log all requests in the Apache combined format to one log
+file per day in the `log/` directory using the
+[rotating-file-stream module](https://www.npmjs.com/package/rotating-file-stream).
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+var path = require('path');
+var rfs = require('rotating-file-stream'); // version 2.x
+
+var app = express();
+
+// create a rotating write stream
+var accessLogStream = rfs.createStream('access.log', {
+ interval: '1d', // rotate daily
+ path: path.join(__dirname, 'log'),
+});
+
+// setup the logger
+app.use(morgan('combined', { stream: accessLogStream }));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### split / dual logging
+
+The `morgan` middleware can be used as many times as needed, enabling
+combinations like:
+
+- Log entry on request and one on response
+- Log all requests to file, but errors to console
+- ... and more!
+
+Sample app that will log all requests to a file using Apache format, but
+error responses are logged to the console:
+
+```js
+var express = require('express');
+var fs = require('fs');
+var morgan = require('morgan');
+var path = require('path');
+
+var app = express();
+
+// log only 4xx and 5xx responses to console
+app.use(
+ morgan('dev', {
+ skip: function (req, res) {
+ return res.statusCode < 400;
+ },
+ })
+);
+
+// log all requests to access.log
+app.use(
+ morgan('common', {
+ stream: fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' }),
+ })
+);
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### use custom token formats
+
+Sample app that will use custom token formats. This adds an ID to all requests and displays it using the `:id` token.
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+var uuid = require('node-uuid');
+
+morgan.token('id', function getId(req) {
+ return req.id;
+});
+
+var app = express();
+
+app.use(assignId);
+app.use(morgan(':id :method :url :response-time'));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+
+function assignId(req, res, next) {
+ req.id = uuid.v4();
+ next();
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/morgan/master?label=ci
+[ci-url]: https://github.com/expressjs/morgan/actions/workflows/ci.yml
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/morgan/master
+[coveralls-url]: https://coveralls.io/r/expressjs/morgan?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/morgan
+[npm-url]: https://npmjs.org/package/morgan
+[npm-version-image]: https://badgen.net/npm/v/morgan
diff --git a/astro/src/content/resources/en/middleware/multer.md b/astro/src/content/resources/en/middleware/multer.md
new file mode 100644
index 0000000000..326786ab3d
--- /dev/null
+++ b/astro/src/content/resources/en/middleware/multer.md
@@ -0,0 +1,352 @@
+---
+title: Express multer middleware
+module: multer
+---
+
+# Multer [![NPM Version][npm-version-image]][npm-url] [![NPM Downloads][npm-downloads-image]][npm-url] [![Build Status][ci-image]][ci-url] [![Test Coverage][test-image]][test-url] [![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+
+Multer is a node.js middleware for handling `multipart/form-data`, which is primarily used for uploading files. It is written
+on top of [busboy](https://github.com/mscdex/busboy) for maximum efficiency.
+
+**NOTE**: Multer will not process any form which is not multipart (`multipart/form-data`).
+
+## Translations
+
+This README is also available in other languages:
+
+| | |
+| ------------------------------------------------------------------------------ | --------------- |
+| [العربية](https://github.com/expressjs/multer/blob/main/doc/README-ar.md) | Arabic |
+| [简体中文](https://github.com/expressjs/multer/blob/main/doc/README-zh-cn.md) | Chinese |
+| [Français](https://github.com/expressjs/multer/blob/main/doc/README-fr.md) | French |
+| [한국어](https://github.com/expressjs/multer/blob/main/doc/README-ko.md) | Korean |
+| [Português](https://github.com/expressjs/multer/blob/main/doc/README-pt-br.md) | Portuguese (BR) |
+| [Русский язык](https://github.com/expressjs/multer/blob/main/doc/README-ru.md) | Russian |
+| [Español](https://github.com/expressjs/multer/blob/main/doc/README-es.md) | Spanish |
+| [O'zbek tili](https://github.com/expressjs/multer/blob/main/doc/README-uz.md) | Uzbek |
+| [Việt Nam](https://github.com/expressjs/multer/blob/main/doc/README-vi.md) | Vietnamese |
+
+## Installation
+
+```sh
+$ npm install multer
+```
+
+## Usage
+
+Multer adds a `body` object and a `file` or `files` object to the `request` object. The `body` object contains the values of the text fields of the form, the `file` or `files` object contains the files uploaded via the form.
+
+Basic usage example:
+
+Don't forget the `enctype="multipart/form-data"` in your form.
+
+```html
+
+```
+
+```javascript
+const express = require('express');
+const multer = require('multer');
+const upload = multer({ dest: 'uploads/' });
+
+const app = express();
+
+app.post('/profile', upload.single('avatar'), function (req, res, next) {
+ // req.file is the `avatar` file
+ // req.body will hold the text fields, if there were any
+});
+
+app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
+ // req.files is array of `photos` files
+ // req.body will contain the text fields, if there were any
+});
+
+const uploadMiddleware = upload.fields([
+ { name: 'avatar', maxCount: 1 },
+ { name: 'gallery', maxCount: 8 },
+]);
+app.post('/cool-profile', uploadMiddleware, function (req, res, next) {
+ // req.files is an object (String -> Array) where fieldname is the key, and the value is array of files
+ //
+ // e.g.
+ // req.files['avatar'][0] -> File
+ // req.files['gallery'] -> Array
+ //
+ // req.body will contain the text fields, if there were any
+});
+```
+
+In case you need to handle a text-only multipart form, you should use the `.none()` method:
+
+```javascript
+const express = require('express');
+const app = express();
+const multer = require('multer');
+const upload = multer();
+
+app.post('/profile', upload.none(), function (req, res, next) {
+ // req.body contains the text fields
+});
+```
+
+Here's an example on how multer is used in a HTML form. Take special note of the `enctype="multipart/form-data"` and `name="uploaded_file"` fields:
+
+```html
+
+```
+
+Then in your javascript file you would add these lines to access both the file and the body. It is important that you use the `name` field value from the form in your upload function. This tells multer which field on the request it should look for the files in. If these fields aren't the same in the HTML form and on your server, your upload will fail:
+
+```javascript
+const multer = require('multer');
+const upload = multer({ dest: './public/data/uploads/' });
+app.post('/stats', upload.single('uploaded_file'), function (req, res) {
+ // req.file is the name of your file in the form above, here 'uploaded_file'
+ // req.body will hold the text fields, if there were any
+ console.log(req.file, req.body);
+});
+```
+
+## API
+
+### File information
+
+Each file contains the following information:
+
+| Key | Description | Note |
+| -------------- | --------------------------------------------- | --------------- |
+| `fieldname` | Field name specified in the form |
+| `originalname` | Name of the file on the user's computer |
+| `encoding` | Encoding type of the file |
+| `mimetype` | Mime type of the file |
+| `size` | Size of the file in bytes |
+| `destination` | The folder to which the file has been saved | `DiskStorage` |
+| `filename` | The name of the file within the `destination` | `DiskStorage` |
+| `path` | The full path to the uploaded file | `DiskStorage` |
+| `buffer` | A `Buffer` of the entire file | `MemoryStorage` |
+
+### `multer(opts)`
+
+Multer accepts an options object, the most basic of which is the `dest`
+property, which tells Multer where to upload the files. In case you omit the
+options object, the files will be kept in memory and never written to disk.
+
+By default, Multer will rename the files so as to avoid naming conflicts. The
+renaming function can be customized according to your needs.
+
+The following are the options that can be passed to Multer.
+
+| Key | Description |
+| ------------------- | --------------------------------------------------------- |
+| `dest` or `storage` | Where to store the files |
+| `fileFilter` | Function to control which files are accepted |
+| `limits` | Limits of the uploaded data |
+| `preservePath` | Keep the full path of files instead of just the base name |
+
+In an average web app, only `dest` might be required, and configured as shown in
+the following example.
+
+```javascript
+const upload = multer({ dest: 'uploads/' });
+```
+
+If you want more control over your uploads, you'll want to use the `storage`
+option instead of `dest`. Multer ships with storage engines `DiskStorage`
+and `MemoryStorage`; More engines are available from third parties.
+
+#### `.single(fieldname)`
+
+Accept a single file with the name `fieldname`. The single file will be stored
+in `req.file`.
+
+#### `.array(fieldname[, maxCount])`
+
+Accept an array of files, all with the name `fieldname`. Optionally error out if
+more than `maxCount` files are uploaded. The array of files will be stored in
+`req.files`.
+
+#### `.fields(fields)`
+
+Accept a mix of files, specified by `fields`. An object with arrays of files
+will be stored in `req.files`.
+
+`fields` should be an array of objects with `name` and optionally a `maxCount`.
+Example:
+
+```javascript
+[
+ { name: 'avatar', maxCount: 1 },
+ { name: 'gallery', maxCount: 8 },
+];
+```
+
+#### `.none()`
+
+Accept only text fields. If any file upload is made, error with code
+"LIMIT_UNEXPECTED_FILE" will be issued.
+
+#### `.any()`
+
+Accepts all files that comes over the wire. An array of files will be stored in
+`req.files`.
+
+**WARNING:** Make sure that you always handle the files that a user uploads.
+Never add multer as a global middleware since a malicious user could upload
+files to a route that you didn't anticipate. Only use this function on routes
+where you are handling the uploaded files.
+
+### `storage`
+
+#### `DiskStorage`
+
+The disk storage engine gives you full control on storing files to disk.
+
+```javascript
+const storage = multer.diskStorage({
+ destination: function (req, file, cb) {
+ cb(null, '/tmp/my-uploads');
+ },
+ filename: function (req, file, cb) {
+ const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
+ cb(null, file.fieldname + '-' + uniqueSuffix);
+ },
+});
+
+const upload = multer({ storage: storage });
+```
+
+There are two options available, `destination` and `filename`. They are both
+functions that determine where the file should be stored.
+
+`destination` is used to determine within which folder the uploaded files should
+be stored. This can also be given as a `string` (e.g. `'/tmp/uploads'`). If no
+`destination` is given, the operating system's default directory for temporary
+files is used.
+
+**Note:** You are responsible for creating the directory when providing
+`destination` as a function. When passing a string, multer will make sure that
+the directory is created for you.
+
+`filename` is used to determine what the file should be named inside the folder.
+If no `filename` is given, each file will be given a random name that doesn't
+include any file extension.
+
+**Note:** Multer will not append any file extension for you, your function
+should return a filename complete with a file extension.
+
+Each function gets passed both the request (`req`) and some information about
+the file (`file`) to aid with the decision.
+
+Note that `req.body` might not have been fully populated yet. It depends on the
+order that the client transmits fields and files to the server.
+
+For understanding the calling convention used in the callback (needing to pass
+null as the first param), refer to
+[Node.js error handling](https://web.archive.org/web/20220417042018/https://www.joyent.com/node-js/production/design/errors)
+
+#### `MemoryStorage`
+
+The memory storage engine stores the files in memory as `Buffer` objects. It
+doesn't have any options.
+
+```javascript
+const storage = multer.memoryStorage();
+const upload = multer({ storage: storage });
+```
+
+When using memory storage, the file info will contain a field called
+`buffer` that contains the entire file.
+
+**WARNING**: Uploading very large files, or relatively small files in large
+numbers very quickly, can cause your application to run out of memory when
+memory storage is used.
+
+### `limits`
+
+An object specifying the size limits of the following optional properties. Multer passes this object into busboy directly, and the details of the properties can be found on [busboy's page](https://github.com/mscdex/busboy#busboy-methods).
+
+The following integer values are available:
+
+| Key | Description | Default |
+| --------------- | ----------------------------------------------------------------------- | --------- |
+| `fieldNameSize` | Max field name size | 100 bytes |
+| `fieldSize` | Max field value size (in bytes) | 1MB |
+| `fields` | Max number of non-file fields | Infinity |
+| `fileSize` | For multipart forms, the max file size (in bytes) | Infinity |
+| `files` | For multipart forms, the max number of file fields | Infinity |
+| `parts` | For multipart forms, the max number of parts (fields + files) | Infinity |
+| `headerPairs` | For multipart forms, the max number of header key=>value pairs to parse | 2000 |
+
+Specifying the limits can help protect your site against denial of service (DoS) attacks.
+
+### `fileFilter`
+
+Set this to a function to control which files should be uploaded and which
+should be skipped. The function should look like this:
+
+```javascript
+function fileFilter(req, file, cb) {
+ // The function should call `cb` with a boolean
+ // to indicate if the file should be accepted
+
+ // To reject this file pass `false`, like so:
+ cb(null, false);
+
+ // To accept the file pass `true`, like so:
+ cb(null, true);
+
+ // You can always pass an error if something goes wrong:
+ cb(new Error("I don't have a clue!"));
+}
+```
+
+## Error handling
+
+When encountering an error, Multer will delegate the error to Express. You can
+display a nice error page using [the standard express way](http://expressjs.com/guide/error-handling.html).
+
+If you want to catch errors specifically from Multer, you can call the
+middleware function by yourself. Also, if you want to catch only [the Multer errors](https://github.com/expressjs/multer/blob/main/lib/multer-error.js), you can use the `MulterError` class that is attached to the `multer` object itself (e.g. `err instanceof multer.MulterError`).
+
+```javascript
+const multer = require('multer');
+const upload = multer().single('avatar');
+
+app.post('/profile', function (req, res) {
+ upload(req, res, function (err) {
+ if (err instanceof multer.MulterError) {
+ // A Multer error occurred when uploading.
+ } else if (err) {
+ // An unknown error occurred when uploading.
+ }
+
+ // Everything went fine.
+ });
+});
+```
+
+## Custom storage engine
+
+For information on how to build your own storage engine, see [Multer Storage Engine](https://github.com/expressjs/multer/blob/main/StorageEngine.md).
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://github.com/expressjs/multer/actions/workflows/ci.yml/badge.svg
+[ci-url]: https://github.com/expressjs/multer/actions/workflows/ci.yml
+[test-url]: https://coveralls.io/r/expressjs/multer?branch=main
+[test-image]: https://badgen.net/coveralls/c/github/expressjs/multer/main
+[npm-downloads-image]: https://badgen.net/npm/dm/multer
+[npm-url]: https://npmjs.org/package/multer
+[npm-version-image]: https://badgen.net/npm/v/multer
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/multer/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer
diff --git a/astro/src/content/resources/en/middleware/overview.md b/astro/src/content/resources/en/middleware/overview.md
new file mode 100755
index 0000000000..46217759e7
--- /dev/null
+++ b/astro/src/content/resources/en/middleware/overview.md
@@ -0,0 +1,40 @@
+---
+title: Express middleware
+description: Explore a list of Express.js middleware modules maintained by the Express team and the community, including built-in middleware and popular third-party modules.
+module: mw-home
+---
+
+## Express middleware
+
+The Express middleware modules listed here are maintained by the
+[Expressjs team](https://github.com/orgs/expressjs/people).
+
+| Middleware module | Description |
+| ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
+| [body-parser](/en/resources/middleware/body-parser) | Parse HTTP request body. |
+| [compression](/en/resources/middleware/compression) | Compress HTTP responses. |
+| [cookie-parser](/en/resources/middleware/cookie-parser) | Parse cookie header and populate `req.cookies`. See also [cookies](https://github.com/jed/cookies). |
+| [cookie-session](/en/resources/middleware/cookie-session) | Establish cookie-based sessions. |
+| [cors](/en/resources/middleware/cors) | Enable cross-origin resource sharing (CORS) with various options. |
+| [errorhandler](/en/resources/middleware/errorhandler) | Development error-handling/debugging. |
+| [method-override](/en/resources/middleware/method-override) | Override HTTP methods using header. |
+| [morgan](/en/resources/middleware/morgan) | HTTP request logger. |
+| [multer](/en/resources/middleware/multer) | Handle multi-part form data. |
+| [response-time](/en/resources/middleware/response-time) | Record HTTP response time. |
+| [serve-favicon](/en/resources/middleware/serve-favicon) | Serve a favicon. |
+| [serve-index](/en/resources/middleware/serve-index) | Serve directory listing for a given path. |
+| [serve-static](/en/resources/middleware/serve-static) | Serve static files. |
+| [session](/en/resources/middleware/session) | Establish server-based sessions (development only). |
+| [timeout](/en/resources/middleware/timeout) | Set a timeout perioHTTP request processing. |
+| [vhost](/en/resources/middleware/vhost) | Create virtual domains. |
+
+## Additional middleware modules
+
+These are some additional popular middleware modules.
+
+{% include community-caveat.html %}
+
+| Middleware module | Description |
+| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
+| [helmet](https://github.com/helmetjs/helmet) | Helps secure your apps by setting various HTTP headers. |
+| [passport](https://github.com/jaredhanson/passport) | Authentication using "strategies" such as OAuth, OpenID and many others. See [passportjs.org](https://passportjs.org/) for more information. |
diff --git a/astro/src/content/resources/en/middleware/response-time.md b/astro/src/content/resources/en/middleware/response-time.md
new file mode 100644
index 0000000000..f911f480f5
--- /dev/null
+++ b/astro/src/content/resources/en/middleware/response-time.md
@@ -0,0 +1,314 @@
+---
+title: Express response-time middleware
+module: response-time
+---
+
+# compression
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+[![Funding][funding-image]][funding-url]
+
+Node.js compression middleware.
+
+The following compression codings are supported:
+
+- deflate
+- gzip
+- br (brotli)
+
+**Note** Brotli is supported only since Node.js versions v11.7.0 and v10.16.0.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```bash
+$ npm install compression
+```
+
+## API
+
+```js
+var compression = require('compression');
+```
+
+### compression([options])
+
+Returns the compression middleware using the given `options`. The middleware
+will attempt to compress response bodies for all requests that traverse through
+the middleware, based on the given `options`.
+
+This middleware will never compress responses that include a `Cache-Control`
+header with the [`no-transform` directive](https://tools.ietf.org/html/rfc7234#section-5.2.2.4),
+as compressing will transform the body.
+
+#### Options
+
+`compression()` accepts these properties in the options object. In addition to
+those listed below, [zlib](https://nodejs.org/api/zlib.html) options may be
+passed in to the options object or
+[brotli](https://nodejs.org/api/zlib.html#zlib_class_brotlioptions) options.
+
+##### chunkSize
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_CHUNK`, or `16384`.
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### filter
+
+Type: `Function`
+
+A function to decide if the response should be considered for compression.
+This function is called as `filter(req, res)` and is expected to return
+`true` to consider the response for compression, or `false` to not compress
+the response.
+
+The default filter function uses the [compressible](https://www.npmjs.com/package/compressible)
+module to determine if `res.getHeader('Content-Type')` is compressible.
+
+##### level
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_COMPRESSION`, or `-1`
+
+The level of zlib compression to apply to responses. A higher level will result
+in better compression, but will take longer to complete. A lower level will
+result in less compression, but will be much faster.
+
+This is an integer in the range of `0` (no compression) to `9` (maximum
+compression). The special value `-1` can be used to mean the "default
+compression level", which is a default compromise between speed and
+compression (currently equivalent to level 6).
+
+- `-1` Default compression level (also `zlib.constants.Z_DEFAULT_COMPRESSION`).
+- `0` No compression (also `zlib.constants.Z_NO_COMPRESSION`).
+- `1` Fastest compression (also `zlib.constants.Z_BEST_SPEED`).
+- `2`
+- `3`
+- `4`
+- `5`
+- `6` (currently what `zlib.constants.Z_DEFAULT_COMPRESSION` points to).
+- `7`
+- `8`
+- `9` Best compression (also `zlib.constants.Z_BEST_COMPRESSION`).
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### memLevel
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_MEMLEVEL`, or `8`
+
+This specifies how much memory should be allocated for the internal compression
+state and is an integer in the range of `1` (minimum level) and `9` (maximum
+level).
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### brotli
+
+Type: `Object`
+
+This specifies the options for configuring Brotli. See [Node.js documentation](https://nodejs.org/api/zlib.html#class-brotlioptions) for a complete list of available options.
+
+##### strategy
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_STRATEGY`
+
+This is used to tune the compression algorithm. This value only affects the
+compression ratio, not the correctness of the compressed output, even if it
+is not set appropriately.
+
+- `zlib.constants.Z_DEFAULT_STRATEGY` Use for normal data.
+- `zlib.constants.Z_FILTERED` Use for data produced by a filter (or predictor).
+ Filtered data consists mostly of small values with a somewhat random
+ distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect is to force more Huffman coding and less
+ string matching; it is somewhat intermediate between `zlib.constants.Z_DEFAULT_STRATEGY`
+ and `zlib.constants.Z_HUFFMAN_ONLY`.
+- `zlib.constants.Z_FIXED` Use to prevent the use of dynamic Huffman codes, allowing
+ for a simpler decoder for special applications.
+- `zlib.constants.Z_HUFFMAN_ONLY` Use to force Huffman encoding only (no string match).
+- `zlib.constants.Z_RLE` Use to limit match distances to one (run-length encoding).
+ This is designed to be almost as fast as `zlib.constants.Z_HUFFMAN_ONLY`, but give
+ better compression for PNG image data.
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### threshold
+
+Type: `Number` or `String`
+Default: `1kb`
+
+The byte threshold for the response body size before compression is considered
+for the response. This is a number of bytes or any string
+accepted by the [bytes](https://www.npmjs.com/package/bytes) module.
+
+**Note** this is only an advisory setting; if the response size cannot be determined
+at the time the response headers are written, then it is assumed the response is
+_over_ the threshold. To guarantee the response size can be determined, be sure
+set a `Content-Length` response header.
+
+##### windowBits
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_WINDOWBITS`, or `15`
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### enforceEncoding
+
+Type: `String`
+Default: `identity`
+
+This is the default encoding to use when the client does not specify an encoding in the request's [Accept-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) header.
+
+#### .filter
+
+The default `filter` function. This is used to construct a custom filter
+function that is an extension of the default function.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+app.use(compression({ filter: shouldCompress }));
+
+function shouldCompress(req, res) {
+ if (req.headers['x-no-compression']) {
+ // don't compress responses with this request header
+ return false;
+ }
+
+ // fallback to standard filter function
+ return compression.filter(req, res);
+}
+```
+
+### res.flush
+
+This module adds a `res.flush()` method to force the partially-compressed
+response to be flushed to the client.
+
+## Examples
+
+### express
+
+When using this module with express, simply `app.use` the module as
+high as you like. Requests that pass through the middleware will be compressed.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress all responses
+app.use(compression());
+
+// add all routes
+```
+
+### Node.js HTTP server
+
+```js
+var compression = require('compression')({ threshold: 0 });
+var http = require('http');
+
+function createServer(fn) {
+ return http.createServer(function (req, res) {
+ compression(req, res, function (err) {
+ if (err) {
+ res.statusCode = err.status || 500;
+ res.end(err.message);
+ return;
+ }
+
+ fn(req, res);
+ });
+ });
+}
+
+var server = createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello world!');
+});
+
+server.listen(3000, () => {
+ console.log('> Listening at http://localhost:3000');
+});
+```
+
+### Server-Sent Events
+
+Because of the nature of compression this module does not work out of the box
+with server-sent events. To compress content, a window of the output needs to
+be buffered up in order to get good compression. Typically when using server-sent
+events, there are certain block of data that need to reach the client.
+
+You can achieve this by calling `res.flush()` when you need the data written to
+actually make it to the client.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress responses
+app.use(compression());
+
+// server-sent event stream
+app.get('/events', function (req, res) {
+ res.setHeader('Content-Type', 'text/event-stream');
+ res.setHeader('Cache-Control', 'no-cache');
+
+ // send a ping approx every 2 seconds
+ var timer = setInterval(function () {
+ res.write('data: ping\n\n');
+
+ // !!! this is the important part
+ res.flush();
+ }, 2000);
+
+ res.on('close', function () {
+ clearInterval(timer);
+ });
+});
+```
+
+## Contributing
+
+The Express.js project welcomes all constructive contributions. Contributions take many forms,
+from code for bug fixes and enhancements, to additions and fixes to documentation, additional
+tests, triaging incoming pull requests and issues, and more!
+
+See the [Contributing Guide](https://github.com/expressjs/express/blob/master/Contributing.md) for more technical details on contributing.
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://badgen.net/npm/v/compression
+[npm-url]: https://npmjs.org/package/compression
+[downloads-image]: https://badgen.net/npm/dm/compression
+[downloads-url]: https://npmcharts.com/compare/compression?minimal=true
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/compression/master?label=CI
+[github-actions-ci-url]: https://github.com/expressjs/compression/actions?query=workflow%3Aci
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/compression/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/compression
+[funding-url]: https://opencollective.com/express
+[funding-image]: https://badgen.net/badge/icon/sponsor/pink?icon=github&label=Open%20Collective
diff --git a/astro/src/content/resources/en/middleware/serve-favicon.md b/astro/src/content/resources/en/middleware/serve-favicon.md
new file mode 100644
index 0000000000..7a77865c6b
--- /dev/null
+++ b/astro/src/content/resources/en/middleware/serve-favicon.md
@@ -0,0 +1,156 @@
+---
+title: Express serve-favicon middleware
+module: serve-favicon
+---
+
+# serve-index
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Linux Build Status][ci-image]][ci-url]
+[![Windows Build][appveyor-image]][appveyor-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+Serves pages that contain directory listings for a given path.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-index
+```
+
+## API
+
+```js
+var serveIndex = require('serve-index');
+```
+
+### serveIndex(path, options)
+
+Returns middlware that serves an index of the directory in the given `path`.
+
+The `path` is based off the `req.url` value, so a `req.url` of `'/some/dir`
+with a `path` of `'public'` will look at `'public/some/dir'`. If you are using
+something like `express`, you can change the URL "base" with `app.use` (see
+the express example).
+
+#### Options
+
+Serve index accepts these properties in the options object.
+
+##### filter
+
+Apply this filter function to files. Defaults to `false`. The `filter` function
+is called for each file, with the signature `filter(filename, index, files, dir)`
+where `filename` is the name of the file, `index` is the array index, `files` is
+the array of files and `dir` is the absolute path the file is located (and thus,
+the directory the listing is for).
+
+##### hidden
+
+Display hidden (dot) files. Defaults to `false`.
+
+##### icons
+
+Display icons. Defaults to `false`.
+
+##### stylesheet
+
+Optional path to a CSS stylesheet. Defaults to a built-in stylesheet.
+
+##### template
+
+Optional path to an HTML template or a function that will render a HTML
+string. Defaults to a built-in template.
+
+When given a string, the string is used as a file path to load and then the
+following tokens are replaced in templates:
+
+- `{directory}` with the name of the directory.
+- `{files}` with the HTML of an unordered list of file links.
+- `{linked-path}` with the HTML of a link to the directory.
+- `{style}` with the specified stylesheet and embedded images.
+
+When given as a function, the function is called as `template(locals, callback)`
+and it needs to invoke `callback(error, htmlString)`. The following are the
+provided locals:
+
+- `directory` is the directory being displayed (where `/` is the root).
+- `displayIcons` is a Boolean for if icons should be rendered or not.
+- `fileList` is a sorted array of files in the directory. The array contains
+ objects with the following properties:
+ - `name` is the relative name for the file.
+ - `stat` is a `fs.Stats` object for the file.
+- `path` is the full filesystem path to `directory`.
+- `style` is the default stylesheet or the contents of the `stylesheet` option.
+- `viewName` is the view name provided by the `view` option.
+
+##### view
+
+Display mode. `tiles` and `details` are available. Defaults to `tiles`.
+
+## Examples
+
+### Serve directory indexes with vanilla node.js http server
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var serveIndex = require('serve-index');
+var serveStatic = require('serve-static');
+
+// Serve directory indexes for public/ftp folder (with icons)
+var index = serveIndex('public/ftp', { icons: true });
+
+// Serve up public/ftp folder files
+var serve = serveStatic('public/ftp');
+
+// Create server
+var server = http.createServer(function onRequest(req, res) {
+ var done = finalhandler(req, res);
+ serve(req, res, function onNext(err) {
+ if (err) return done(err);
+ index(req, res, done);
+ });
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve directory indexes with express
+
+```js
+var express = require('express');
+var serveIndex = require('serve-index');
+
+var app = express();
+
+// Serve URLs like /ftp/thing as public/ftp/thing
+// The express.static serves the file contents
+// The serveIndex is this module serving the directory
+app.use('/ftp', express.static('public/ftp'), serveIndex('public/ftp', { icons: true }));
+
+// Listen
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE). The [Silk](http://www.famfamfam.com/lab/icons/silk/) icons
+are created by/copyright of [FAMFAMFAM](http://www.famfamfam.com/).
+
+[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/serve-index/master.svg?label=windows
+[appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index
+[ci-image]: https://badgen.net/github/checks/expressjs/serve-index/master?label=ci
+[ci-url]: https://github.com/expressjs/serve-index/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/serve-index/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-index?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/serve-index.svg
+[downloads-url]: https://npmjs.org/package/serve-index
+[npm-image]: https://img.shields.io/npm/v/serve-index.svg
+[npm-url]: https://npmjs.org/package/serve-index
diff --git a/astro/src/content/resources/en/middleware/serve-index.md b/astro/src/content/resources/en/middleware/serve-index.md
new file mode 100644
index 0000000000..da03cf94b2
--- /dev/null
+++ b/astro/src/content/resources/en/middleware/serve-index.md
@@ -0,0 +1,156 @@
+---
+title: Express serve-index middleware
+module: serve-index
+---
+
+# serve-index
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Linux Build Status][ci-image]][ci-url]
+[![Windows Build][appveyor-image]][appveyor-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+Serves pages that contain directory listings for a given path.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-index
+```
+
+## API
+
+```js
+var serveIndex = require('serve-index');
+```
+
+### serveIndex(path, options)
+
+Returns middlware that serves an index of the directory in the given `path`.
+
+The `path` is based off the `req.url` value, so a `req.url` of `'/some/dir`
+with a `path` of `'public'` will look at `'public/some/dir'`. If you are using
+something like `express`, you can change the URL "base" with `app.use` (see
+the express example).
+
+#### Options
+
+Serve index accepts these properties in the options object.
+
+##### filter
+
+Apply this filter function to files. Defaults to `false`. The `filter` function
+is called for each file, with the signature `filter(filename, index, files, dir)`
+where `filename` is the name of the file, `index` is the array index, `files` is
+the array of files and `dir` is the absolute path the file is located (and thus,
+the directory the listing is for).
+
+##### hidden
+
+Display hidden (dot) files. Defaults to `false`.
+
+##### icons
+
+Display icons. Defaults to `false`.
+
+##### stylesheet
+
+Optional path to a CSS stylesheet. Defaults to a built-in stylesheet.
+
+##### template
+
+Optional path to an HTML template or a function that will render a HTML
+string. Defaults to a built-in template.
+
+When given a string, the string is used as a file path to load and then the
+following tokens are replaced in templates:
+
+- `{directory}` with the name of the directory.
+- `{files}` with the HTML of an unordered list of file links.
+- `{linked-path}` with the HTML of a link to the directory.
+- `{style}` with the specified stylesheet and embedded images.
+
+When given as a function, the function is called as `template(locals, callback)`
+and it needs to invoke `callback(error, htmlString)`. The following are the
+provided locals:
+
+- `directory` is the directory being displayed (where `/` is the root).
+- `displayIcons` is a Boolean for if icons should be rendered or not.
+- `fileList` is a sorted array of files in the directory. The array contains
+ objects with the following properties:
+ - `name` is the relative name for the file.
+ - `stat` is a `fs.Stats` object for the file.
+- `path` is the full filesystem path to `directory`.
+- `style` is the default stylesheet or the contents of the `stylesheet` option.
+- `viewName` is the view name provided by the `view` option.
+
+##### view
+
+Display mode. `tiles` and `details` are available. Defaults to `tiles`.
+
+## Examples
+
+### Serve directory indexes with vanilla node.js http server
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var serveIndex = require('serve-index');
+var serveStatic = require('serve-static');
+
+// Serve directory indexes for public/ftp folder (with icons)
+var index = serveIndex('public/ftp', { icons: true });
+
+// Serve up public/ftp folder files
+var serve = serveStatic('public/ftp');
+
+// Create server
+var server = http.createServer(function onRequest(req, res) {
+ var done = finalhandler(req, res);
+ serve(req, res, function onNext(err) {
+ if (err) return done(err);
+ index(req, res, done);
+ });
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve directory indexes with express
+
+```js
+var express = require('express');
+var serveIndex = require('serve-index');
+
+var app = express();
+
+// Serve URLs like /ftp/thing as public/ftp/thing
+// The express.static serves the file contents
+// The serveIndex is this module serving the directory
+app.use('/ftp', express.static('public/ftp'), serveIndex('public/ftp', { icons: true }));
+
+// Listen
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE). The [Silk](http://www.famfamfam.com/lab/icons/silk/) icons
+are created by/copyright of [FAMFAMFAM](http://www.famfamfam.com/).
+
+[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/serve-index/master.svg?label=windows
+[appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index
+[ci-image]: https://badgen.net/github/checks/expressjs/serve-index/master?label=ci
+[ci-url]: https://github.com/expressjs/serve-index/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/serve-index/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-index?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/serve-index.svg
+[downloads-url]: https://npmjs.org/package/serve-index
+[npm-image]: https://img.shields.io/npm/v/serve-index.svg
+[npm-url]: https://npmjs.org/package/serve-index
diff --git a/astro/src/content/resources/en/middleware/serve-static.md b/astro/src/content/resources/en/middleware/serve-static.md
new file mode 100644
index 0000000000..b048165d7b
--- /dev/null
+++ b/astro/src/content/resources/en/middleware/serve-static.md
@@ -0,0 +1,260 @@
+---
+title: Express serve-static middleware
+module: serve-static
+---
+
+# serve-static
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![CI][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-static
+```
+
+## API
+
+```js
+const serveStatic = require('serve-static');
+```
+
+### serveStatic(root, options)
+
+Create a new middleware function to serve files from within a given root
+directory. The file to serve will be determined by combining `req.url`
+with the provided root directory. When a file is not found, instead of
+sending a 404 response, this module will instead call `next()` to move on
+to the next middleware, allowing for stacking and fall-backs.
+
+#### Options
+
+##### acceptRanges
+
+Enable or disable accepting ranged requests, defaults to true.
+Disabling this will not send `Accept-Ranges` and ignore the contents
+of the `Range` request header.
+
+##### cacheControl
+
+Enable or disable setting `Cache-Control` response header, defaults to
+true. Disabling this will ignore the `immutable` and `maxAge` options.
+
+##### dotfiles
+
+Set how "dotfiles" are treated when encountered. A dotfile is a file
+or directory that begins with a dot ("."). Note this check is done on
+the path itself without checking if the path actually exists on the
+disk. If `root` is specified, only the dotfiles above the root are
+checked (i.e. the root itself can be within a dotfile when set
+to "deny").
+
+- `'allow'` No special treatment for dotfiles.
+- `'deny'` Deny a request for a dotfile and 403/`next()`.
+- `'ignore'` Pretend like the dotfile does not exist and 404/`next()`.
+
+The default value is `'ignore'`.
+
+##### etag
+
+Enable or disable etag generation, defaults to true.
+
+##### extensions
+
+Set file extension fallbacks. When set, if a file is not found, the given
+extensions will be added to the file name and search for. The first that
+exists will be served. Example: `['html', 'htm']`.
+
+The default value is `false`.
+
+##### fallthrough
+
+Set the middleware to have client errors fall-through as just unhandled
+requests, otherwise forward a client error. The difference is that client
+errors like a bad request or a request to a non-existent file will cause
+this middleware to simply `next()` to your next middleware when this value
+is `true`. When this value is `false`, these errors (even 404s), will invoke
+`next(err)`.
+
+Typically `true` is desired such that multiple physical directories can be
+mapped to the same web address or for routes to fill in non-existent files.
+
+The value `false` can be used if this middleware is mounted at a path that
+is designed to be strictly a single file system directory, which allows for
+short-circuiting 404s for less overhead. This middleware will also reply to
+all methods.
+
+The default value is `true`.
+
+##### immutable
+
+Enable or disable the `immutable` directive in the `Cache-Control` response
+header, defaults to `false`. If set to `true`, the `maxAge` option should
+also be specified to enable caching. The `immutable` directive will prevent
+supported clients from making conditional requests during the life of the
+`maxAge` option to check if the file has changed.
+
+##### index
+
+By default this module will send "index.html" files in response to a request
+on a directory. To disable this set `false` or to supply a new index pass a
+string or an array in preferred order.
+
+##### lastModified
+
+Enable or disable `Last-Modified` header, defaults to true. Uses the file
+system's last modified value.
+
+##### maxAge
+
+Provide a max-age in milliseconds for http caching, defaults to 0. This
+can also be a string accepted by the [ms](https://www.npmjs.org/package/ms#readme)
+module.
+
+##### redirect
+
+Redirect to trailing "/" when the pathname is a dir. Defaults to `true`.
+
+##### setHeaders
+
+Function to set custom headers on response. Alterations to the headers need to
+occur synchronously. The function is called as `fn(res, path, stat)`, where
+the arguments are:
+
+- `res` the response object
+- `path` the file path that is being sent
+- `stat` the stat object of the file that is being sent
+
+## Examples
+
+### Serve files with vanilla node.js http server
+
+```js
+const finalhandler = require('finalhandler');
+const http = require('http');
+const serveStatic = require('serve-static');
+
+// Serve up public/ftp folder
+const serve = serveStatic('public/ftp', { index: ['index.html', 'index.htm'] });
+
+// Create server
+const server = http.createServer((req, res) => {
+ serve(req, res, finalhandler(req, res));
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve all files as downloads
+
+```js
+const contentDisposition = require('content-disposition');
+const finalhandler = require('finalhandler');
+const http = require('http');
+const serveStatic = require('serve-static');
+
+// Serve up public/ftp folder
+const serve = serveStatic('public/ftp', {
+ index: false,
+ setHeaders: setHeaders,
+});
+
+// Set header to force download
+function setHeaders(res, path) {
+ res.setHeader('Content-Disposition', contentDisposition(path));
+}
+
+// Create server
+const server = http.createServer((req, res) => {
+ serve(req, res, finalhandler(req, res));
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serving using express
+
+#### Simple
+
+This is a simple example of using Express.
+
+```js
+const express = require('express');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(serveStatic('public/ftp', { index: ['default.html', 'default.htm'] }));
+app.listen(3000);
+```
+
+#### Multiple roots
+
+This example shows a simple way to search through multiple directories.
+Files are searched for in `public-optimized/` first, then `public/` second
+as a fallback.
+
+```js
+const express = require('express');
+const path = require('path');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(serveStatic(path.join(__dirname, 'public-optimized')));
+app.use(serveStatic(path.join(__dirname, 'public')));
+app.listen(3000);
+```
+
+#### Different settings for paths
+
+This example shows how to set a different max age depending on the served
+file. In this example, HTML files are not cached, while everything else
+is for 1 day.
+
+```js
+const express = require('express');
+const path = require('path');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(
+ serveStatic(path.join(__dirname, 'public'), {
+ maxAge: '1d',
+ setHeaders: setCustomCacheControl,
+ })
+);
+
+app.listen(3000);
+
+function setCustomCacheControl(res, file) {
+ if (path.extname(file) === '.html') {
+ // Custom Cache-Control for HTML files
+ res.setHeader('Cache-Control', 'public, max-age=0');
+ }
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/serve-static/master
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-static?branch=master
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/serve-static/master?label=linux
+[github-actions-ci-url]: https://github.com/expressjs/serve-static/actions/workflows/ci.yml
+[node-image]: https://badgen.net/npm/node/serve-static
+[node-url]: https://nodejs.org/en/download/
+[npm-downloads-image]: https://badgen.net/npm/dm/serve-static
+[npm-url]: https://npmjs.org/package/serve-static
+[npm-version-image]: https://badgen.net/npm/v/serve-static
diff --git a/astro/src/content/resources/en/middleware/session.md b/astro/src/content/resources/en/middleware/session.md
new file mode 100644
index 0000000000..90f3837a42
--- /dev/null
+++ b/astro/src/content/resources/en/middleware/session.md
@@ -0,0 +1,1046 @@
+---
+title: Express session middleware
+module: session
+---
+
+# express-session
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][node-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install express-session
+```
+
+## API
+
+```js
+var session = require('express-session');
+```
+
+### session(options)
+
+Create a session middleware with the given `options`.
+
+**Note** Session data is _not_ saved in the cookie itself, just the session ID.
+Session data is stored server-side.
+
+**Note** Since version 1.5.0, the [`cookie-parser` middleware](https://www.npmjs.com/package/cookie-parser)
+no longer needs to be used for this module to work. This module now directly reads
+and writes cookies on `req`/`res`. Using `cookie-parser` may result in issues
+if the `secret` is not the same between this module and `cookie-parser`.
+
+**Warning** The default server-side session storage, `MemoryStore`, is _purposely_
+not designed for a production environment. It will leak memory under most
+conditions, does not scale past a single process, and is meant for debugging and
+developing.
+
+For a list of stores, see [compatible session stores](#compatible-session-stores).
+
+#### Options
+
+`express-session` accepts these properties in the options object.
+
+##### cookie
+
+Settings object for the session ID cookie. The default value is
+`{ path: '/', httpOnly: true, secure: false, maxAge: null }`.
+
+The following are options that can be set in this object.
+
+##### cookie.domain
+
+Specifies the value for the `Domain` `Set-Cookie` attribute. By default, no domain
+is set, and most clients will consider the cookie to apply to only the current
+domain.
+
+##### cookie.expires
+
+Specifies the `Date` object to be the value for the `Expires` `Set-Cookie` attribute.
+By default, no expiration is set, and most clients will consider this a
+"non-persistent cookie" and will delete it on a condition like exiting a web browser
+application.
+
+**Note** If both `expires` and `maxAge` are set in the options, then the last one
+defined in the object is what is used.
+
+**Note** The `expires` option should not be set directly; instead only use the `maxAge`
+option.
+
+##### cookie.httpOnly
+
+Specifies the `boolean` value for the `HttpOnly` `Set-Cookie` attribute. When truthy,
+the `HttpOnly` attribute is set, otherwise it is not. By default, the `HttpOnly`
+attribute is set.
+
+**Note** be careful when setting this to `true`, as compliant clients will not allow
+client-side JavaScript to see the cookie in `document.cookie`.
+
+##### cookie.maxAge
+
+Specifies the `number` (in milliseconds) to use when calculating the `Expires`
+`Set-Cookie` attribute. This is done by taking the current server time and adding
+`maxAge` milliseconds to the value to calculate an `Expires` datetime. By default,
+no maximum age is set.
+
+**Note** If both `expires` and `maxAge` are set in the options, then the last one
+defined in the object is what is used.
+
+##### cookie.partitioned
+
+Specifies the `boolean` value for the [`Partitioned` `Set-Cookie`](rfc-cutler-httpbis-partitioned-cookies)
+attribute. When truthy, the `Partitioned` attribute is set, otherwise it is not.
+By default, the `Partitioned` attribute is not set.
+
+**Note** This is an attribute that has not yet been fully standardized, and may
+change in the future. This also means many clients may ignore this attribute until
+they understand it.
+
+More information about can be found in [the proposal](https://github.com/privacycg/CHIPS).
+
+##### cookie.path
+
+Specifies the value for the `Path` `Set-Cookie`. By default, this is set to `'/'`, which
+is the root path of the domain.
+
+##### cookie.priority
+
+Specifies the `string` to be the value for the [`Priority` `Set-Cookie` attribute][rfc-west-cookie-priority-00-4.1].
+
+- `'low'` will set the `Priority` attribute to `Low`.
+- `'medium'` will set the `Priority` attribute to `Medium`, the default priority when not set.
+- `'high'` will set the `Priority` attribute to `High`.
+
+More information about the different priority levels can be found in
+[the specification][rfc-west-cookie-priority-00-4.1].
+
+**Note** This is an attribute that has not yet been fully standardized, and may change in the future.
+This also means many clients may ignore this attribute until they understand it.
+
+##### cookie.sameSite
+
+Specifies the `boolean` or `string` to be the value for the `SameSite` `Set-Cookie` attribute.
+By default, this is `false`.
+
+- `true` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
+- `false` will not set the `SameSite` attribute.
+- `'lax'` will set the `SameSite` attribute to `Lax` for lax same site enforcement.
+- `'none'` will set the `SameSite` attribute to `None` for an explicit cross-site cookie.
+- `'strict'` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
+
+More information about the different enforcement levels can be found in
+[the specification][rfc-6265bis-03-4.1.2.7].
+
+**Note** This is an attribute that has not yet been fully standardized, and may change in
+the future. This also means many clients may ignore this attribute until they understand it.
+
+**Note** There is a [draft spec](https://tools.ietf.org/html/draft-west-cookie-incrementalism-01)
+that requires that the `Secure` attribute be set to `true` when the `SameSite` attribute has been
+set to `'none'`. Some web browsers or other clients may be adopting this specification.
+
+##### cookie.secure
+
+Specifies the `boolean` value for the `Secure` `Set-Cookie` attribute. When truthy,
+the `Secure` attribute is set, otherwise it is not. By default, the `Secure`
+attribute is not set.
+
+**Note** be careful when setting this to `true`, as compliant clients will not send
+the cookie back to the server in the future if the browser does not have an HTTPS
+connection.
+
+Please note that `secure: true` is a **recommended** option. However, it requires
+an https-enabled website, i.e., HTTPS is necessary for secure cookies. If `secure`
+is set, and you access your site over HTTP, the cookie will not be set. If you
+have your node.js behind a proxy and are using `secure: true`, you need to set
+"trust proxy" in express:
+
+```js
+var app = express();
+app.set('trust proxy', 1); // trust first proxy
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ cookie: { secure: true },
+ })
+);
+```
+
+For using secure cookies in production, but allowing for testing in development,
+the following is an example of enabling this setup based on `NODE_ENV` in express:
+
+```js
+var app = express();
+var sess = {
+ secret: 'keyboard cat',
+ cookie: {},
+};
+
+if (app.get('env') === 'production') {
+ app.set('trust proxy', 1); // trust first proxy
+ sess.cookie.secure = true; // serve secure cookies
+}
+
+app.use(session(sess));
+```
+
+The `cookie.secure` option can also be set to the special value `'auto'` to have
+this setting automatically match the determined security of the connection. Be
+careful when using this setting if the site is available both as HTTP and HTTPS,
+as once the cookie is set on HTTPS, it will no longer be visible over HTTP. This
+is useful when the Express `"trust proxy"` setting is properly setup to simplify
+development vs production configuration.
+
+##### genid
+
+Function to call to generate a new session ID. Provide a function that returns
+a string that will be used as a session ID. The function is given `req` as the
+first argument if you want to use some value attached to `req` when generating
+the ID.
+
+The default value is a function which uses the `uid-safe` library to generate IDs.
+
+**NOTE** be careful to generate unique IDs so your sessions do not conflict.
+
+```js
+app.use(
+ session({
+ genid: function (req) {
+ return genuuid(); // use UUIDs for session IDs
+ },
+ secret: 'keyboard cat',
+ })
+);
+```
+
+##### name
+
+The name of the session ID cookie to set in the response (and read from in the
+request).
+
+The default value is `'connect.sid'`.
+
+**Note** if you have multiple apps running on the same hostname (this is just
+the name, i.e. `localhost` or `127.0.0.1`; different schemes and ports do not
+name a different hostname), then you need to separate the session cookies from
+each other. The simplest method is to simply set different `name`s per app.
+
+##### proxy
+
+Trust the reverse proxy when setting secure cookies (via the "X-Forwarded-Proto"
+header).
+
+The default value is `undefined`.
+
+- `true` The "X-Forwarded-Proto" header will be used.
+- `false` All headers are ignored and the connection is considered secure only
+ if there is a direct TLS/SSL connection.
+- `undefined` Uses the "trust proxy" setting from express
+
+##### resave
+
+Forces the session to be saved back to the session store, even if the session
+was never modified during the request. Depending on your store this may be
+necessary, but it can also create race conditions where a client makes two
+parallel requests to your server and changes made to the session in one
+request may get overwritten when the other request ends, even if it made no
+changes (this behavior also depends on what store you're using).
+
+The default value is `true`, but using the default has been deprecated,
+as the default will change in the future. Please research into this setting
+and choose what is appropriate to your use-case. Typically, you'll want
+`false`.
+
+How do I know if this is necessary for my store? The best way to know is to
+check with your store if it implements the `touch` method. If it does, then
+you can safely set `resave: false`. If it does not implement the `touch`
+method and your store sets an expiration date on stored sessions, then you
+likely need `resave: true`.
+
+##### rolling
+
+Force the session identifier cookie to be set on every response. The expiration
+is reset to the original [`maxAge`](#cookiemaxage), resetting the expiration
+countdown.
+
+The default value is `false`.
+
+With this enabled, the session identifier cookie will expire in
+[`maxAge`](#cookiemaxage) since the last response was sent instead of in
+[`maxAge`](#cookiemaxage) since the session was last modified by the server.
+
+This is typically used in conjunction with short, non-session-length
+[`maxAge`](#cookiemaxage) values to provide a quick timeout of the session data
+with reduced potential of it occurring during on going server interactions.
+
+**Note** When this option is set to `true` but the `saveUninitialized` option is
+set to `false`, the cookie will not be set on a response with an uninitialized
+session. This option only modifies the behavior when an existing session was
+loaded for the request.
+
+##### saveUninitialized
+
+Forces a session that is "uninitialized" to be saved to the store. A session is
+uninitialized when it is new but not modified. Choosing `false` is useful for
+implementing login sessions, reducing server storage usage, or complying with
+laws that require permission before setting a cookie. Choosing `false` will also
+help with race conditions where a client makes multiple parallel requests
+without a session.
+
+The default value is `true`, but using the default has been deprecated, as the
+default will change in the future. Please research into this setting and
+choose what is appropriate to your use-case.
+
+**Note** if you are using Session in conjunction with PassportJS, Passport
+will add an empty Passport object to the session for use after a user is
+authenticated, which will be treated as a modification to the session, causing
+it to be saved. _This has been fixed in PassportJS 0.3.0_
+
+##### secret
+
+**Required option**
+
+This is the secret used to sign the session ID cookie. The secret can be any type
+of value that is supported by Node.js `crypto.createHmac` (like a string or a
+`Buffer`). This can be either a single secret, or an array of multiple secrets. If
+an array of secrets is provided, only the first element will be used to sign the
+session ID cookie, while all the elements will be considered when verifying the
+signature in requests. The secret itself should be not easily parsed by a human and
+would best be a random set of characters. A best practice may include:
+
+- The use of environment variables to store the secret, ensuring the secret itself
+ does not exist in your repository.
+- Periodic updates of the secret, while ensuring the previous secret is in the
+ array.
+
+Using a secret that cannot be guessed will reduce the ability to hijack a session to
+only guessing the session ID (as determined by the `genid` option).
+
+Changing the secret value will invalidate all existing sessions. In order to rotate
+the secret without invalidating sessions, provide an array of secrets, with the new
+secret as first element of the array, and including previous secrets as the later
+elements.
+
+**Note** HMAC-256 is used to sign the session ID. For this reason, the secret should
+contain at least 32 bytes of entropy.
+
+##### store
+
+The session store instance, defaults to a new `MemoryStore` instance.
+
+##### unset
+
+Control the result of unsetting `req.session` (through `delete`, setting to `null`,
+etc.).
+
+The default value is `'keep'`.
+
+- `'destroy'` The session will be destroyed (deleted) when the response ends.
+- `'keep'` The session in the store will be kept, but modifications made during
+ the request are ignored and not saved.
+
+### req.session
+
+To store or access session data, simply use the request property `req.session`,
+which is (generally) serialized as JSON by the store, so nested objects
+are typically fine. For example below is a user-specific view counter:
+
+```js
+// Use the session middleware
+app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 } }));
+
+// Access the session as req.session
+app.get('/', function (req, res, next) {
+ if (req.session.views) {
+ req.session.views++;
+ res.setHeader('Content-Type', 'text/html');
+ res.write('views: ' + req.session.views + '
');
+ res.write('expires in: ' + req.session.cookie.maxAge / 1000 + 's
');
+ res.end();
+ } else {
+ req.session.views = 1;
+ res.end('welcome to the session demo. refresh!');
+ }
+});
+```
+
+#### Session.regenerate(callback)
+
+To regenerate the session simply invoke the method. Once complete,
+a new SID and `Session` instance will be initialized at `req.session`
+and the `callback` will be invoked.
+
+```js
+req.session.regenerate(function (err) {
+ // will have a new session here
+});
+```
+
+#### Session.destroy(callback)
+
+Destroys the session and will unset the `req.session` property.
+Once complete, the `callback` will be invoked.
+
+```js
+req.session.destroy(function (err) {
+ // cannot access session here
+});
+```
+
+#### Session.reload(callback)
+
+Reloads the session data from the store and re-populates the
+`req.session` object. Once complete, the `callback` will be invoked.
+
+```js
+req.session.reload(function (err) {
+ // session updated
+});
+```
+
+#### Session.save(callback)
+
+Save the session back to the store, replacing the contents on the store with the
+contents in memory (though a store may do something else--consult the store's
+documentation for exact behavior).
+
+This method is automatically called at the end of the HTTP response if the
+session data has been altered (though this behavior can be altered with various
+options in the middleware constructor). Because of this, typically this method
+does not need to be called.
+
+There are some cases where it is useful to call this method, for example,
+redirects, long-lived requests or in WebSockets.
+
+```js
+req.session.save(function (err) {
+ // session saved
+});
+```
+
+#### Session.touch()
+
+Updates the `.maxAge` property. Typically this is
+not necessary to call, as the session middleware does this for you.
+
+### req.session.id
+
+Each session has a unique ID associated with it. This property is an
+alias of [`req.sessionID`](#reqsessionid-1) and cannot be modified.
+It has been added to make the session ID accessible from the `session`
+object.
+
+### req.session.cookie
+
+Each session has a unique cookie object accompany it. This allows
+you to alter the session cookie per visitor. For example we can
+set `req.session.cookie.expires` to `false` to enable the cookie
+to remain for only the duration of the user-agent.
+
+#### Cookie.maxAge
+
+Alternatively `req.session.cookie.maxAge` will return the time
+remaining in milliseconds, which we may also re-assign a new value
+to adjust the `.expires` property appropriately. The following
+are essentially equivalent
+
+```js
+var hour = 3600000;
+req.session.cookie.expires = new Date(Date.now() + hour);
+req.session.cookie.maxAge = hour;
+```
+
+For example when `maxAge` is set to `60000` (one minute), and 30 seconds
+has elapsed it will return `30000` until the current request has completed,
+at which time `req.session.touch()` is called to reset
+`req.session.cookie.maxAge` to its original value.
+
+```js
+req.session.cookie.maxAge; // => 30000
+```
+
+#### Cookie.originalMaxAge
+
+The `req.session.cookie.originalMaxAge` property returns the original
+`maxAge` (time-to-live), in milliseconds, of the session cookie.
+
+### req.sessionID
+
+To get the ID of the loaded session, access the request property
+`req.sessionID`. This is simply a read-only value set when a session
+is loaded/created.
+
+## Session Store Implementation
+
+Every session store _must_ be an `EventEmitter` and implement specific
+methods. The following methods are the list of **required**, **recommended**,
+and **optional**.
+
+- Required methods are ones that this module will always call on the store.
+- Recommended methods are ones that this module will call on the store if
+ available.
+- Optional methods are ones this module does not call at all, but helps
+ present uniform stores to users.
+
+For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo.
+
+### store.all(callback)
+
+**Optional**
+
+This optional method is used to get all sessions in the store as an array. The
+`callback` should be called as `callback(error, sessions)`.
+
+### store.destroy(sid, callback)
+
+**Required**
+
+This required method is used to destroy/delete a session from the store given
+a session ID (`sid`). The `callback` should be called as `callback(error)` once
+the session is destroyed.
+
+### store.clear(callback)
+
+**Optional**
+
+This optional method is used to delete all sessions from the store. The
+`callback` should be called as `callback(error)` once the store is cleared.
+
+### store.length(callback)
+
+**Optional**
+
+This optional method is used to get the count of all sessions in the store.
+The `callback` should be called as `callback(error, len)`.
+
+### store.get(sid, callback)
+
+**Required**
+
+This required method is used to get a session from the store given a session
+ID (`sid`). The `callback` should be called as `callback(error, session)`.
+
+The `session` argument should be a session if found, otherwise `null` or
+`undefined` if the session was not found (and there was no error). A special
+case is made when `error.code === 'ENOENT'` to act like `callback(null, null)`.
+
+### store.set(sid, session, callback)
+
+**Required**
+
+This required method is used to upsert a session into the store given a
+session ID (`sid`) and session (`session`) object. The callback should be
+called as `callback(error)` once the session has been set in the store.
+
+### store.touch(sid, session, callback)
+
+**Recommended**
+
+This recommended method is used to "touch" a given session given a
+session ID (`sid`) and session (`session`) object. The `callback` should be
+called as `callback(error)` once the session has been touched.
+
+This is primarily used when the store will automatically delete idle sessions
+and this method is used to signal to the store the given session is active,
+potentially resetting the idle timer.
+
+## Compatible Session Stores
+
+The following modules implement a session store that is compatible with this
+module. Please make a PR to add additional modules :)
+
+[![★][aerospike-session-store-image] aerospike-session-store][aerospike-session-store-url] A session store using [Aerospike](http://www.aerospike.com/).
+
+[aerospike-session-store-url]: https://www.npmjs.com/package/aerospike-session-store
+[aerospike-session-store-image]: https://badgen.net/github/stars/aerospike/aerospike-session-store-expressjs?label=%E2%98%85
+
+[![★][better-sqlite3-session-store-image] better-sqlite3-session-store][better-sqlite3-session-store-url] A session store based on [better-sqlite3](https://github.com/JoshuaWise/better-sqlite3).
+
+[better-sqlite3-session-store-url]: https://www.npmjs.com/package/better-sqlite3-session-store
+[better-sqlite3-session-store-image]: https://badgen.net/github/stars/timdaub/better-sqlite3-session-store?label=%E2%98%85
+
+[![★][cassandra-store-image] cassandra-store][cassandra-store-url] An Apache Cassandra-based session store.
+
+[cassandra-store-url]: https://www.npmjs.com/package/cassandra-store
+[cassandra-store-image]: https://badgen.net/github/stars/webcc/cassandra-store?label=%E2%98%85
+
+[![★][cluster-store-image] cluster-store][cluster-store-url] A wrapper for using in-process / embedded
+stores - such as SQLite (via knex), leveldb, files, or memory - with node cluster (desirable for Raspberry Pi 2
+and other multi-core embedded devices).
+
+[cluster-store-url]: https://www.npmjs.com/package/cluster-store
+[cluster-store-image]: https://badgen.net/github/stars/coolaj86/cluster-store?label=%E2%98%85
+
+[![★][connect-arango-image] connect-arango][connect-arango-url] An ArangoDB-based session store.
+
+[connect-arango-url]: https://www.npmjs.com/package/connect-arango
+[connect-arango-image]: https://badgen.net/github/stars/AlexanderArvidsson/connect-arango?label=%E2%98%85
+
+[![★][connect-azuretables-image] connect-azuretables][connect-azuretables-url] An [Azure Table Storage](https://azure.microsoft.com/en-gb/services/storage/tables/)-based session store.
+
+[connect-azuretables-url]: https://www.npmjs.com/package/connect-azuretables
+[connect-azuretables-image]: https://badgen.net/github/stars/mike-goodwin/connect-azuretables?label=%E2%98%85
+
+[![★][connect-cloudant-store-image] connect-cloudant-store][connect-cloudant-store-url] An [IBM Cloudant](https://cloudant.com/)-based session store.
+
+[connect-cloudant-store-url]: https://www.npmjs.com/package/connect-cloudant-store
+[connect-cloudant-store-image]: https://badgen.net/github/stars/adriantanasa/connect-cloudant-store?label=%E2%98%85
+
+[![★][connect-cosmosdb-image] connect-cosmosdb][connect-cosmosdb-url] An Azure [Cosmos DB](https://azure.microsoft.com/en-us/products/cosmos-db/)-based session store.
+
+[connect-cosmosdb-url]: https://www.npmjs.com/package/connect-cosmosdb
+[connect-cosmosdb-image]: https://badgen.net/github/stars/thekillingspree/connect-cosmosdb?label=%E2%98%85
+
+[![★][connect-couchbase-image] connect-couchbase][connect-couchbase-url] A [couchbase](http://www.couchbase.com/)-based session store.
+
+[connect-couchbase-url]: https://www.npmjs.com/package/connect-couchbase
+[connect-couchbase-image]: https://badgen.net/github/stars/christophermina/connect-couchbase?label=%E2%98%85
+
+[![★][connect-datacache-image] connect-datacache][connect-datacache-url] An [IBM Bluemix Data Cache](http://www.ibm.com/cloud-computing/bluemix/)-based session store.
+
+[connect-datacache-url]: https://www.npmjs.com/package/connect-datacache
+[connect-datacache-image]: https://badgen.net/github/stars/adriantanasa/connect-datacache?label=%E2%98%85
+
+[![★][@google-cloud/connect-datastore-image] @google-cloud/connect-datastore][@google-cloud/connect-datastore-url] A [Google Cloud Datastore](https://cloud.google.com/datastore/docs/concepts/overview)-based session store.
+
+[@google-cloud/connect-datastore-url]: https://www.npmjs.com/package/@google-cloud/connect-datastore
+[@google-cloud/connect-datastore-image]: https://badgen.net/github/stars/GoogleCloudPlatform/cloud-datastore-session-node?label=%E2%98%85
+
+[![★][connect-db2-image] connect-db2][connect-db2-url] An IBM DB2-based session store built using [ibm_db](https://www.npmjs.com/package/ibm_db) module.
+
+[connect-db2-url]: https://www.npmjs.com/package/connect-db2
+[connect-db2-image]: https://badgen.net/github/stars/wallali/connect-db2?label=%E2%98%85
+
+[![★][connect-dynamodb-image] connect-dynamodb][connect-dynamodb-url] A DynamoDB-based session store.
+
+[connect-dynamodb-url]: https://www.npmjs.com/package/connect-dynamodb
+[connect-dynamodb-image]: https://badgen.net/github/stars/ca98am79/connect-dynamodb?label=%E2%98%85
+
+[![★][@google-cloud/connect-firestore-image] @google-cloud/connect-firestore][@google-cloud/connect-firestore-url] A [Google Cloud Firestore](https://cloud.google.com/firestore/docs/overview)-based session store.
+
+[@google-cloud/connect-firestore-url]: https://www.npmjs.com/package/@google-cloud/connect-firestore
+[@google-cloud/connect-firestore-image]: https://badgen.net/github/stars/googleapis/nodejs-firestore-session?label=%E2%98%85
+
+[![★][connect-hazelcast-image] connect-hazelcast][connect-hazelcast-url] Hazelcast session store for Connect and Express.
+
+[connect-hazelcast-url]: https://www.npmjs.com/package/connect-hazelcast
+[connect-hazelcast-image]: https://badgen.net/github/stars/huseyinbabal/connect-hazelcast?label=%E2%98%85
+
+[![★][connect-loki-image] connect-loki][connect-loki-url] A Loki.js-based session store.
+
+[connect-loki-url]: https://www.npmjs.com/package/connect-loki
+[connect-loki-image]: https://badgen.net/github/stars/Requarks/connect-loki?label=%E2%98%85
+
+[![★][connect-lowdb-image] connect-lowdb][connect-lowdb-url] A lowdb-based session store.
+
+[connect-lowdb-url]: https://www.npmjs.com/package/connect-lowdb
+[connect-lowdb-image]: https://badgen.net/github/stars/travishorn/connect-lowdb?label=%E2%98%85
+
+[![★][connect-memcached-image] connect-memcached][connect-memcached-url] A memcached-based session store.
+
+[connect-memcached-url]: https://www.npmjs.com/package/connect-memcached
+[connect-memcached-image]: https://badgen.net/github/stars/balor/connect-memcached?label=%E2%98%85
+
+[![★][connect-memjs-image] connect-memjs][connect-memjs-url] A memcached-based session store using
+[memjs](https://www.npmjs.com/package/memjs) as the memcached client.
+
+[connect-memjs-url]: https://www.npmjs.com/package/connect-memjs
+[connect-memjs-image]: https://badgen.net/github/stars/liamdon/connect-memjs?label=%E2%98%85
+
+[![★][connect-ml-image] connect-ml][connect-ml-url] A MarkLogic Server-based session store.
+
+[connect-ml-url]: https://www.npmjs.com/package/connect-ml
+[connect-ml-image]: https://badgen.net/github/stars/bluetorch/connect-ml?label=%E2%98%85
+
+[![★][connect-monetdb-image] connect-monetdb][connect-monetdb-url] A MonetDB-based session store.
+
+[connect-monetdb-url]: https://www.npmjs.com/package/connect-monetdb
+[connect-monetdb-image]: https://badgen.net/github/stars/MonetDB/npm-connect-monetdb?label=%E2%98%85
+
+[![★][connect-mongo-image] connect-mongo][connect-mongo-url] A MongoDB-based session store.
+
+[connect-mongo-url]: https://www.npmjs.com/package/connect-mongo
+[connect-mongo-image]: https://badgen.net/github/stars/kcbanner/connect-mongo?label=%E2%98%85
+
+[![★][connect-mongodb-session-image] connect-mongodb-session][connect-mongodb-session-url] Lightweight MongoDB-based session store built and maintained by MongoDB.
+
+[connect-mongodb-session-url]: https://www.npmjs.com/package/connect-mongodb-session
+[connect-mongodb-session-image]: https://badgen.net/github/stars/mongodb-js/connect-mongodb-session?label=%E2%98%85
+
+[![★][connect-mssql-v2-image] connect-mssql-v2][connect-mssql-v2-url] A Microsoft SQL Server-based session store based on [connect-mssql](https://www.npmjs.com/package/connect-mssql).
+
+[connect-mssql-v2-url]: https://www.npmjs.com/package/connect-mssql-v2
+[connect-mssql-v2-image]: https://badgen.net/github/stars/jluboff/connect-mssql-v2?label=%E2%98%85
+
+[![★][connect-neo4j-image] connect-neo4j][connect-neo4j-url] A [Neo4j](https://neo4j.com)-based session store.
+
+[connect-neo4j-url]: https://www.npmjs.com/package/connect-neo4j
+[connect-neo4j-image]: https://badgen.net/github/stars/MaxAndersson/connect-neo4j?label=%E2%98%85
+
+[![★][connect-ottoman-image] connect-ottoman][connect-ottoman-url] A [couchbase ottoman](http://www.couchbase.com/)-based session store.
+
+[connect-ottoman-url]: https://www.npmjs.com/package/connect-ottoman
+[connect-ottoman-image]: https://badgen.net/github/stars/noiissyboy/connect-ottoman?label=%E2%98%85
+
+[![★][connect-pg-simple-image] connect-pg-simple][connect-pg-simple-url] A PostgreSQL-based session store.
+
+[connect-pg-simple-url]: https://www.npmjs.com/package/connect-pg-simple
+[connect-pg-simple-image]: https://badgen.net/github/stars/voxpelli/node-connect-pg-simple?label=%E2%98%85
+
+[![★][connect-redis-image] connect-redis][connect-redis-url] A Redis-based session store.
+
+[connect-redis-url]: https://www.npmjs.com/package/connect-redis
+[connect-redis-image]: https://badgen.net/github/stars/tj/connect-redis?label=%E2%98%85
+
+[![★][connect-session-firebase-image] connect-session-firebase][connect-session-firebase-url] A session store based on the [Firebase Realtime Database](https://firebase.google.com/docs/database/)
+
+[connect-session-firebase-url]: https://www.npmjs.com/package/connect-session-firebase
+[connect-session-firebase-image]: https://badgen.net/github/stars/benweier/connect-session-firebase?label=%E2%98%85
+
+[![★][connect-session-knex-image] connect-session-knex][connect-session-knex-url] A session store using
+[Knex.js](http://knexjs.org/), which is a SQL query builder for PostgreSQL, MySQL, MariaDB, SQLite3, and Oracle.
+
+[connect-session-knex-url]: https://www.npmjs.com/package/connect-session-knex
+[connect-session-knex-image]: https://badgen.net/github/stars/llambda/connect-session-knex?label=%E2%98%85
+
+[![★][connect-session-sequelize-image] connect-session-sequelize][connect-session-sequelize-url] A session store using
+[Sequelize.js](http://sequelizejs.com/), which is a Node.js / io.js ORM for PostgreSQL, MySQL, SQLite and MSSQL.
+
+[connect-session-sequelize-url]: https://www.npmjs.com/package/connect-session-sequelize
+[connect-session-sequelize-image]: https://badgen.net/github/stars/mweibel/connect-session-sequelize?label=%E2%98%85
+
+[![★][connect-sqlite3-image] connect-sqlite3][connect-sqlite3-url] A [SQLite3](https://github.com/mapbox/node-sqlite3) session store modeled after the TJ's `connect-redis` store.
+
+[connect-sqlite3-url]: https://www.npmjs.com/package/connect-sqlite3
+[connect-sqlite3-image]: https://badgen.net/github/stars/rawberg/connect-sqlite3?label=%E2%98%85
+
+[![★][connect-typeorm-image] connect-typeorm][connect-typeorm-url] A [TypeORM](https://github.com/typeorm/typeorm)-based session store.
+
+[connect-typeorm-url]: https://www.npmjs.com/package/connect-typeorm
+[connect-typeorm-image]: https://badgen.net/github/stars/makepost/connect-typeorm?label=%E2%98%85
+
+[![★][couchdb-expression-image] couchdb-expression][couchdb-expression-url] A [CouchDB](https://couchdb.apache.org/)-based session store.
+
+[couchdb-expression-url]: https://www.npmjs.com/package/couchdb-expression
+[couchdb-expression-image]: https://badgen.net/github/stars/tkshnwesper/couchdb-expression?label=%E2%98%85
+
+[![★][dynamodb-store-image] dynamodb-store][dynamodb-store-url] A DynamoDB-based session store.
+
+[dynamodb-store-url]: https://www.npmjs.com/package/dynamodb-store
+[dynamodb-store-image]: https://badgen.net/github/stars/rafaelrpinto/dynamodb-store?label=%E2%98%85
+
+[![★][dynamodb-store-v3-image] dynamodb-store-v3][dynamodb-store-v3-url] Implementation of a session store using DynamoDB backed by the [AWS SDK for JavaScript v3](https://github.com/aws/aws-sdk-js-v3).
+
+[dynamodb-store-v3-url]: https://www.npmjs.com/package/dynamodb-store-v3
+[dynamodb-store-v3-image]: https://badgen.net/github/stars/FryDay/dynamodb-store-v3?label=%E2%98%85
+
+[![★][express-etcd-image] express-etcd][express-etcd-url] An [etcd](https://github.com/stianeikeland/node-etcd) based session store.
+
+[express-etcd-url]: https://www.npmjs.com/package/express-etcd
+[express-etcd-image]: https://badgen.net/github/stars/gildean/express-etcd?label=%E2%98%85
+
+[![★][express-mysql-session-image] express-mysql-session][express-mysql-session-url] A session store using native
+[MySQL](https://www.mysql.com/) via the [node-mysql](https://github.com/felixge/node-mysql) module.
+
+[express-mysql-session-url]: https://www.npmjs.com/package/express-mysql-session
+[express-mysql-session-image]: https://badgen.net/github/stars/chill117/express-mysql-session?label=%E2%98%85
+
+[![★][express-nedb-session-image] express-nedb-session][express-nedb-session-url] A NeDB-based session store.
+
+[express-nedb-session-url]: https://www.npmjs.com/package/express-nedb-session
+[express-nedb-session-image]: https://badgen.net/github/stars/louischatriot/express-nedb-session?label=%E2%98%85
+
+[![★][express-oracle-session-image] express-oracle-session][express-oracle-session-url] A session store using native
+[oracle](https://www.oracle.com/) via the [node-oracledb](https://www.npmjs.com/package/oracledb) module.
+
+[express-oracle-session-url]: https://www.npmjs.com/package/express-oracle-session
+[express-oracle-session-image]: https://badgen.net/github/stars/slumber86/express-oracle-session?label=%E2%98%85
+
+[![★][express-session-cache-manager-image] express-session-cache-manager][express-session-cache-manager-url]
+A store that implements [cache-manager](https://www.npmjs.com/package/cache-manager), which supports
+a [variety of storage types](https://www.npmjs.com/package/cache-manager#store-engines).
+
+[express-session-cache-manager-url]: https://www.npmjs.com/package/express-session-cache-manager
+[express-session-cache-manager-image]: https://badgen.net/github/stars/theogravity/express-session-cache-manager?label=%E2%98%85
+
+[![★][express-session-etcd3-image] express-session-etcd3][express-session-etcd3-url] An [etcd3](https://github.com/mixer/etcd3) based session store.
+
+[express-session-etcd3-url]: https://www.npmjs.com/package/express-session-etcd3
+[express-session-etcd3-image]: https://badgen.net/github/stars/willgm/express-session-etcd3?label=%E2%98%85
+
+[![★][express-session-level-image] express-session-level][express-session-level-url] A [LevelDB](https://github.com/Level/levelup) based session store.
+
+[express-session-level-url]: https://www.npmjs.com/package/express-session-level
+[express-session-level-image]: https://badgen.net/github/stars/tgohn/express-session-level?label=%E2%98%85
+
+[![★][express-session-rsdb-image] express-session-rsdb][express-session-rsdb-url] Session store based on Rocket-Store: A very simple, super fast and yet powerful, flat file database.
+
+[express-session-rsdb-url]: https://www.npmjs.com/package/express-session-rsdb
+[express-session-rsdb-image]: https://badgen.net/github/stars/paragi/express-session-rsdb?label=%E2%98%85
+
+[![★][express-sessions-image] express-sessions][express-sessions-url] A session store supporting both MongoDB and Redis.
+
+[express-sessions-url]: https://www.npmjs.com/package/express-sessions
+[express-sessions-image]: https://badgen.net/github/stars/konteck/express-sessions?label=%E2%98%85
+
+[![★][firestore-store-image] firestore-store][firestore-store-url] A [Firestore](https://github.com/hendrysadrak/firestore-store)-based session store.
+
+[firestore-store-url]: https://www.npmjs.com/package/firestore-store
+[firestore-store-image]: https://badgen.net/github/stars/hendrysadrak/firestore-store?label=%E2%98%85
+
+[![★][fortune-session-image] fortune-session][fortune-session-url] A [Fortune.js](https://github.com/fortunejs/fortune)
+based session store. Supports all backends supported by Fortune (MongoDB, Redis, Postgres, NeDB).
+
+[fortune-session-url]: https://www.npmjs.com/package/fortune-session
+[fortune-session-image]: https://badgen.net/github/stars/aliceklipper/fortune-session?label=%E2%98%85
+
+[![★][hazelcast-store-image] hazelcast-store][hazelcast-store-url] A Hazelcast-based session store built on the [Hazelcast Node Client](https://www.npmjs.com/package/hazelcast-client).
+
+[hazelcast-store-url]: https://www.npmjs.com/package/hazelcast-store
+[hazelcast-store-image]: https://badgen.net/github/stars/jackspaniel/hazelcast-store?label=%E2%98%85
+
+[![★][level-session-store-image] level-session-store][level-session-store-url] A LevelDB-based session store.
+
+[level-session-store-url]: https://www.npmjs.com/package/level-session-store
+[level-session-store-image]: https://badgen.net/github/stars/toddself/level-session-store?label=%E2%98%85
+
+[![★][lowdb-session-store-image] lowdb-session-store][lowdb-session-store-url] A [lowdb](https://www.npmjs.com/package/lowdb)-based session store.
+
+[lowdb-session-store-url]: https://www.npmjs.com/package/lowdb-session-store
+[lowdb-session-store-image]: https://badgen.net/github/stars/fhellwig/lowdb-session-store?label=%E2%98%85
+
+[![★][medea-session-store-image] medea-session-store][medea-session-store-url] A Medea-based session store.
+
+[medea-session-store-url]: https://www.npmjs.com/package/medea-session-store
+[medea-session-store-image]: https://badgen.net/github/stars/BenjaminVadant/medea-session-store?label=%E2%98%85
+
+[![★][memorystore-image] memorystore][memorystore-url] A memory session store made for production.
+
+[memorystore-url]: https://www.npmjs.com/package/memorystore
+[memorystore-image]: https://badgen.net/github/stars/roccomuso/memorystore?label=%E2%98%85
+
+[![★][mssql-session-store-image] mssql-session-store][mssql-session-store-url] A SQL Server-based session store.
+
+[mssql-session-store-url]: https://www.npmjs.com/package/mssql-session-store
+[mssql-session-store-image]: https://badgen.net/github/stars/jwathen/mssql-session-store?label=%E2%98%85
+
+[![★][nedb-session-store-image] nedb-session-store][nedb-session-store-url] An alternate NeDB-based (either in-memory or file-persisted) session store.
+
+[nedb-session-store-url]: https://www.npmjs.com/package/nedb-session-store
+[nedb-session-store-image]: https://badgen.net/github/stars/JamesMGreene/nedb-session-store?label=%E2%98%85
+
+[![★][@quixo3/prisma-session-store-image] @quixo3/prisma-session-store][@quixo3/prisma-session-store-url] A session store for the [Prisma Framework](https://www.prisma.io).
+
+[@quixo3/prisma-session-store-url]: https://www.npmjs.com/package/@quixo3/prisma-session-store
+[@quixo3/prisma-session-store-image]: https://badgen.net/github/stars/kleydon/prisma-session-store?label=%E2%98%85
+
+[![★][restsession-image] restsession][restsession-url] Store sessions utilizing a RESTful API
+
+[restsession-url]: https://www.npmjs.com/package/restsession
+[restsession-image]: https://badgen.net/github/stars/jankal/restsession?label=%E2%98%85
+
+[![★][sequelstore-connect-image] sequelstore-connect][sequelstore-connect-url] A session store using [Sequelize.js](http://sequelizejs.com/).
+
+[sequelstore-connect-url]: https://www.npmjs.com/package/sequelstore-connect
+[sequelstore-connect-image]: https://badgen.net/github/stars/MattMcFarland/sequelstore-connect?label=%E2%98%85
+
+[![★][session-file-store-image] session-file-store][session-file-store-url] A file system-based session store.
+
+[session-file-store-url]: https://www.npmjs.com/package/session-file-store
+[session-file-store-image]: https://badgen.net/github/stars/valery-barysok/session-file-store?label=%E2%98%85
+
+[![★][session-pouchdb-store-image] session-pouchdb-store][session-pouchdb-store-url] Session store for PouchDB / CouchDB. Accepts embedded, custom, or remote PouchDB instance and realtime synchronization.
+
+[session-pouchdb-store-url]: https://www.npmjs.com/package/session-pouchdb-store
+[session-pouchdb-store-image]: https://badgen.net/github/stars/solzimer/session-pouchdb-store?label=%E2%98%85
+
+[![★][@cyclic.sh/session-store-image] @cyclic.sh/session-store][@cyclic.sh/session-store-url] A DynamoDB-based session store for [Cyclic.sh](https://www.cyclic.sh/) apps.
+
+[@cyclic.sh/session-store-url]: https://www.npmjs.com/package/@cyclic.sh/session-store
+[@cyclic.sh/session-store-image]: https://badgen.net/github/stars/cyclic-software/session-store?label=%E2%98%85
+
+[![★][@databunker/session-store-image] @databunker/session-store][@databunker/session-store-url] A [Databunker](https://databunker.org/)-based encrypted session store.
+
+[@databunker/session-store-url]: https://www.npmjs.com/package/@databunker/session-store
+[@databunker/session-store-image]: https://badgen.net/github/stars/securitybunker/databunker-session-store?label=%E2%98%85
+
+[![★][sessionstore-image] sessionstore][sessionstore-url] A session store that works with various databases.
+
+[sessionstore-url]: https://www.npmjs.com/package/sessionstore
+[sessionstore-image]: https://badgen.net/github/stars/adrai/sessionstore?label=%E2%98%85
+
+[![★][tch-nedb-session-image] tch-nedb-session][tch-nedb-session-url] A file system session store based on NeDB.
+
+[tch-nedb-session-url]: https://www.npmjs.com/package/tch-nedb-session
+[tch-nedb-session-image]: https://badgen.net/github/stars/tomaschyly/NeDBSession?label=%E2%98%85
+
+## Examples
+
+### View counter
+
+A simple example using `express-session` to store page views for a user.
+
+```js
+var express = require('express');
+var parseurl = require('parseurl');
+var session = require('express-session');
+
+var app = express();
+
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ })
+);
+
+app.use(function (req, res, next) {
+ if (!req.session.views) {
+ req.session.views = {};
+ }
+
+ // get the url pathname
+ var pathname = parseurl(req).pathname;
+
+ // count the views
+ req.session.views[pathname] = (req.session.views[pathname] || 0) + 1;
+
+ next();
+});
+
+app.get('/foo', function (req, res, next) {
+ res.send('you viewed this page ' + req.session.views['/foo'] + ' times');
+});
+
+app.get('/bar', function (req, res, next) {
+ res.send('you viewed this page ' + req.session.views['/bar'] + ' times');
+});
+
+app.listen(3000);
+```
+
+### User login
+
+A simple example using `express-session` to keep a user log in session.
+
+```js
+var escapeHtml = require('escape-html');
+var express = require('express');
+var session = require('express-session');
+
+var app = express();
+
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ })
+);
+
+// middleware to test if authenticated
+function isAuthenticated(req, res, next) {
+ if (req.session.user) next();
+ else next('route');
+}
+
+app.get('/', isAuthenticated, function (req, res) {
+ // this is only called when there is an authentication user due to isAuthenticated
+ res.send('hello, ' + escapeHtml(req.session.user) + '!' + ' Logout ');
+});
+
+app.get('/', function (req, res) {
+ res.send(
+ ''
+ );
+});
+
+app.post('/login', express.urlencoded({ extended: false }), function (req, res) {
+ // login logic to validate req.body.user and req.body.pass
+ // would be implemented here. for this example any combo works
+
+ // regenerate the session, which is good practice to help
+ // guard against forms of session fixation
+ req.session.regenerate(function (err) {
+ if (err) next(err);
+
+ // store user information in session, typically a user id
+ req.session.user = req.body.user;
+
+ // save the session before redirection to ensure page
+ // load does not happen before session is saved
+ req.session.save(function (err) {
+ if (err) return next(err);
+ res.redirect('/');
+ });
+ });
+});
+
+app.get('/logout', function (req, res, next) {
+ // logout logic
+
+ // clear the user from the session object and save.
+ // this will ensure that re-using the old session id
+ // does not have a logged in user
+ req.session.user = null;
+ req.session.save(function (err) {
+ if (err) next(err);
+
+ // regenerate the session, which is good practice to help
+ // guard against forms of session fixation
+ req.session.regenerate(function (err) {
+ if (err) next(err);
+ res.redirect('/');
+ });
+ });
+});
+
+app.listen(3000);
+```
+
+## Debugging
+
+This module uses the [debug](https://www.npmjs.com/package/debug) module
+internally to log information about session operations.
+
+To see all the internal logs, set the `DEBUG` environment variable to
+`express-session` when launching your app (`npm start`, in this example):
+
+```sh
+$ DEBUG=express-session npm start
+```
+
+On Windows, use the corresponding command;
+
+```sh
+> set DEBUG=express-session & npm start
+```
+
+## License
+
+[MIT](LICENSE)
+
+[rfc-6265bis-03-4.1.2.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7
+[rfc-cutler-httpbis-partitioned-cookies]: https://tools.ietf.org/html/draft-cutler-httpbis-partitioned-cookies/
+[rfc-west-cookie-priority-00-4.1]: https://tools.ietf.org/html/draft-west-cookie-priority-00#section-4.1
+[ci-image]: https://badgen.net/github/checks/expressjs/session/master?label=ci
+[ci-url]: https://github.com/expressjs/session/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/session/master
+[coveralls-url]: https://coveralls.io/r/expressjs/session?branch=master
+[node-url]: https://nodejs.org/en/download
+[npm-downloads-image]: https://badgen.net/npm/dm/express-session
+[npm-url]: https://npmjs.org/package/express-session
+[npm-version-image]: https://badgen.net/npm/v/express-session
diff --git a/astro/src/content/resources/en/middleware/timeout.md b/astro/src/content/resources/en/middleware/timeout.md
new file mode 100644
index 0000000000..f6057aedfd
--- /dev/null
+++ b/astro/src/content/resources/en/middleware/timeout.md
@@ -0,0 +1,176 @@
+---
+title: Express timeout middleware
+module: timeout
+---
+
+# connect-timeout
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][travis-image]][travis-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Times out a request in the Connect/Express application framework.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install connect-timeout
+```
+
+## API
+
+**NOTE** This module is not recommend as a "top-level" middleware (i.e.
+`app.use(timeout('5s'))`) unless you take precautions to halt your own
+middleware processing. See [as top-level middleware](#as-top-level-middleware)
+for how to use as a top-level middleware.
+
+While the library will emit a 'timeout' event when requests exceed the given
+timeout, node will continue processing the slow request until it terminates.
+Slow requests will continue to use CPU and memory, even if you are returning
+a HTTP response in the timeout callback. For better control over CPU/memory,
+you may need to find the events that are taking a long time (3rd party HTTP
+requests, disk I/O, database calls) and find a way to cancel them, and/or
+close the attached sockets.
+
+### timeout(time, [options])
+
+Returns middleware that times out in `time` milliseconds. `time` can also
+be a string accepted by the [ms](https://www.npmjs.org/package/ms#readme)
+module. On timeout, `req` will emit `"timeout"`.
+
+#### Options
+
+The `timeout` function takes an optional `options` object that may contain
+any of the following keys:
+
+##### respond
+
+Controls if this module will "respond" in the form of forwarding an error.
+If `true`, the timeout error is passed to `next()` so that you may customize
+the response behavior. This error has a `.timeout` property as well as
+`.status == 503`. This defaults to `true`.
+
+### req.clearTimeout()
+
+Clears the timeout on the request. The timeout is completely removed and
+will not fire for this request in the future.
+
+### req.timedout
+
+`true` if timeout fired; `false` otherwise.
+
+## Examples
+
+### as top-level middleware
+
+Because of the way middleware processing works, once this module
+passes the request to the next middleware (which it has to do in order
+for you to do work), it can no longer stop the flow, so you must take
+care to check if the request has timedout before you continue to act
+on the request.
+
+```javascript
+var bodyParser = require('body-parser');
+var cookieParser = require('cookie-parser');
+var express = require('express');
+var timeout = require('connect-timeout');
+
+// example of using this top-level; note the use of haltOnTimedout
+// after every middleware; it will stop the request flow on a timeout
+var app = express();
+app.use(timeout('5s'));
+app.use(bodyParser());
+app.use(haltOnTimedout);
+app.use(cookieParser());
+app.use(haltOnTimedout);
+
+// Add your routes here, etc.
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+app.listen(3000);
+```
+
+### express 3.x
+
+```javascript
+var express = require('express');
+var bodyParser = require('body-parser');
+var timeout = require('connect-timeout');
+
+var app = express();
+app.post('/save', timeout('5s'), bodyParser.json(), haltOnTimedout, function (req, res, next) {
+ savePost(req.body, function (err, id) {
+ if (err) return next(err);
+ if (req.timedout) return;
+ res.send('saved as id ' + id);
+ });
+});
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+function savePost(post, cb) {
+ setTimeout(
+ function () {
+ cb(null, (Math.random() * 40000) >>> 0);
+ },
+ (Math.random() * 7000) >>> 0
+ );
+}
+
+app.listen(3000);
+```
+
+### connect
+
+```javascript
+var bodyParser = require('body-parser');
+var connect = require('connect');
+var timeout = require('connect-timeout');
+
+var app = connect();
+app.use('/save', timeout('5s'), bodyParser.json(), haltOnTimedout, function (req, res, next) {
+ savePost(req.body, function (err, id) {
+ if (err) return next(err);
+ if (req.timedout) return;
+ res.send('saved as id ' + id);
+ });
+});
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+function savePost(post, cb) {
+ setTimeout(
+ function () {
+ cb(null, (Math.random() * 40000) >>> 0);
+ },
+ (Math.random() * 7000) >>> 0
+ );
+}
+
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/connect-timeout.svg
+[npm-url]: https://npmjs.org/package/connect-timeout
+[travis-image]: https://img.shields.io/travis/expressjs/timeout/master.svg
+[travis-url]: https://travis-ci.org/expressjs/timeout
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/timeout/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/timeout?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/connect-timeout.svg
+[downloads-url]: https://npmjs.org/package/connect-timeout
diff --git a/astro/src/content/resources/en/middleware/vhost.md b/astro/src/content/resources/en/middleware/vhost.md
new file mode 100644
index 0000000000..72f49d7f93
--- /dev/null
+++ b/astro/src/content/resources/en/middleware/vhost.md
@@ -0,0 +1,174 @@
+---
+title: Express vhost middleware
+module: vhost
+---
+
+# vhost
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Install
+
+```sh
+$ npm install vhost
+```
+
+## API
+
+```js
+var vhost = require('vhost');
+```
+
+### vhost(hostname, handle)
+
+Create a new middleware function to hand off request to `handle` when the incoming
+host for the request matches `hostname`. The function is called as
+`handle(req, res, next)`, like a standard middleware.
+
+`hostname` can be a string or a RegExp object. When `hostname` is a string it can
+contain `*` to match 1 or more characters in that section of the hostname. When
+`hostname` is a RegExp, it will be forced to case-insensitive (since hostnames are)
+and will be forced to match based on the start and end of the hostname.
+
+When host is matched and the request is sent down to a vhost handler, the `req.vhost`
+property will be populated with an object. This object will have numeric properties
+corresponding to each wildcard (or capture group if RegExp object provided) and the
+`hostname` that was matched.
+
+```js
+var connect = require('connect');
+var vhost = require('vhost');
+var app = connect();
+
+app.use(
+ vhost('*.*.example.com', function handle(req, res, next) {
+ // for match of "foo.bar.example.com:8080" against "*.*.example.com":
+ console.dir(req.vhost.host); // => 'foo.bar.example.com:8080'
+ console.dir(req.vhost.hostname); // => 'foo.bar.example.com'
+ console.dir(req.vhost.length); // => 2
+ console.dir(req.vhost[0]); // => 'foo'
+ console.dir(req.vhost[1]); // => 'bar'
+ })
+);
+```
+
+## Examples
+
+### using with connect for static serving
+
+```js
+var connect = require('connect');
+var serveStatic = require('serve-static');
+var vhost = require('vhost');
+
+var mailapp = connect();
+
+// add middlewares to mailapp for mail.example.com
+
+// create app to serve static files on subdomain
+var staticapp = connect();
+staticapp.use(serveStatic('public'));
+
+// create main app
+var app = connect();
+
+// add vhost routing to main app for mail
+app.use(vhost('mail.example.com', mailapp));
+
+// route static assets for "assets-*" subdomain to get
+// around max host connections limit on browsers
+app.use(vhost('assets-*.example.com', staticapp));
+
+// add middlewares and main usage to app
+
+app.listen(3000);
+```
+
+### using with connect for user subdomains
+
+```js
+var connect = require('connect');
+var serveStatic = require('serve-static');
+var vhost = require('vhost');
+
+var mainapp = connect();
+
+// add middlewares to mainapp for the main web site
+
+// create app that will server user content from public/{username}/
+var userapp = connect();
+
+userapp.use(function (req, res, next) {
+ var username = req.vhost[0]; // username is the "*"
+
+ // pretend request was for /{username}/* for file serving
+ req.originalUrl = req.url;
+ req.url = '/' + username + req.url;
+
+ next();
+});
+userapp.use(serveStatic('public'));
+
+// create main app
+var app = connect();
+
+// add vhost routing for main app
+app.use(vhost('userpages.local', mainapp));
+app.use(vhost('www.userpages.local', mainapp));
+
+// listen on all subdomains for user pages
+app.use(vhost('*.userpages.local', userapp));
+
+app.listen(3000);
+```
+
+### using with any generic request handler
+
+```js
+var connect = require('connect');
+var http = require('http');
+var vhost = require('vhost');
+
+// create main app
+var app = connect();
+
+app.use(
+ vhost('mail.example.com', function (req, res) {
+ // handle req + res belonging to mail.example.com
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello from mail!');
+ })
+);
+
+// an external api server in any framework
+var httpServer = http.createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello from the api!');
+});
+
+app.use(
+ vhost('api.example.com', function (req, res) {
+ // handle req + res belonging to api.example.com
+ // pass the request to a standard Node.js HTTP server
+ httpServer.emit('request', req, res);
+ })
+);
+
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/vhost.svg
+[npm-url]: https://npmjs.org/package/vhost
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/vhost/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/vhost
+[downloads-image]: https://img.shields.io/npm/dm/vhost.svg
+[downloads-url]: https://npmjs.org/package/vhost
+[github-actions-ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/vhost/ci.yml?branch=master&label=ci
+[github-actions-ci-url]: https://github.com/expressjs/vhost/actions/workflows/ci.yml
diff --git a/astro/src/content/resources/en/utils.md b/astro/src/content/resources/en/utils.md
new file mode 100644
index 0000000000..546b2f09b4
--- /dev/null
+++ b/astro/src/content/resources/en/utils.md
@@ -0,0 +1,22 @@
+---
+title: Express utilities
+description: Discover utility modules related to Express.js and Node.js, including tools for cookies, CSRF protection, URL parsing, routing, and more to enhance your applications.
+---
+
+## Express utility functions
+
+The [pillarjs](https://github.com/pillarjs) GitHub organization contains a number of modules
+for utility functions that may be generally useful.
+
+| Utility modules | Description |
+| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| [cookies](https://www.npmjs.com/package/cookies) | Get and set HTTP(S) cookies that can be signed to prevent tampering, using Keygrip. Can be used with the Node.js HTTP library or as Express middleware. |
+| [csrf](https://www.npmjs.com/package/csrf) | Contains the logic behind CSRF token creation and verification. Use this module to create custom CSRF middleware. |
+| [finalhandler](https://www.npmjs.com/package/finalhandler) | Function to invoke as the final step to respond to HTTP request. |
+| [parseurl](https://www.npmjs.com/package/parseurl) | Parse a URL with caching. |
+| [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) | Turn an Express-style path string such as ``/user/:name` into a regular expression. |
+| [resolve-path](https://www.npmjs.com/package/resolve-path) | Resolves a relative path against a root path with validation. |
+| [router](https://www.npmjs.com/package/router) | Simple middleware-style router. |
+| [send](https://www.npmjs.com/package/send) | Library for streaming files as a HTTP response, with support for partial responses (ranges), conditional-GET negotiation, and granular events. |
+
+For additional low-level HTTP-related modules, see [jshttp](https://github.com/jshttp).
diff --git a/astro/src/content/resources/es/community.md b/astro/src/content/resources/es/community.md
new file mode 100755
index 0000000000..e40d97e421
--- /dev/null
+++ b/astro/src/content/resources/es/community.md
@@ -0,0 +1,70 @@
+---
+title: Express community
+description: Connect with the Express.js community, learn about the technical committee, find resources, explore community-contributed modules, and get involved in discussions.
+---
+
+# Community
+
+## Technical committee
+
+The Express technical committee meets online every two weeks (as needed) to discuss development and maintenance of Express,
+and other issues relevant to the Express project. Each meeting is typically announced in an
+[expressjs/discussions issue](https://github.com/expressjs/discussions/issues) with a link to join or view the meeting, which is
+open to all observers.
+
+The meetings are recorded; for a list of the recordings, see the [Express.js YouTube channel](https://www.youtube.com/channel/UCYjxjAeH6TRik9Iwy5nXw7g).
+
+Members of the Express technical committee are:
+
+**Active:**
+
+- [@blakeembrey](https://github.com/blakeembrey) - Blake Embrey
+- [@crandmck](https://github.com/crandmck) - Rand McKinney
+- [@LinusU](https://github.com/LinusU) - Linus Unnebäck
+- [@ulisesgascon](https://github.com/ulisesGascon) - Ulises Gascón
+- [@sheplu](https://github.com/sheplu) - Jean Burellier
+- [@wesleytodd](https://github.com/wesleytodd) - Wes Todd
+- [@jonchurch](https://github.com/jonchurch) - Jon Church
+- [@ctcpip](https://github.com/ctcpip/) - Chris de Almeida
+
+**Inactive:**
+
+- [@dougwilson](https://github.com/dougwilson) - Douglas Wilson
+- [@hacksparrow](https://github.com/hacksparrow) - Hage Yaapa
+- [@jonathanong](https://github.com/jonathanong) - jongleberry
+- [@niftylettuce](https://github.com/niftylettuce) - niftylettuce
+- [@troygoode](https://github.com/troygoode) - Troy Goode
+
+## Express is made of many modules
+
+Our vibrant community has created a large variety of extensions,
+[middleware modules](/en/resources/middleware) and higher-level frameworks.
+
+Additionally, the Express community maintains modules in these two GitHub orgs:
+
+- [jshttp](https://github.com/jshttp) modules providing useful utility functions; see [Utility modules](/en/resources/utils).
+- [pillarjs](https://github.com/pillarjs): low-level modules that Express uses internally.
+
+To keep up with what is going on in the whole community, check out the [ExpressJS StatusBoard](https://expressjs.github.io/statusboard/).
+
+## Issues
+
+If you've come across what you think is a bug, or just want to make
+a feature request open a ticket in the [issue queue](https://github.com/expressjs/express/issues).
+
+## Examples
+
+View dozens of Express application [examples](https://github.com/expressjs/express/tree/master/examples)
+in the repository covering everything from API design and authentication to template engine integration.
+
+## Github Discussions
+
+The [GitHub Discussions](https://github.com/expressjs/discussions) section is an excellent space to engage in conversations about the development and maintenance of Express, as well as to share ideas and discuss topics related to its usage.
+
+# Branding of Express.js
+
+## Express.js Logo
+
+Express is a project of the OpenJS Foundation. Please review the [trademark policy](https://trademark-policy.openjsf.org/) for information about permissible use of Express.js logos and marks.
+
+
diff --git a/astro/src/content/resources/es/contributing.md b/astro/src/content/resources/es/contributing.md
new file mode 100644
index 0000000000..96c92467ee
--- /dev/null
+++ b/astro/src/content/resources/es/contributing.md
@@ -0,0 +1,482 @@
+---
+title: Contributing to Express
+description: Find out how to contribute to Express.js, including guidelines for reporting issues, submitting pull requests, becoming a collaborator, and understanding security policies.
+---
+
+# Contributing to Express
+
+### Looking to contribute to Expressjs.com? Click [here](#expressjs-website-contributing).
+
+Express and the other projects in the [expressjs organization on GitHub](https://github.com/expressjs) are projects of the [OpenJs Foundation](https://openjsf.org/).
+These projects are governed under the general policies and guidelines of the Node.js Foundation along with the additional guidelines below.
+
+- [Technical committee](#technical-committee)
+- [Community contributing guide](#community-contributing-guide)
+- [Collaborator's guide](#collaborators-guide)
+- [Security policies and procedures](#security-policies-and-procedures)
+
+## Technical committee
+
+The Express technical committee consists of active project members, and guides development and maintenance of the Express project. For more information, see [Express Community - Technical committee](/en/resources/community#technical-committee).
+
+## Community contributing guide
+
+
+
+The goal of this document is to create a contribution process that:
+
+- Encourages new contributions.
+- Encourages contributors to remain involved.
+- Avoids unnecessary processes and bureaucracy whenever possible.
+- Creates a transparent decision making process that makes it clear how
+ contributors can be involved in decision making.
+
+### Vocabulary
+
+- A **Contributor** is any individual creating or commenting on an issue or pull request.
+- A **Committer** is a subset of contributors who have been given write access to the repository.
+- A **Project Captain** is the lead maintainer of a repository.
+- A **TC (Technical Committee)** is a group of committers representing the required technical
+ expertise to resolve rare disputes.
+- A **Triager** is a subset of contributors who have been given triage access to the repository.
+
+### Logging Issues
+
+Log an issue for any question or problem you might have. When in doubt, log an issue, and
+any additional policies about what to include will be provided in the responses. The only
+exception is security disclosures which should be sent privately.
+
+Committers may direct you to another repository, ask for additional clarifications, and
+add appropriate metadata before the issue is addressed.
+
+Please be courteous and respectful. Every participant is expected to follow the
+project's Code of Conduct.
+
+### Contributions
+
+Any change to resources in this repository must be through pull requests. This applies to all changes
+to documentation, code, binary files, etc. Even long term committers and TC members must use
+pull requests.
+
+No pull request can be merged without being reviewed.
+
+For non-trivial contributions, pull requests should sit for at least 36 hours to ensure that
+contributors in other timezones have time to review. Consideration should also be given to
+weekends and other holiday periods to ensure active committers all have reasonable time to
+become involved in the discussion and review process if they wish.
+
+The default for each contribution is that it is accepted once no committer has an objection.
+During a review, committers may also request that a specific contributor who is most versed in a
+particular area gives a "LGTM" before the PR can be merged. There is no additional "sign off"
+process for contributions to land. Once all issues brought by committers are addressed it can
+be landed by any committer.
+
+In the case of an objection being raised in a pull request by another committer, all involved
+committers should seek to arrive at a consensus by way of addressing concerns being expressed
+by discussion, compromise on the proposed change, or withdrawal of the proposed change.
+
+If a contribution is controversial and committers cannot agree about how to get it to land
+or if it should land then it should be escalated to the TC. TC members should regularly
+discuss pending contributions in order to find a resolution. It is expected that only a
+small minority of issues be brought to the TC for resolution and that discussion and
+compromise among committers be the default resolution mechanism.
+
+### Becoming a Triager
+
+Anyone can become a triager! Read more about the process of being a triager in
+[the triage process document](https://github.com/expressjs/discussions/blob/master/Triager-Guide.md).
+
+Currently, any existing [organization member](https://github.com/orgs/expressjs/people) can nominate
+a new triager. If you are interested in becoming a triager, our best advice is to actively participate
+in the community by helping triaging issues and pull requests. As well we recommend
+to engage in other community activities like attending the TC meetings, and participating in the Slack
+discussions. If you feel ready and have been helping triage some issues, reach out to an active member of the organization to ask if they'd
+be willing to support you. If they agree, they can create a pull request to formalize your nomination. In the case of an objection to the nomination, the triage team is responsible for working with the individuals involved and finding a resolution.
+
+You can also reach out to any of the [organization members](https://github.com/orgs/expressjs/people)
+if you have questions or need guidance.
+
+### Becoming a Committer
+
+All contributors who have landed significant and valuable contributions should be onboarded in a timely manner,
+and added as a committer, and be given write access to the repository.
+
+Committers are expected to follow this policy and continue to send pull requests, go through
+proper review, and have other committers merge their pull requests.
+
+### TC Process
+
+The TC uses a "consensus seeking" process for issues that are escalated to the TC.
+The group tries to find a resolution that has no open objections among TC members.
+If a consensus cannot be reached that has no objections then a majority wins vote
+is called. It is also expected that the majority of decisions made by the TC are via
+a consensus seeking process and that voting is only used as a last-resort.
+
+Resolution may involve returning the issue to project captains with suggestions on
+how to move forward towards a consensus. It is not expected that a meeting of the TC
+will resolve all issues on its agenda during that meeting and may prefer to continue
+the discussion happening among the project captains.
+
+Members can be added to the TC at any time. Any TC member can nominate another committer
+to the TC and the TC uses its standard consensus seeking process to evaluate whether or
+not to add this new member. The TC will consist of a minimum of 3 active members and a
+maximum of 10. If the TC should drop below 5 members the active TC members should nominate
+someone new. If a TC member is stepping down, they are encouraged (but not required) to
+nominate someone to take their place.
+
+TC members will be added as admin's on the Github orgs, npm orgs, and other resources as
+necessary to be effective in the role.
+
+To remain "active" a TC member should have participation within the last 12 months and miss
+no more than six consecutive TC meetings. Our goal is to increase participation, not punish
+people for any lack of participation, this guideline should be only be used as such
+(replace an inactive member with a new active one, for example). Members who do not meet this
+are expected to step down. If A TC member does not step down, an issue can be opened in the
+discussions repo to move them to inactive status. TC members who step down or are removed due
+to inactivity will be moved into inactive status.
+
+Inactive status members can become active members by self nomination if the TC is not already
+larger than the maximum of 10. They will also be given preference if, while at max size, an
+active member steps down.
+
+### Project Captains
+
+The Express TC can designate captains for individual projects/repos in the
+organizations. These captains are responsible for being the primary
+day-to-day maintainers of the repo on a technical and community front.
+Repo captains are empowered with repo ownership and package publication rights.
+When there are conflicts, especially on topics that effect the Express project
+at large, captains are responsible to raise it up to the TC and drive
+those conflicts to resolution. Captains are also responsible for making sure
+community members follow the community guidelines, maintaining the repo
+and the published package, as well as in providing user support.
+
+Like TC members, Repo captains are a subset of committers.
+
+To become a captain for a project the candidate is expected to participate in that
+project for at least 6 months as a committer prior to the request. They should have
+helped with code contributions as well as triaging issues. They are also required to
+have 2FA enabled on both their GitHub and npm accounts.
+
+Any TC member or an existing captain on the **same** repo can nominate another committer
+to the captain role. To do so, they should submit a PR to this document, updating the
+**Active Project Captains** section (while maintaining the sort order) with the project
+name, the nominee's GitHub handle, and their npm username (if different).
+
+- Repos can have as many captains as make sense for the scope of work.
+- A TC member or an existing repo captain **on the same project** can nominate a new captain.
+ Repo captains from other projects should not nominate captains for a different project.
+
+The PR will require at least 2 approvals from TC members and 2 weeks hold time to allow
+for comment and/or dissent. When the PR is merged, a TC member will add them to the
+proper GitHub/npm groups.
+
+#### Active Projects and Captains
+
+The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members)
+
+#### Current Initiative Captains
+
+The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains)
+
+### Inactivity and Emeritus Policy for Any Role
+
+To support the health and continuity of the project, all individuals holding a role within the community (such as Triager, Committer, WG member, Project Captain, or TC member) are encouraged to maintain active participation.
+
+Inactivity is defined as the absence of meaningful involvement in the project—such as contributions, code reviews, triage, meeting attendance, or discussion participation—for a continuous period of 6 months.
+
+#### Exceptions
+
+Anyone may request a temporary leave from active participation due to personal or professional reasons. In such cases, the individual should inform the relevant team or the Technical Committee (TC). During this time, the inactivity policy is paused, and the individual will not be flagged as inactive.
+
+#### Inactivity Process
+
+- If someone is deemed inactive, the individual may be transitioned to an emeritus role that reflects their past contributions. A best effort will be made to inform them that this has occurred. They may request to be reinstated when they are ready to be active again.
+- The emeritus status helps preserve a clear record of contributors who have meaningfully shaped the project over time.
+
+#### Accountability
+
+- The Technical Committee (TC) and the respective captains of each package/team are responsible for assessing activity levels and enacting this policy fairly and transparently, in coordination with other relevant teams.
+- In case of disagreement, the situation can be discussed and resolved by consensus within the TC or appropriate team.
+
+### Developer's Certificate of Origin 1.1
+
+```text
+By making a contribution to this project, I certify that:
+
+ (a) The contribution was created in whole or in part by me and I
+ have the right to submit it under the open source license
+ indicated in the file; or
+
+ (b) The contribution is based upon previous work that, to the best
+ of my knowledge, is covered under an appropriate open source
+ license and I have the right under that license to submit that
+ work with modifications, whether created in whole or in part
+ by me, under the same open source license (unless I am
+ permitted to submit under a different license), as indicated
+ in the file; or
+
+ (c) The contribution was provided directly to me by some other
+ person who certified (a), (b) or (c) and I have not modified
+ it.
+
+ (d) I understand and agree that this project and the contribution
+ are public and that a record of the contribution (including all
+ personal information I submit with it, including my sign-off) is
+ maintained indefinitely and may be redistributed consistent with
+ this project or the open source license(s) involved.
+```
+
+## Collaborator's guide
+
+
+
+### Website Issues
+
+Open issues for the expressjs.com website in https://github.com/expressjs/expressjs.com.
+
+For issues in other Express managed repos (everything in `expressjs`, `pillarjs` or `jshttp` other than `expressjs/express`), be sure to check their contributing guide and open issues and PRs in the appropriate repository.
+
+### PRs and Code contributions
+
+- Tests must pass.
+- Follow the [JavaScript Standard Style](https://standardjs.com/) and `npm run lint`.
+- If you fix a bug, add a test.
+
+### Branches
+
+Use the `master` branch for bug fixes or minor work that is intended for the
+current release stream.
+
+Use the correspondingly named branch, e.g. `6.x`, for anything intended for
+a future release of Express.
+
+### Steps for contributing
+
+1. Create an issue for the
+ bug you want to fix or the feature that you want to add.
+2. Create your own fork on GitHub, then
+ checkout your fork.
+3. Write your code in your local copy. It's good practice to create a branch for
+ each new issue you work on, although not compulsory.
+4. To run the test suite, first install the dependencies by running `npm install`,
+ then run `npm test`.
+5. Ensure your code is linted by running `npm run lint` -- fix any issue you
+ see listed.
+6. If the tests pass, you can commit your changes to your fork and then create
+ a pull request from there. Make sure to reference your issue from the pull
+ request comments by including the issue number e.g. `#123`.
+
+### Issues which are questions
+
+We will typically close any vague issues or questions that are specific to some
+app you are writing. Please double check the docs and other references before
+being trigger happy with posting a question issue.
+
+Things that will help get your question issue looked at:
+
+- Full and runnable JS code.
+- Clear description of the problem or unexpected behavior.
+- Clear description of the expected result.
+- Steps you have taken to debug it yourself.
+
+If you post a question and do not outline the above items or make it easy for
+us to understand and reproduce your issue, it will be closed.
+
+If your question meets all of the above requirements but you do not believe it needs to be looked at
+by the maintainers
+(for example, if you are just looking for community input) please open it as a discussion topic instead
+of an issue. If you
+are unsure and open an issue, we may move it to discussions if we triage them and decide they do
+not need high
+visibility or maintainer input.
+
+## Security Policies and Procedures
+
+
+
+This document outlines security procedures and general policies for the Express
+project.
+
+- [Reporting a Bug](#reporting-a-bug)
+- [Disclosure Policy](#disclosure-policy)
+- [Comments on this Policy](#comments-on-this-policy)
+
+### Reporting a Bug
+
+The Express team and community take all security bugs in Express seriously.
+Thank you for improving the security of Express. We appreciate your efforts and
+responsible disclosure and will make every effort to acknowledge your
+contributions.
+
+Report security bugs by emailing `express-security@lists.openjsf.org`.
+
+To ensure the timely response to your report, please ensure that the entirety
+of the report is contained within the email body and not solely behind a web
+link or an attachment.
+
+The lead maintainer will acknowledge your email within 48 hours, and will send a
+more detailed response within 48 hours indicating the next steps in handling
+your report. After the initial reply to your report, the security team will
+endeavor to keep you informed of the progress towards a fix and full
+announcement, and may ask for additional information or guidance.
+
+Report security bugs in third-party modules to the person or team maintaining
+the module.
+
+### Pre-release Versions
+
+Alpha and Beta releases are unstable and **not suitable for production use**.
+Vulnerabilities found in pre-releases should be reported according to the [Reporting a Bug](#reporting-a-bug) section.
+Due to the unstable nature of the branch it is not guaranteed that any fixes will be released in the next pre-release.
+
+### Disclosure Policy
+
+When the security team receives a security bug report, they will assign it to a
+primary handler. This person will coordinate the fix and release process,
+involving the following steps:
+
+- Confirm the problem and determine the affected versions.
+- Audit code to find any potential similar problems.
+- Prepare fixes for all releases still under maintenance. These fixes will be
+ released as fast as possible to npm.
+
+### The Express Threat Model
+
+We are currently working on a new version of the security model, the most updated version can be found [here](https://github.com/expressjs/security-wg/blob/main/docs/ThreatModel.md)
+
+### Comments on this Policy
+
+If you have suggestions on how this process could be improved please submit a
+pull request.
+
+---
+
+# Contributing to Expressjs.com {#expressjs-website-contributing}
+
+
+
+### The Official Documentation of the Express.js Framework
+
+This is the contribution documentation for the [expressjs.com](https://github.com/expressjs/expressjs.com) website.
+
+#### Need some ideas? These are some typical issues.
+
+1. **Website issues**: If you see anything on the site that could use a tune-up, think about how to fix it.
+ - Display or screen sizing problems
+ - Mobile responsiveness issues
+ - Missing or broken accessibility features
+ - Website outages
+ - Broken links
+ - Page structure or user interface enhancements
+
+2. **Content Issues**: Fix anything related to site content or typos.
+ - Spelling errors
+ - Incorrect/outdated Express.js documentation
+ - Missing content
+
+3. **Translation Issues**: Fix any translation errors or contribute new content.
+ - Fix spelling errors
+ - Fix incorrect/poorly translated words
+ - Check out the [Contributing translations](#contributing-translations) section below for a contributing guide.
+
+#### Want to work on a backlog issue?
+
+We often have bugs or enhancements that need work. You can find these under our repo's [Issues tab](https://github.com/expressjs/expressjs.com/issues). Check out the tags to find something that's a good match for you.
+
+#### Have an idea? Found a bug?
+
+If you've found a bug or a typo, or if you have an idea for an enhancement, you can:
+
+- Submit a [new issue](https://github.com/expressjs/expressjs.com/issues/new/choose) on our repo. Do this for larger proposals, or if you'd like to discuss or get feedback first.
+
+- Make a [GitHub pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). If you have already done work, and it's ready to go, feel free to send it our way.
+
+## Getting Started
+
+The steps below will guide you through the Expressjs.com contribution process.
+
+#### Step 1: (OPTIONAL) Open a New Issue
+
+So you've found a problem that you want to fix, or have a site enhancement you want to make.
+
+1. If you want to get feedback or discuss, open a discussion [issue](https://github.com/expressjs/expressjs.com/issues/new/choose) prior to starting work. This is not required, but encouraged for larger proposals.
+ - While we highly encourage this step, it is only for submissions proposing significant change. It helps us to clarify and focus the work, and ensure it aligns with overall project priorities.
+ - For submissions proposing minor improvements or corrections, this is not needed. You can skip this step.
+ - When opening an issue please give it a title and fill in the description section. The more details you provide, the more feedback we can give.
+
+2. After receiving your issue the Express.js documentation team will respond with feedback. We read every submission and always try to respond quickly with feedback.
+ - For submissions proposing significant change, we encourage you to follow the review process before starting work.
+
+#### Step 2: Get the Application Code Base
+
+Clone the repo and get the code:
+
+```sh
+git clone https://github.com/expressjs/expressjs.com.git
+```
+
+After you've got the code you're ready to start making your changes!
+
+But just in case you need a little extra explanation, this section below outlines the main sections of the code base, where most changes are likely to be made.
+
+**Markdown Page Files**:
+
+- These files render to html and make up the individual pages of the site. Most of the site's documentation text content is written in `md` files.
+- Change these to make changes to individual pages' content/text or markup.
+- Each language has its own complete set of pages, located under their respective language directories - all the Spanish markdown content is found in the `es` directory, for example.
+
+**Includes Partials and Layout Templates**
+
+- `_includes` are partials that are imported and reused across multiple pages.
+ - These are used to import text content for reuse across pages, such as the API documentation, e.g., `_includes > api > en > 5x`, which is included in every language.
+ - These are used to include the page components that make up site-wide user interface and periphery structure, e.g., Header, Footer, etc.
+- `_layouts` are the templates used to wrap the site's individual pages.
+ - These are used to display the structure of the site's periphery, such as the header and footer, and for injecting and displaying individual markdown pages inside the `content` tag.
+
+**Blog Markdown Files**
+
+- These files make up the individual blog posts. If you want to contribute a blog post please
+ follow the specific instructions for [How to write a blog post.](https://expressjs.com/en/blog/write-post)
+- Located under the `_posts` directory.
+
+**CSS or Javascript**
+
+- All css and js files are kept in `css` and `js` folders on the project root.
+
+The Express.js website is built using [Jekyll](https://jekyllrb.com/) and is hosted on [GitHub Pages](https://pages.github.com/).
+
+#### Step 3: Running the Application
+
+Now you'll need a way to see your changes, which means you'll need a running version of the application. You have two options.
+
+1. **Run Locally**: This gets the local version of the application up and running on your machine. Follow our [Local Setup Guide](https://github.com/expressjs/expressjs.com?tab=readme-ov-file#build-the-website-locally) to use this option.
+ - This is the recommended option for moderate to complex work.
+
+2. **Run using Deploy Preview**: Use this option if you don't want to bother with a local installation. Part of our continuous integration pipeline includes [Netlify Deploy Preview](https://docs.netlify.com/deploy/deploy-types/deploy-previews/).
+ 1. To use this you'll need to get your changes online - after you've made your first commit on your feature branch, make a _draft_ pull request.
+ 2. After the build steps are complete, you'll have access to a **Deploy Preview** tab that will run your changes on the web, rebuilding after each commit is pushed.
+ 3. After you are completely done your work, and it's ready for review, remove the draft status on your pull request and submit your work.
+
+## Contributing translations
+
+We use Crowdin to manage our translations in multiple languages and achieve automatic translation with artificial intelligence. Since these translations can be inefficient in some cases, we need help from the community to provide accurate and helpful translations.
+
+The documentation is translated into these languages:
+
+- Chinese Simplified (`zh-cn`)
+- Chinese Traditional (`zh-tw`)
+- English (`en`)
+- French (`fr`)
+- German (`de`)
+- Italian (`it`)
+- Japanese (`ja`)
+- Korean (`ko`)
+- Brazilian Portuguese (`pt-br`)
+- Spanish (`es`)
+
+### How to translate
+
+1. Request to join the Express.js Website project on [Crowdin](https://express.crowdin.com/website)
+2. [Select the language you want to translate](https://support.crowdin.com/for-translators/#starting-translation)
+3. [Start translating](https://support.crowdin.com/online-editor/)
diff --git a/astro/src/content/resources/es/glossary.md b/astro/src/content/resources/es/glossary.md
new file mode 100755
index 0000000000..8b45bf01eb
--- /dev/null
+++ b/astro/src/content/resources/es/glossary.md
@@ -0,0 +1,62 @@
+---
+title: Express glossary
+description: A comprehensive glossary of terms related to Express.js, Node.js, middleware, routing, and other key concepts to help you understand and use Express effectively.
+---
+
+# Glossary
+
+### application
+
+In general, one or more programs that are designed to carry out operations for a specific purpose. In the context of Express, a program that uses the Express API running on the Node.js platform. Might also refer to an [app object](/en/api#express).
+
+### API
+
+Application programming interface. Spell out the abbreviation when it is first used.
+
+### Express
+
+A fast, un-opinionated, minimalist web framework for Node.js applications. In general, "Express" is preferred to "Express.js," though the latter is acceptable.
+
+### libuv
+
+A multi-platform support library which focuses on asynchronous I/O, primarily developed for use by Node.js.
+
+### middleware
+
+A function that is invoked by the Express routing layer before the final request handler, and thus sits in the middle between a raw request and the final intended route. A few fine points of terminology around middleware:
+
+- `var foo = require('middleware')` is called _requiring_ or _using_ a Node.js module. Then the statement `var mw = foo()` typically returns the middleware.
+- `app.use(mw)` is called _adding the middleware to the global processing stack_.
+- `app.get('/foo', mw, function (req, res) { ... })` is called _adding the middleware to the "GET /foo" processing stack_.
+
+### Node.js
+
+A software platform that is used to build scalable network applications. Node.js uses JavaScript as its scripting language, and achieves high throughput via non-blocking I/O and a single-threaded event loop. See [nodejs.org](https://nodejs.org/en/). **Usage note**: Initially, "Node.js," thereafter "Node".
+
+### open-source, open source
+
+When used as an adjective, hyphenate; for example: "This is open-source software." See [Open-source software on Wikipedia](http://en.wikipedia.org/wiki/Open-source_software).
+
+{% capture english-rules %}
+
+Although it is common not to hyphenate this term, we are using the standard English rules for hyphenating a compound adjective.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=english-rules %}
+
+### request
+
+An HTTP request. A client submits an HTTP request message to a server, which returns a response. The request must use one of several [request methods](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods) such as GET, POST, and so on.
+
+### response
+
+An HTTP response. A server returns an HTTP response message to the client. The response contains completion status information about the request and might also contain requested content in its message body.
+
+### route
+
+Part of a URL that identifies a resource. For example, in `http://foo.com/products/id`, "/products/id" is the route.
+
+### router
+
+See [router](/en/api#router) in the API reference.
diff --git a/astro/src/content/resources/es/middleware/body-parser.md b/astro/src/content/resources/es/middleware/body-parser.md
new file mode 100644
index 0000000000..e82649a95c
--- /dev/null
+++ b/astro/src/content/resources/es/middleware/body-parser.md
@@ -0,0 +1,498 @@
+---
+title: Express body-parser middleware
+module: body-parser
+---
+
+# body-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+
+Node.js body parsing middleware.
+
+Parse incoming request bodies in a middleware before your handlers, available
+under the `req.body` property.
+
+**Note** As `req.body`'s shape is based on user-controlled input, all
+properties and values in this object are untrusted and should be validated
+before trusting. For example, `req.body.foo.toString()` may fail in multiple
+ways, for example the `foo` property may not be there or may not be a string,
+and `toString` may not be a function and instead a string or other user input.
+
+[Learn about the anatomy of an HTTP transaction in Node.js](https://nodejs.org/en/learn/http/anatomy-of-an-http-transaction).
+
+_This does not handle multipart bodies_, due to their complex and typically
+large nature. For multipart bodies, you may be interested in the following
+modules:
+
+- [busboy](https://www.npmjs.com/package/busboy#readme) and
+ [connect-busboy](https://www.npmjs.com/package/connect-busboy#readme)
+- [multiparty](https://www.npmjs.com/package/multiparty#readme) and
+ [connect-multiparty](https://www.npmjs.com/package/connect-multiparty#readme)
+- [formidable](https://www.npmjs.com/package/formidable#readme)
+- [multer](https://www.npmjs.com/package/multer#readme)
+
+This module provides the following parsers:
+
+- [JSON body parser](#bodyparserjsonoptions)
+- [Raw body parser](#bodyparserrawoptions)
+- [Text body parser](#bodyparsertextoptions)
+- [URL-encoded form body parser](#bodyparserurlencodedoptions)
+
+Other body parsers you might be interested in:
+
+- [body](https://www.npmjs.com/package/body#readme)
+- [co-body](https://www.npmjs.com/package/co-body#readme)
+
+## Installation
+
+```sh
+$ npm install body-parser
+```
+
+## API
+
+```js
+const bodyParser = require('body-parser');
+```
+
+The `bodyParser` object exposes various factories to create middlewares. All
+middlewares will populate the `req.body` property with the parsed body when
+the `Content-Type` request header matches the `type` option.
+
+The various errors returned by this module are described in the
+[errors section](#errors).
+
+### bodyParser.json([options])
+
+Returns middleware that only parses `json` and only looks at requests where
+the `Content-Type` header matches the `type` option. This parser accepts any
+Unicode encoding of the body and supports automatic inflation of `gzip`,
+`br` (brotli) and `deflate` encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`).
+
+#### Options
+
+The `json` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### defaultCharset
+
+Specify the default character set for the json content if the charset is not
+specified in the `Content-Type` header of the request. Defaults to `utf-8`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### reviver
+
+The `reviver` option is passed directly to `JSON.parse` as the second
+argument. You can find more information on this argument
+[in the MDN documentation about JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Example.3A_Using_the_reviver_parameter).
+
+##### strict
+
+When set to `true`, will only accept arrays and objects; when `false` will
+accept anything `JSON.parse` accepts. Defaults to `true`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not a
+function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `json`), a mime type (like `application/json`), or
+a mime type with a wildcard (like `*/*` or `*/json`). If a function, the `type`
+option is called as `fn(req)` and the request is parsed if it returns a truthy
+value. Defaults to `application/json`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.raw([options])
+
+Returns middleware that parses all bodies as a `Buffer` and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser supports automatic inflation of `gzip`, `br` (brotli) and `deflate`
+encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This will be a `Buffer` object
+of the body.
+
+#### Options
+
+The `raw` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function.
+If not a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this
+can be an extension name (like `bin`), a mime type (like
+`application/octet-stream`), or a mime type with a wildcard (like `*/*` or
+`application/*`). If a function, the `type` option is called as `fn(req)`
+and the request is parsed if it returns a truthy value. Defaults to
+`application/octet-stream`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.text([options])
+
+Returns middleware that parses all bodies as a string and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser supports automatic inflation of `gzip`, `br` (brotli) and `deflate`
+encodings.
+
+A new `body` string containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This will be a string of the
+body.
+
+#### Options
+
+The `text` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### defaultCharset
+
+Specify the default character set for the text content if the charset is not
+specified in the `Content-Type` header of the request. Defaults to `utf-8`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not
+a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `txt`), a mime type (like `text/plain`), or a mime
+type with a wildcard (like `*/*` or `text/*`). If a function, the `type`
+option is called as `fn(req)` and the request is parsed if it returns a
+truthy value. Defaults to `text/plain`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.urlencoded([options])
+
+Returns middleware that only parses `urlencoded` bodies and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser accepts only UTF-8 encoding of the body and supports automatic
+inflation of `gzip`, `br` (brotli) and `deflate` encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This object will contain
+key-value pairs, where the value can be a string or array (when `extended` is
+`false`), or any type (when `extended` is `true`).
+
+#### Options
+
+The `urlencoded` function takes an optional `options` object that may contain
+any of the following keys:
+
+##### extended
+
+The "extended" syntax allows for rich objects and arrays to be encoded into the
+URL-encoded format, allowing for a JSON-like experience with URL-encoded. For
+more information, please [see the qs
+library](https://www.npmjs.com/package/qs#readme).
+
+Defaults to `false`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### parameterLimit
+
+The `parameterLimit` option controls the maximum number of parameters that
+are allowed in the URL-encoded data. If a request contains more parameters
+than this value, a 413 will be returned to the client. Defaults to `1000`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not
+a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `urlencoded`), a mime type (like
+`application/x-www-form-urlencoded`), or a mime type with a wildcard (like
+`*/x-www-form-urlencoded`). If a function, the `type` option is called as
+`fn(req)` and the request is parsed if it returns a truthy value. Defaults
+to `application/x-www-form-urlencoded`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+##### defaultCharset
+
+The default charset to parse as, if not specified in content-type. Must be
+either `utf-8` or `iso-8859-1`. Defaults to `utf-8`.
+
+##### charsetSentinel
+
+Whether to let the value of the `utf8` parameter take precedence as the charset
+selector. It requires the form to contain a parameter named `utf8` with a value
+of `✓`. Defaults to `false`.
+
+##### interpretNumericEntities
+
+Whether to decode numeric entities such as `☺` when parsing an iso-8859-1
+form. Defaults to `false`.
+
+##### depth
+
+The `depth` option is used to configure the maximum depth of the `qs` library when `extended` is `true`. This allows you to limit the amount of keys that are parsed and can be useful to prevent certain types of abuse. Defaults to `32`. It is recommended to keep this value as low as possible.
+
+## Errors
+
+The middlewares provided by this module create errors using the
+[`http-errors` module](https://www.npmjs.com/package/http-errors). The errors
+will typically have a `status`/`statusCode` property that contains the suggested
+HTTP response code, an `expose` property to determine if the `message` property
+should be displayed to the client, a `type` property to determine the type of
+error without matching against the `message`, and a `body` property containing
+the read body, if available.
+
+The following are the common errors created, though any error can come through
+for various reasons.
+
+### content encoding unsupported
+
+This error will occur when the request had a `Content-Encoding` header that
+contained an encoding but the "inflation" option was set to `false`. The
+`status` property is set to `415`, the `type` property is set to
+`'encoding.unsupported'`, and the `charset` property will be set to the
+encoding that is unsupported.
+
+### entity parse failed
+
+This error will occur when the request contained an entity that could not be
+parsed by the middleware. The `status` property is set to `400`, the `type`
+property is set to `'entity.parse.failed'`, and the `body` property is set to
+the entity value that failed parsing.
+
+### entity verify failed
+
+This error will occur when the request contained an entity that could not be
+failed verification by the defined `verify` option. The `status` property is
+set to `403`, the `type` property is set to `'entity.verify.failed'`, and the
+`body` property is set to the entity value that failed verification.
+
+### request aborted
+
+This error will occur when the request is aborted by the client before reading
+the body has finished. The `received` property will be set to the number of
+bytes received before the request was aborted and the `expected` property is
+set to the number of expected bytes. The `status` property is set to `400`
+and `type` property is set to `'request.aborted'`.
+
+### request entity too large
+
+This error will occur when the request body's size is larger than the "limit"
+option. The `limit` property will be set to the byte limit and the `length`
+property will be set to the request body's length. The `status` property is
+set to `413` and the `type` property is set to `'entity.too.large'`.
+
+### request size did not match content length
+
+This error will occur when the request's length did not match the length from
+the `Content-Length` header. This typically occurs when the request is malformed,
+typically when the `Content-Length` header was calculated based on characters
+instead of bytes. The `status` property is set to `400` and the `type` property
+is set to `'request.size.invalid'`.
+
+### stream encoding should not be set
+
+This error will occur when something called the `req.setEncoding` method prior
+to this middleware. This module operates directly on bytes only and you cannot
+call `req.setEncoding` when using this module. The `status` property is set to
+`500` and the `type` property is set to `'stream.encoding.set'`.
+
+### stream is not readable
+
+This error will occur when the request is no longer readable when this middleware
+attempts to read it. This typically means something other than a middleware from
+this module read the request body already and the middleware was also configured to
+read the same request. The `status` property is set to `500` and the `type`
+property is set to `'stream.not.readable'`.
+
+### too many parameters
+
+This error will occur when the content of the request exceeds the configured
+`parameterLimit` for the `urlencoded` parser. The `status` property is set to
+`413` and the `type` property is set to `'parameters.too.many'`.
+
+### unsupported charset "BOGUS"
+
+This error will occur when the request had a charset parameter in the
+`Content-Type` header, but the `iconv-lite` module does not support it OR the
+parser does not support it. The charset is contained in the message as well
+as in the `charset` property. The `status` property is set to `415`, the
+`type` property is set to `'charset.unsupported'`, and the `charset` property
+is set to the charset that is unsupported.
+
+### unsupported content encoding "bogus"
+
+This error will occur when the request had a `Content-Encoding` header that
+contained an unsupported encoding. The encoding is contained in the message
+as well as in the `encoding` property. The `status` property is set to `415`,
+the `type` property is set to `'encoding.unsupported'`, and the `encoding`
+property is set to the encoding that is unsupported.
+
+### The input exceeded the depth
+
+This error occurs when using `bodyParser.urlencoded` with the `extended` property set to `true` and the input exceeds the configured `depth` option. The `status` property is set to `400`. It is recommended to review the `depth` option and evaluate if it requires a higher value. When the `depth` option is set to `32` (default value), the error will not be thrown.
+
+## Examples
+
+### Express/Connect top-level generic
+
+This example demonstrates adding a generic JSON and URL-encoded parser as a
+top-level middleware, which will parse the bodies of all incoming requests.
+This is the simplest setup.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// parse application/x-www-form-urlencoded
+app.use(bodyParser.urlencoded());
+
+// parse application/json
+app.use(bodyParser.json());
+
+app.use(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.write('you posted:\n');
+ res.end(String(JSON.stringify(req.body, null, 2)));
+});
+```
+
+### Express route-specific
+
+This example demonstrates adding body parsers specifically to the routes that
+need them. In general, this is the most recommended way to use body-parser with
+Express.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// create application/json parser
+const jsonParser = bodyParser.json();
+
+// create application/x-www-form-urlencoded parser
+const urlencodedParser = bodyParser.urlencoded();
+
+// POST /login gets urlencoded bodies
+app.post('/login', urlencodedParser, function (req, res) {
+ if (!req.body || !req.body.username) res.sendStatus(400);
+ res.send('welcome, ' + req.body.username);
+});
+
+// POST /api/users gets JSON bodies
+app.post('/api/users', jsonParser, function (req, res) {
+ if (!req.body) res.sendStatus(400);
+ // create user in req.body
+});
+```
+
+### Change accepted type for parsers
+
+All the parsers accept a `type` option which allows you to change the
+`Content-Type` that the middleware will parse.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// parse various different custom JSON types as JSON
+app.use(bodyParser.json({ type: 'application/*+json' }));
+
+// parse some custom thing into a Buffer
+app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }));
+
+// parse an HTML body into a string
+app.use(bodyParser.text({ type: 'text/html' }));
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/body-parser/ci.yml?branch=master&label=ci
+[ci-url]: https://github.com/expressjs/body-parser/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coverallsCoverage/github/expressjs/body-parser?branch=master
+[coveralls-url]: https://coveralls.io/r/expressjs/body-parser?branch=master
+[npm-downloads-image]: https://img.shields.io/npm/dm/body-parser
+[npm-url]: https://npmjs.com/package/body-parser
+[npm-version-image]: https://img.shields.io/npm/v/body-parser
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/body-parser/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/body-parser
diff --git a/astro/src/content/resources/es/middleware/compression.md b/astro/src/content/resources/es/middleware/compression.md
new file mode 100644
index 0000000000..6ac63fcb7a
--- /dev/null
+++ b/astro/src/content/resources/es/middleware/compression.md
@@ -0,0 +1,314 @@
+---
+title: Express compression middleware
+module: compression
+---
+
+# compression
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+[![Funding][funding-image]][funding-url]
+
+Node.js compression middleware.
+
+The following compression codings are supported:
+
+- deflate
+- gzip
+- br (brotli)
+
+**Note** Brotli is supported only since Node.js versions v11.7.0 and v10.16.0.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```bash
+$ npm install compression
+```
+
+## API
+
+```js
+var compression = require('compression');
+```
+
+### compression([options])
+
+Returns the compression middleware using the given `options`. The middleware
+will attempt to compress response bodies for all requests that traverse through
+the middleware, based on the given `options`.
+
+This middleware will never compress responses that include a `Cache-Control`
+header with the [`no-transform` directive](https://tools.ietf.org/html/rfc7234#section-5.2.2.4),
+as compressing will transform the body.
+
+#### Options
+
+`compression()` accepts these properties in the options object. In addition to
+those listed below, [zlib](https://nodejs.org/api/zlib.html) options may be
+passed in to the options object or
+[brotli](https://nodejs.org/api/zlib.html#zlib_class_brotlioptions) options.
+
+##### chunkSize
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_CHUNK`, or `16384`.
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### filter
+
+Type: `Function`
+
+A function to decide if the response should be considered for compression.
+This function is called as `filter(req, res)` and is expected to return
+`true` to consider the response for compression, or `false` to not compress
+the response.
+
+The default filter function uses the [compressible](https://www.npmjs.com/package/compressible)
+module to determine if `res.getHeader('Content-Type')` is compressible.
+
+##### level
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_COMPRESSION`, or `-1`
+
+The level of zlib compression to apply to responses. A higher level will result
+in better compression, but will take longer to complete. A lower level will
+result in less compression, but will be much faster.
+
+This is an integer in the range of `0` (no compression) to `9` (maximum
+compression). The special value `-1` can be used to mean the "default
+compression level", which is a default compromise between speed and
+compression (currently equivalent to level 6).
+
+- `-1` Default compression level (also `zlib.constants.Z_DEFAULT_COMPRESSION`).
+- `0` No compression (also `zlib.constants.Z_NO_COMPRESSION`).
+- `1` Fastest compression (also `zlib.constants.Z_BEST_SPEED`).
+- `2`
+- `3`
+- `4`
+- `5`
+- `6` (currently what `zlib.constants.Z_DEFAULT_COMPRESSION` points to).
+- `7`
+- `8`
+- `9` Best compression (also `zlib.constants.Z_BEST_COMPRESSION`).
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### memLevel
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_MEMLEVEL`, or `8`
+
+This specifies how much memory should be allocated for the internal compression
+state and is an integer in the range of `1` (minimum level) and `9` (maximum
+level).
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### brotli
+
+Type: `Object`
+
+This specifies the options for configuring Brotli. See [Node.js documentation](https://nodejs.org/api/zlib.html#class-brotlioptions) for a complete list of available options.
+
+##### strategy
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_STRATEGY`
+
+This is used to tune the compression algorithm. This value only affects the
+compression ratio, not the correctness of the compressed output, even if it
+is not set appropriately.
+
+- `zlib.constants.Z_DEFAULT_STRATEGY` Use for normal data.
+- `zlib.constants.Z_FILTERED` Use for data produced by a filter (or predictor).
+ Filtered data consists mostly of small values with a somewhat random
+ distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect is to force more Huffman coding and less
+ string matching; it is somewhat intermediate between `zlib.constants.Z_DEFAULT_STRATEGY`
+ and `zlib.constants.Z_HUFFMAN_ONLY`.
+- `zlib.constants.Z_FIXED` Use to prevent the use of dynamic Huffman codes, allowing
+ for a simpler decoder for special applications.
+- `zlib.constants.Z_HUFFMAN_ONLY` Use to force Huffman encoding only (no string match).
+- `zlib.constants.Z_RLE` Use to limit match distances to one (run-length encoding).
+ This is designed to be almost as fast as `zlib.constants.Z_HUFFMAN_ONLY`, but give
+ better compression for PNG image data.
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### threshold
+
+Type: `Number` or `String`
+Default: `1kb`
+
+The byte threshold for the response body size before compression is considered
+for the response. This is a number of bytes or any string
+accepted by the [bytes](https://www.npmjs.com/package/bytes) module.
+
+**Note** this is only an advisory setting; if the response size cannot be determined
+at the time the response headers are written, then it is assumed the response is
+_over_ the threshold. To guarantee the response size can be determined, be sure
+set a `Content-Length` response header.
+
+##### windowBits
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_WINDOWBITS`, or `15`
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### enforceEncoding
+
+Type: `String`
+Default: `identity`
+
+This is the default encoding to use when the client does not specify an encoding in the request's [Accept-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) header.
+
+#### .filter
+
+The default `filter` function. This is used to construct a custom filter
+function that is an extension of the default function.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+app.use(compression({ filter: shouldCompress }));
+
+function shouldCompress(req, res) {
+ if (req.headers['x-no-compression']) {
+ // don't compress responses with this request header
+ return false;
+ }
+
+ // fallback to standard filter function
+ return compression.filter(req, res);
+}
+```
+
+### res.flush
+
+This module adds a `res.flush()` method to force the partially-compressed
+response to be flushed to the client.
+
+## Examples
+
+### express
+
+When using this module with express, simply `app.use` the module as
+high as you like. Requests that pass through the middleware will be compressed.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress all responses
+app.use(compression());
+
+// add all routes
+```
+
+### Node.js HTTP server
+
+```js
+var compression = require('compression')({ threshold: 0 });
+var http = require('http');
+
+function createServer(fn) {
+ return http.createServer(function (req, res) {
+ compression(req, res, function (err) {
+ if (err) {
+ res.statusCode = err.status || 500;
+ res.end(err.message);
+ return;
+ }
+
+ fn(req, res);
+ });
+ });
+}
+
+var server = createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello world!');
+});
+
+server.listen(3000, () => {
+ console.log('> Listening at http://localhost:3000');
+});
+```
+
+### Server-Sent Events
+
+Because of the nature of compression this module does not work out of the box
+with server-sent events. To compress content, a window of the output needs to
+be buffered up in order to get good compression. Typically when using server-sent
+events, there are certain block of data that need to reach the client.
+
+You can achieve this by calling `res.flush()` when you need the data written to
+actually make it to the client.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress responses
+app.use(compression());
+
+// server-sent event stream
+app.get('/events', function (req, res) {
+ res.setHeader('Content-Type', 'text/event-stream');
+ res.setHeader('Cache-Control', 'no-cache');
+
+ // send a ping approx every 2 seconds
+ var timer = setInterval(function () {
+ res.write('data: ping\n\n');
+
+ // !!! this is the important part
+ res.flush();
+ }, 2000);
+
+ res.on('close', function () {
+ clearInterval(timer);
+ });
+});
+```
+
+## Contributing
+
+The Express.js project welcomes all constructive contributions. Contributions take many forms,
+from code for bug fixes and enhancements, to additions and fixes to documentation, additional
+tests, triaging incoming pull requests and issues, and more!
+
+See the [Contributing Guide](https://github.com/expressjs/express/blob/master/Contributing.md) for more technical details on contributing.
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://badgen.net/npm/v/compression
+[npm-url]: https://npmjs.org/package/compression
+[downloads-image]: https://badgen.net/npm/dm/compression
+[downloads-url]: https://npmcharts.com/compare/compression?minimal=true
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/compression/master?label=CI
+[github-actions-ci-url]: https://github.com/expressjs/compression/actions?query=workflow%3Aci
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/compression/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/compression
+[funding-url]: https://opencollective.com/express
+[funding-image]: https://badgen.net/badge/icon/sponsor/pink?icon=github&label=Open%20Collective
diff --git a/astro/src/content/resources/es/middleware/cookie-parser.md b/astro/src/content/resources/es/middleware/cookie-parser.md
new file mode 100644
index 0000000000..2a59496387
--- /dev/null
+++ b/astro/src/content/resources/es/middleware/cookie-parser.md
@@ -0,0 +1,124 @@
+---
+title: Express cookie-parser middleware
+module: cookie-parser
+---
+
+# cookie-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Parse `Cookie` header and populate `req.cookies` with an object keyed by the
+cookie names. Optionally you may enable signed cookie support by passing a
+`secret` string, which assigns `req.secret` so it may be used by other
+middleware.
+
+## Installation
+
+```sh
+$ npm install cookie-parser
+```
+
+## API
+
+```js
+var cookieParser = require('cookie-parser');
+```
+
+### cookieParser(secret, options)
+
+Create a new cookie parser middleware function using the given `secret` and
+`options`.
+
+- `secret` a string or array used for signing cookies. This is optional and if
+ not specified, will not parse signed cookies. If a string is provided, this
+ is used as the secret. If an array is provided, an attempt will be made to
+ unsign the cookie with each secret in order.
+- `options` an object that is passed to `cookie.parse` as the second option. See
+ [cookie](https://www.npmjs.org/package/cookie) for more information.
+ - `decode` a function to decode the value of the cookie
+
+The middleware will parse the `Cookie` header on the request and expose the
+cookie data as the property `req.cookies` and, if a `secret` was provided, as
+the property `req.signedCookies`. These properties are name value pairs of the
+cookie name to cookie value.
+
+When `secret` is provided, this module will unsign and validate any signed cookie
+values and move those name value pairs from `req.cookies` into `req.signedCookies`.
+A signed cookie is a cookie that has a value prefixed with `s:`. Signed cookies
+that fail signature validation will have the value `false` instead of the tampered
+value.
+
+In addition, this module supports special "JSON cookies". These are cookie where
+the value is prefixed with `j:`. When these values are encountered, the value will
+be exposed as the result of `JSON.parse`. If parsing fails, the original value will
+remain.
+
+### cookieParser.JSONCookie(str)
+
+Parse a cookie value as a JSON cookie. This will return the parsed JSON value
+if it was a JSON cookie, otherwise, it will return the passed value.
+
+### cookieParser.JSONCookies(cookies)
+
+Given an object, this will iterate over the keys and call `JSONCookie` on each
+value, replacing the original value with the parsed value. This returns the
+same object that was passed in.
+
+### cookieParser.signedCookie(str, secret)
+
+Parse a cookie value as a signed cookie. This will return the parsed unsigned
+value if it was a signed cookie and the signature was valid. If the value was
+not signed, the original value is returned. If the value was signed but the
+signature could not be validated, `false` is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+### cookieParser.signedCookies(cookies, secret)
+
+Given an object, this will iterate over the keys and check if any value is a
+signed cookie. If it is a signed cookie and the signature is valid, the key
+will be deleted from the object and added to the new object that is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+## Example
+
+```js
+var express = require('express');
+var cookieParser = require('cookie-parser');
+
+var app = express();
+app.use(cookieParser());
+
+app.get('/', function (req, res) {
+ // Cookies that have not been signed
+ console.log('Cookies: ', req.cookies);
+
+ // Cookies that have been signed
+ console.log('Signed Cookies: ', req.signedCookies);
+});
+
+app.listen(8080);
+
+// curl command that sends an HTTP request with two cookies
+// curl http://127.0.0.1:8080 --cookie "Cho=Kim;Greet=Hello"
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/cookie-parser/master?label=ci
+[ci-url]: https://github.com/expressjs/cookie-parser/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/cookie-parser/master
+[coveralls-url]: https://coveralls.io/r/expressjs/cookie-parser?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/cookie-parser
+[npm-url]: https://npmjs.org/package/cookie-parser
+[npm-version-image]: https://badgen.net/npm/v/cookie-parser
diff --git a/astro/src/content/resources/es/middleware/cookie-session.md b/astro/src/content/resources/es/middleware/cookie-session.md
new file mode 100644
index 0000000000..2d6d1f885b
--- /dev/null
+++ b/astro/src/content/resources/es/middleware/cookie-session.md
@@ -0,0 +1,124 @@
+---
+title: Express cookie-session middleware
+module: cookie-session
+---
+
+# cookie-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Parse `Cookie` header and populate `req.cookies` with an object keyed by the
+cookie names. Optionally you may enable signed cookie support by passing a
+`secret` string, which assigns `req.secret` so it may be used by other
+middleware.
+
+## Installation
+
+```sh
+$ npm install cookie-parser
+```
+
+## API
+
+```js
+var cookieParser = require('cookie-parser');
+```
+
+### cookieParser(secret, options)
+
+Create a new cookie parser middleware function using the given `secret` and
+`options`.
+
+- `secret` a string or array used for signing cookies. This is optional and if
+ not specified, will not parse signed cookies. If a string is provided, this
+ is used as the secret. If an array is provided, an attempt will be made to
+ unsign the cookie with each secret in order.
+- `options` an object that is passed to `cookie.parse` as the second option. See
+ [cookie](https://www.npmjs.org/package/cookie) for more information.
+ - `decode` a function to decode the value of the cookie
+
+The middleware will parse the `Cookie` header on the request and expose the
+cookie data as the property `req.cookies` and, if a `secret` was provided, as
+the property `req.signedCookies`. These properties are name value pairs of the
+cookie name to cookie value.
+
+When `secret` is provided, this module will unsign and validate any signed cookie
+values and move those name value pairs from `req.cookies` into `req.signedCookies`.
+A signed cookie is a cookie that has a value prefixed with `s:`. Signed cookies
+that fail signature validation will have the value `false` instead of the tampered
+value.
+
+In addition, this module supports special "JSON cookies". These are cookie where
+the value is prefixed with `j:`. When these values are encountered, the value will
+be exposed as the result of `JSON.parse`. If parsing fails, the original value will
+remain.
+
+### cookieParser.JSONCookie(str)
+
+Parse a cookie value as a JSON cookie. This will return the parsed JSON value
+if it was a JSON cookie, otherwise, it will return the passed value.
+
+### cookieParser.JSONCookies(cookies)
+
+Given an object, this will iterate over the keys and call `JSONCookie` on each
+value, replacing the original value with the parsed value. This returns the
+same object that was passed in.
+
+### cookieParser.signedCookie(str, secret)
+
+Parse a cookie value as a signed cookie. This will return the parsed unsigned
+value if it was a signed cookie and the signature was valid. If the value was
+not signed, the original value is returned. If the value was signed but the
+signature could not be validated, `false` is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+### cookieParser.signedCookies(cookies, secret)
+
+Given an object, this will iterate over the keys and check if any value is a
+signed cookie. If it is a signed cookie and the signature is valid, the key
+will be deleted from the object and added to the new object that is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+## Example
+
+```js
+var express = require('express');
+var cookieParser = require('cookie-parser');
+
+var app = express();
+app.use(cookieParser());
+
+app.get('/', function (req, res) {
+ // Cookies that have not been signed
+ console.log('Cookies: ', req.cookies);
+
+ // Cookies that have been signed
+ console.log('Signed Cookies: ', req.signedCookies);
+});
+
+app.listen(8080);
+
+// curl command that sends an HTTP request with two cookies
+// curl http://127.0.0.1:8080 --cookie "Cho=Kim;Greet=Hello"
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/cookie-parser/master?label=ci
+[ci-url]: https://github.com/expressjs/cookie-parser/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/cookie-parser/master
+[coveralls-url]: https://coveralls.io/r/expressjs/cookie-parser?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/cookie-parser
+[npm-url]: https://npmjs.org/package/cookie-parser
+[npm-version-image]: https://badgen.net/npm/v/cookie-parser
diff --git a/astro/src/content/resources/es/middleware/cors.md b/astro/src/content/resources/es/middleware/cors.md
new file mode 100644
index 0000000000..55d70922cb
--- /dev/null
+++ b/astro/src/content/resources/es/middleware/cors.md
@@ -0,0 +1,261 @@
+---
+title: Express cors middleware
+module: cors
+---
+
+# cors
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+CORS is a [Node.js](https://nodejs.org/en/) package for providing a [Connect](https://github.com/senchalabs/connect)/[Express](https://expressjs.com/) middleware that can be used to enable [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS) with various options.
+
+- [Installation](#installation)
+- [Usage](#usage)
+ - [Simple Usage](#simple-usage-enable-all-cors-requests)
+ - [Enable CORS for a Single Route](#enable-cors-for-a-single-route)
+ - [Configuring CORS](#configuring-cors)
+ - [Configuring CORS w/ Dynamic Origin](#configuring-cors-w-dynamic-origin)
+ - [Enabling CORS Pre-Flight](#enabling-cors-pre-flight)
+ - [Customizing CORS Settings Dynamically per Request](#customizing-cors-settings-dynamically-per-request)
+- [Configuration Options](#configuration-options)
+- [License](#license)
+- [Original Author](#original-author)
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/downloading-and-installing-packages-locally):
+
+```sh
+$ npm install cors
+```
+
+## Usage
+
+### Simple Usage (Enable _All_ CORS Requests)
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.use(cors());
+
+app.get('/products/:id', function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for all origins!' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Enable CORS for a Single Route
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.get('/products/:id', cors(), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for a Single Route' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Configuring CORS
+
+See the [configuration options](#configuration-options) for details.
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+var corsOptions = {
+ origin: 'http://example.com',
+ optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
+};
+
+app.get('/products/:id', cors(corsOptions), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for only example.com.' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Configuring CORS w/ Dynamic Origin
+
+This module supports validating the origin dynamically using a function provided
+to the `origin` option. This function will be passed a string that is the origin
+(or `undefined` if the request has no origin), and a `callback` with the signature
+`callback(error, origin)`.
+
+The `origin` argument to the callback can be any value allowed for the `origin`
+option of the middleware, except a function. See the
+[configuration options](#configuration-options) section for more information on all
+the possible value types.
+
+This function is designed to allow the dynamic loading of allowed origin(s) from
+a backing datasource, like a database.
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+var corsOptions = {
+ origin: function (origin, callback) {
+ // db.loadOrigins is an example call to load
+ // a list of origins from a backing database
+ db.loadOrigins(function (error, origins) {
+ callback(error, origins);
+ });
+ },
+};
+
+app.get('/products/:id', cors(corsOptions), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for an allowed domain.' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Enabling CORS Pre-Flight
+
+Certain CORS requests are considered 'complex' and require an initial
+`OPTIONS` request (called the "pre-flight request"). An example of a
+'complex' CORS request is one that uses an HTTP verb other than
+GET/HEAD/POST (such as DELETE) or that uses custom headers. To enable
+pre-flighting, you must add a new OPTIONS handler for the route you want
+to support:
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.options('/products/:id', cors()); // enable pre-flight request for DELETE request
+app.del('/products/:id', cors(), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for all origins!' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+You can also enable pre-flight across-the-board like so:
+
+```javascript
+app.options('*', cors()); // include before other routes
+```
+
+NOTE: When using this middleware as an application level middleware (for
+example, `app.use(cors())`), pre-flight requests are already handled for all
+routes.
+
+### Customizing CORS Settings Dynamically per Request
+
+For APIs that require different CORS configurations for specific routes or requests, you can dynamically generate CORS options based on the incoming request. The `cors` middleware allows you to achieve this by passing a function instead of static options. This function is called for each incoming request and must use the callback pattern to return the appropriate CORS options.
+
+The function accepts:
+
+1. **`req`**:
+ - The incoming request object.
+
+2. **`callback(error, corsOptions)`**:
+ - A function used to return the computed CORS options.
+ - **Arguments**:
+ - **`error`**: Pass `null` if there’s no error, or an error object to indicate a failure.
+ - **`corsOptions`**: An object specifying the CORS policy for the current request.
+
+Here’s an example that handles both public routes and restricted, credential-sensitive routes:
+
+```javascript
+var dynamicCorsOptions = function (req, callback) {
+ var corsOptions;
+ if (req.path.startsWith('/auth/connect/')) {
+ corsOptions = {
+ origin: 'http://mydomain.com', // Allow only a specific origin
+ credentials: true, // Enable cookies and credentials
+ };
+ } else {
+ corsOptions = { origin: '*' }; // Allow all origins for other routes
+ }
+ callback(null, corsOptions);
+};
+
+app.use(cors(dynamicCorsOptions));
+
+app.get('/auth/connect/twitter', function (req, res) {
+ res.send('CORS dynamically applied for Twitter authentication.');
+});
+
+app.get('/public', function (req, res) {
+ res.send('Public data with open CORS.');
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+## Configuration Options
+
+- `origin`: Configures the **Access-Control-Allow-Origin** CORS header. Possible values:
+ - `Boolean` - set `origin` to `true` to reflect the [request origin](https://datatracker.ietf.org/doc/html/draft-abarth-origin-09), as defined by `req.header('Origin')`, or set it to `false` to disable CORS.
+ - `String` - set `origin` to a specific origin. For example, if you set it to
+ - `"http://example.com"` only requests from "http://example.com" will be allowed.
+ - `"*"` for all domains to be allowed.
+ - `RegExp` - set `origin` to a regular expression pattern which will be used to test the request origin. If it's a match, the request origin will be reflected. For example the pattern `/example\.com$/` will reflect any request that is coming from an origin ending with "example.com".
+ - `Array` - set `origin` to an array of valid origins. Each origin can be a `String` or a `RegExp`. For example `["http://example1.com", /\.example2\.com$/]` will accept any request from "http://example1.com" or from a subdomain of "example2.com".
+ - `Function` - set `origin` to a function implementing some custom logic. The function takes the request origin as the first parameter and a callback (called as `callback(err, origin)`, where `origin` is a non-function value of the `origin` option) as the second.
+- `methods`: Configures the **Access-Control-Allow-Methods** CORS header. Expects a comma-delimited string (ex: 'GET,PUT,POST') or an array (ex: `['GET', 'PUT', 'POST']`).
+- `allowedHeaders`: Configures the **Access-Control-Allow-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Type,Authorization') or an array (ex: `['Content-Type', 'Authorization']`). If not specified, defaults to reflecting the headers specified in the request's **Access-Control-Request-Headers** header.
+- `exposedHeaders`: Configures the **Access-Control-Expose-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Range,X-Content-Range') or an array (ex: `['Content-Range', 'X-Content-Range']`). If not specified, no custom headers are exposed.
+- `credentials`: Configures the **Access-Control-Allow-Credentials** CORS header. Set to `true` to pass the header, otherwise it is omitted.
+- `maxAge`: Configures the **Access-Control-Max-Age** CORS header. Set to an integer to pass the header, otherwise it is omitted.
+- `preflightContinue`: Pass the CORS preflight response to the next handler.
+- `optionsSuccessStatus`: Provides a status code to use for successful `OPTIONS` requests, since some legacy browsers (IE11, various SmartTVs) choke on `204`.
+
+The default configuration is the equivalent of:
+
+```json
+{
+ "origin": "*",
+ "methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
+ "preflightContinue": false,
+ "optionsSuccessStatus": 204
+}
+```
+
+For details on the effect of each CORS header, read [this](https://web.dev/articles/cross-origin-resource-sharing) article.
+
+## License
+
+[MIT License](http://www.opensource.org/licenses/mit-license.php)
+
+## Original Author
+
+[Troy Goode](https://github.com/TroyGoode) ([troygoode@gmail.com](mailto:troygoode@gmail.com))
+
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/cors/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/cors?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/cors.svg
+[downloads-url]: https://npmjs.com/package/cors
+[github-actions-ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/cors/ci.yml?branch=master&label=ci
+[github-actions-ci-url]: https://github.com/expressjs/cors?query=workflow%3Aci
+[npm-image]: https://img.shields.io/npm/v/cors.svg
+[npm-url]: https://npmjs.com/package/cors
diff --git a/astro/src/content/resources/es/middleware/errorhandler.md b/astro/src/content/resources/es/middleware/errorhandler.md
new file mode 100644
index 0000000000..20df618320
--- /dev/null
+++ b/astro/src/content/resources/es/middleware/errorhandler.md
@@ -0,0 +1,133 @@
+---
+title: Express errorhandler middleware
+module: errorhandler
+---
+
+# errorhandler
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Development-only error handler middleware.
+
+This middleware is only intended to be used in a development environment, as
+the _full error stack traces and internal details of any object passed to this
+module_ will be sent back to the client when an error occurs.
+
+When an object is provided to Express as an error, this module will display
+as much about this object as possible, and will do so by using content negotiation
+for the response between HTML, JSON, and plain text.
+
+- When the object is a standard `Error` object, the string provided by the
+ `stack` property will be returned in HTML/text responses.
+- When the object is a non-`Error` object, the result of
+ [util.inspect](https://nodejs.org/api/util.html#util_util_inspect_object_options)
+ will be returned in HTML/text responses.
+- For JSON responses, the result will be an object with all enumerable properties
+ from the object in the response.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install errorhandler
+```
+
+## API
+
+
+
+```js
+var errorhandler = require('errorhandler');
+```
+
+### errorhandler(options)
+
+Create new middleware to handle errors and respond with content negotiation.
+
+#### Options
+
+Error handler accepts these properties in the options object.
+
+##### log
+
+Provide a function to be called with the error and a string representation of
+the error. Can be used to write the error to any desired location, or set to
+`false` to only send the error back in the response. Called as
+`log(err, str, req, res)` where `err` is the `Error` object, `str` is a string
+representation of the error, `req` is the request object and `res` is the
+response object (note, this function is invoked _after_ the response has been
+written).
+
+The default value for this option is `true` unless `process.env.NODE_ENV === 'test'`.
+
+Possible values:
+
+- `true`: Log errors using `console.error(str)`.
+- `false`: Only send the error back in the response.
+- A function: pass the error to a function for handling.
+
+## Examples
+
+### Simple example
+
+Basic example of adding this middleware as the error handler only in development
+with `connect` (`express` also can be used in this example).
+
+```js
+var connect = require('connect');
+var errorhandler = require('errorhandler');
+
+var app = connect();
+
+// assumes NODE_ENV is set by the user
+if (process.env.NODE_ENV === 'development') {
+ // only use in development
+ app.use(errorhandler());
+}
+```
+
+### Custom output location
+
+Sometimes you may want to output the errors to a different location than STDERR
+during development, like a system notification, for example.
+
+
+
+```js
+var connect = require('connect');
+var errorhandler = require('errorhandler');
+var notifier = require('node-notifier');
+
+var app = connect();
+
+// assumes NODE_ENV is set by the user
+if (process.env.NODE_ENV === 'development') {
+ // only use in development
+ app.use(errorhandler({ log: errorNotification }));
+}
+
+function errorNotification(err, str, req) {
+ var title = 'Error in ' + req.method + ' ' + req.url;
+
+ notifier.notify({
+ title: title,
+ message: str,
+ });
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/errorhandler/master
+[coveralls-url]: https://coveralls.io/r/expressjs/errorhandler?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/errorhandler
+[npm-url]: https://npmjs.org/package/errorhandler
+[npm-version-image]: https://badgen.net/npm/v/errorhandler
diff --git a/astro/src/content/resources/es/middleware/method-override.md b/astro/src/content/resources/es/middleware/method-override.md
new file mode 100644
index 0000000000..7b97ab855e
--- /dev/null
+++ b/astro/src/content/resources/es/middleware/method-override.md
@@ -0,0 +1,187 @@
+---
+title: Express method-override middleware
+module: method-override
+---
+
+# method-override
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][travis-image]][travis-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Lets you use HTTP verbs such as PUT or DELETE in places where the client doesn't support it.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install method-override
+```
+
+## API
+
+**NOTE** It is very important that this module is used **before** any module that
+needs to know the method of the request (for example, it _must_ be used prior to
+the `csurf` module).
+
+### methodOverride(getter, options)
+
+Create a new middleware function to override the `req.method` property with a new
+value. This value will be pulled from the provided `getter`.
+
+- `getter` - The getter to use to look up the overridden request method for the request. (default: `X-HTTP-Method-Override`)
+- `options.methods` - The allowed methods the original request must be in to check for a method override value. (default: `['POST']`)
+
+If the found method is supported by node.js core, then `req.method` will be set to
+this value, as if it has originally been that value. The previous `req.method`
+value will be stored in `req.originalMethod`.
+
+#### getter
+
+This is the method of getting the override value from the request. If a function is provided,
+the `req` is passed as the first argument, the `res` as the second argument and the method is
+expected to be returned. If a string is provided, the string is used to look up the method
+with the following rules:
+
+- If the string starts with `X-`, then it is treated as the name of a header and that header
+ is used for the method override. If the request contains the same header multiple times, the
+ first occurrence is used.
+- All other strings are treated as a key in the URL query string.
+
+#### options.methods
+
+This allows the specification of what methods(s) the request _MUST_ be in in order to check for
+the method override value. This defaults to only `POST` methods, which is the only method the
+override should arrive in. More methods may be specified here, but it may introduce security
+issues and cause weird behavior when requests travel through caches. This value is an array
+of methods in upper-case. `null` can be specified to allow all methods.
+
+## Examples
+
+### override using a header
+
+To use a header to override the method, specify the header name
+as a string argument to the `methodOverride` function. To then make
+the call, send a `POST` request to a URL with the overridden method
+as the value of that header. This method of using a header would
+typically be used in conjunction with `XMLHttpRequest` on implementations
+that do not support the method you are trying to use.
+
+```js
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// override with the X-HTTP-Method-Override header in the request
+app.use(methodOverride('X-HTTP-Method-Override'));
+```
+
+Example call with header override using `XMLHttpRequest`:
+
+
+
+```js
+const xhr = new XMLHttpRequest();
+xhr.onload = onload;
+xhr.open('post', '/resource', true);
+xhr.setRequestHeader('X-HTTP-Method-Override', 'DELETE');
+xhr.send();
+
+function onload() {
+ alert('got response: ' + this.responseText);
+}
+```
+
+### override using a query value
+
+To use a query string value to override the method, specify the query
+string key as a string argument to the `methodOverride` function. To
+then make the call, send a `POST` request to a URL with the overridden
+method as the value of that query string key. This method of using a
+query value would typically be used in conjunction with plain HTML
+`
+```
+
+### multiple format support
+
+```js
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// override with different headers; last one takes precedence
+app.use(methodOverride('X-HTTP-Method')); // Microsoft
+app.use(methodOverride('X-HTTP-Method-Override')); // Google/GData
+app.use(methodOverride('X-Method-Override')); // IBM
+```
+
+### custom logic
+
+You can implement any kind of custom logic with a function for the `getter`. The following
+implements the logic for looking in `req.body` that was in `method-override@1`:
+
+```js
+const bodyParser = require('body-parser');
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// NOTE: when using req.body, you must fully parse the request body
+// before you call methodOverride() in your middleware stack,
+// otherwise req.body will not be populated.
+app.use(bodyParser.urlencoded());
+app.use(
+ methodOverride(function (req, res) {
+ if (req.body && typeof req.body === 'object' && '_method' in req.body) {
+ // look in urlencoded POST bodies and delete it
+ const method = req.body._method;
+ delete req.body._method;
+ return method;
+ }
+ })
+);
+```
+
+Example call with query override using HTML `
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/method-override.svg
+[npm-url]: https://npmjs.org/package/method-override
+[travis-image]: https://img.shields.io/travis/expressjs/method-override/master.svg
+[travis-url]: https://travis-ci.org/expressjs/method-override
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/method-override/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/method-override?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/method-override.svg
+[downloads-url]: https://npmjs.org/package/method-override
diff --git a/astro/src/content/resources/es/middleware/morgan.md b/astro/src/content/resources/es/middleware/morgan.md
new file mode 100644
index 0000000000..5319d93d57
--- /dev/null
+++ b/astro/src/content/resources/es/middleware/morgan.md
@@ -0,0 +1,458 @@
+---
+title: Express morgan middleware
+module: morgan
+---
+
+# morgan
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+HTTP request logger middleware for node.js
+
+> Named after [Dexter](http://en.wikipedia.org/wiki/Dexter_Morgan), a show you should not watch until completion.
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install morgan
+```
+
+## API
+
+
+
+```js
+var morgan = require('morgan');
+```
+
+### morgan(format, options)
+
+Create a new morgan logger middleware function using the given `format` and `options`.
+The `format` argument may be a string of a predefined name (see below for the names),
+a string of a format string, or a function that will produce a log entry.
+
+The `format` function will be called with three arguments `tokens`, `req`, and `res`,
+where `tokens` is an object with all defined tokens, `req` is the HTTP request and `res`
+is the HTTP response. The function is expected to return a string that will be the log
+line, or `undefined` / `null` to skip logging.
+
+#### Using a predefined format string
+
+
+
+```js
+morgan('tiny');
+```
+
+#### Using format string of predefined tokens
+
+
+
+```js
+morgan(':method :url :status :res[content-length] - :response-time ms');
+```
+
+#### Using a custom format function
+
+
+
+```js
+morgan(function (tokens, req, res) {
+ return [
+ tokens.method(req, res),
+ tokens.url(req, res),
+ tokens.status(req, res),
+ tokens.res(req, res, 'content-length'),
+ '-',
+ tokens['response-time'](req, res),
+ 'ms',
+ ].join(' ');
+});
+```
+
+#### Options
+
+Morgan accepts these properties in the options object.
+
+##### immediate
+
+Write log line on request instead of response. This means that a requests will
+be logged even if the server crashes, _but data from the response (like the
+response code, content length, etc.) cannot be logged_.
+
+##### skip
+
+Function to determine if logging is skipped, defaults to `false`. This function
+will be called as `skip(req, res)`.
+
+
+
+```js
+// EXAMPLE: only log error responses
+morgan('combined', {
+ skip: function (req, res) {
+ return res.statusCode < 400;
+ },
+});
+```
+
+##### stream
+
+Output stream for writing log lines, defaults to `process.stdout`.
+
+#### Predefined Formats
+
+There are various pre-defined formats provided:
+
+##### combined
+
+Standard Apache combined log output.
+
+```
+:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"
+# will output
+::1 - - [27/Nov/2024:06:21:42 +0000] "GET /combined HTTP/1.1" 200 2 "-" "curl/8.7.1"
+```
+
+##### common
+
+Standard Apache common log output.
+
+```
+:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length]
+# will output
+::1 - - [27/Nov/2024:06:21:46 +0000] "GET /common HTTP/1.1" 200 2
+```
+
+##### dev
+
+Concise output colored by response status for development use. The `:status`
+token will be colored green for success codes, red for server error codes,
+yellow for client error codes, cyan for redirection codes, and uncolored
+for information codes.
+
+```
+:method :url :status :response-time ms - :res[content-length]
+# will output
+GET /dev 200 0.224 ms - 2
+```
+
+##### short
+
+Shorter than default, also including response time.
+
+```
+:remote-addr :remote-user :method :url HTTP/:http-version :status :res[content-length] - :response-time ms
+# will output
+::1 - GET /short HTTP/1.1 200 2 - 0.283 ms
+```
+
+##### tiny
+
+The minimal output.
+
+```
+:method :url :status :res[content-length] - :response-time ms
+# will output
+GET /tiny 200 2 - 0.188 ms
+```
+
+#### Tokens
+
+##### Creating new tokens
+
+To define a token, simply invoke `morgan.token()` with the name and a callback function.
+This callback function is expected to return a string value. The value returned is then
+available as ":type" in this case:
+
+
+
+```js
+morgan.token('type', function (req, res) {
+ return req.headers['content-type'];
+});
+```
+
+Calling `morgan.token()` using the same name as an existing token will overwrite that
+token definition.
+
+The token function is expected to be called with the arguments `req` and `res`, representing
+the HTTP request and HTTP response. Additionally, the token can accept further arguments of
+it's choosing to customize behavior.
+
+##### :date[format]
+
+The current date and time in UTC. The available formats are:
+
+- `clf` for the common log format (`"10/Oct/2000:13:55:36 +0000"`)
+- `iso` for the common ISO 8601 date time format (`2000-10-10T13:55:36.000Z`)
+- `web` for the common RFC 1123 date time format (`Tue, 10 Oct 2000 13:55:36 GMT`)
+
+If no format is given, then the default is `web`.
+
+##### :http-version
+
+The HTTP version of the request.
+
+##### :method
+
+The HTTP method of the request.
+
+##### :pid
+
+The process ID of the Node.js process handling the request.
+
+##### :referrer
+
+The Referrer header of the request. This will use the standard mis-spelled Referer header if exists, otherwise Referrer.
+
+##### :remote-addr
+
+The remote address of the request. This will use `req.ip`, otherwise the standard `req.connection.remoteAddress` value (socket address).
+
+##### :remote-user
+
+The user authenticated as part of Basic auth for the request.
+
+##### :req[header]
+
+The given `header` of the request. If the header is not present, the
+value will be displayed as `"-"` in the log.
+
+##### :res[header]
+
+The given `header` of the response. If the header is not present, the
+value will be displayed as `"-"` in the log.
+
+##### :response-time[digits]
+
+The time between the request coming into `morgan` and when the response
+headers are written, in milliseconds.
+
+The `digits` argument is a number that specifies the number of digits to
+include on the number, defaulting to `3`, which provides microsecond precision.
+
+##### :status
+
+The status code of the response.
+
+If the request/response cycle completes before a response was sent to the
+client (for example, the TCP socket closed prematurely by a client aborting
+the request), then the status will be empty (displayed as `"-"` in the log).
+
+##### :total-time[digits]
+
+The time between the request coming into `morgan` and when the response
+has finished being written out to the connection, in milliseconds.
+
+The `digits` argument is a number that specifies the number of digits to
+include on the number, defaulting to `3`, which provides microsecond precision.
+
+##### :url
+
+The URL of the request. This will use `req.originalUrl` if exists, otherwise `req.url`.
+
+##### :user-agent
+
+The contents of the User-Agent header of the request.
+
+### morgan.compile(format)
+
+Compile a format string into a `format` function for use by `morgan`. A format string
+is a string that represents a single log line and can utilize token syntax.
+Tokens are references by `:token-name`. If tokens accept arguments, they can
+be passed using `[]`, for example: `:token-name[pretty]` would pass the string
+`'pretty'` as an argument to the token `token-name`.
+
+The function returned from `morgan.compile` takes three arguments `tokens`, `req`, and
+`res`, where `tokens` is object with all defined tokens, `req` is the HTTP request and
+`res` is the HTTP response. The function will return a string that will be the log line,
+or `undefined` / `null` to skip logging.
+
+Normally formats are defined using `morgan.format(name, format)`, but for certain
+advanced uses, this compile function is directly available.
+
+## Examples
+
+### express/connect
+
+Sample app that will log all request in the Apache combined format to STDOUT
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+
+var app = express();
+
+app.use(morgan('combined'));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### vanilla http server
+
+Sample app that will log all request in the Apache combined format to STDOUT
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var morgan = require('morgan');
+
+// create "middleware"
+var logger = morgan('combined');
+
+http.createServer(function (req, res) {
+ var done = finalhandler(req, res);
+ logger(req, res, function (err) {
+ if (err) return done(err);
+
+ // respond to request
+ res.setHeader('content-type', 'text/plain');
+ res.end('hello, world!');
+ });
+});
+```
+
+### write logs to a file
+
+#### single file
+
+Sample app that will log all requests in the Apache combined format to the file
+`access.log`.
+
+```js
+var express = require('express');
+var fs = require('fs');
+var morgan = require('morgan');
+var path = require('path');
+
+var app = express();
+
+// create a write stream (in append mode)
+var accessLogStream = fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' });
+
+// setup the logger
+app.use(morgan('combined', { stream: accessLogStream }));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+#### log file rotation
+
+Sample app that will log all requests in the Apache combined format to one log
+file per day in the `log/` directory using the
+[rotating-file-stream module](https://www.npmjs.com/package/rotating-file-stream).
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+var path = require('path');
+var rfs = require('rotating-file-stream'); // version 2.x
+
+var app = express();
+
+// create a rotating write stream
+var accessLogStream = rfs.createStream('access.log', {
+ interval: '1d', // rotate daily
+ path: path.join(__dirname, 'log'),
+});
+
+// setup the logger
+app.use(morgan('combined', { stream: accessLogStream }));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### split / dual logging
+
+The `morgan` middleware can be used as many times as needed, enabling
+combinations like:
+
+- Log entry on request and one on response
+- Log all requests to file, but errors to console
+- ... and more!
+
+Sample app that will log all requests to a file using Apache format, but
+error responses are logged to the console:
+
+```js
+var express = require('express');
+var fs = require('fs');
+var morgan = require('morgan');
+var path = require('path');
+
+var app = express();
+
+// log only 4xx and 5xx responses to console
+app.use(
+ morgan('dev', {
+ skip: function (req, res) {
+ return res.statusCode < 400;
+ },
+ })
+);
+
+// log all requests to access.log
+app.use(
+ morgan('common', {
+ stream: fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' }),
+ })
+);
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### use custom token formats
+
+Sample app that will use custom token formats. This adds an ID to all requests and displays it using the `:id` token.
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+var uuid = require('node-uuid');
+
+morgan.token('id', function getId(req) {
+ return req.id;
+});
+
+var app = express();
+
+app.use(assignId);
+app.use(morgan(':id :method :url :response-time'));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+
+function assignId(req, res, next) {
+ req.id = uuid.v4();
+ next();
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/morgan/master?label=ci
+[ci-url]: https://github.com/expressjs/morgan/actions/workflows/ci.yml
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/morgan/master
+[coveralls-url]: https://coveralls.io/r/expressjs/morgan?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/morgan
+[npm-url]: https://npmjs.org/package/morgan
+[npm-version-image]: https://badgen.net/npm/v/morgan
diff --git a/astro/src/content/resources/es/middleware/multer.md b/astro/src/content/resources/es/middleware/multer.md
new file mode 100644
index 0000000000..326786ab3d
--- /dev/null
+++ b/astro/src/content/resources/es/middleware/multer.md
@@ -0,0 +1,352 @@
+---
+title: Express multer middleware
+module: multer
+---
+
+# Multer [![NPM Version][npm-version-image]][npm-url] [![NPM Downloads][npm-downloads-image]][npm-url] [![Build Status][ci-image]][ci-url] [![Test Coverage][test-image]][test-url] [![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+
+Multer is a node.js middleware for handling `multipart/form-data`, which is primarily used for uploading files. It is written
+on top of [busboy](https://github.com/mscdex/busboy) for maximum efficiency.
+
+**NOTE**: Multer will not process any form which is not multipart (`multipart/form-data`).
+
+## Translations
+
+This README is also available in other languages:
+
+| | |
+| ------------------------------------------------------------------------------ | --------------- |
+| [العربية](https://github.com/expressjs/multer/blob/main/doc/README-ar.md) | Arabic |
+| [简体中文](https://github.com/expressjs/multer/blob/main/doc/README-zh-cn.md) | Chinese |
+| [Français](https://github.com/expressjs/multer/blob/main/doc/README-fr.md) | French |
+| [한국어](https://github.com/expressjs/multer/blob/main/doc/README-ko.md) | Korean |
+| [Português](https://github.com/expressjs/multer/blob/main/doc/README-pt-br.md) | Portuguese (BR) |
+| [Русский язык](https://github.com/expressjs/multer/blob/main/doc/README-ru.md) | Russian |
+| [Español](https://github.com/expressjs/multer/blob/main/doc/README-es.md) | Spanish |
+| [O'zbek tili](https://github.com/expressjs/multer/blob/main/doc/README-uz.md) | Uzbek |
+| [Việt Nam](https://github.com/expressjs/multer/blob/main/doc/README-vi.md) | Vietnamese |
+
+## Installation
+
+```sh
+$ npm install multer
+```
+
+## Usage
+
+Multer adds a `body` object and a `file` or `files` object to the `request` object. The `body` object contains the values of the text fields of the form, the `file` or `files` object contains the files uploaded via the form.
+
+Basic usage example:
+
+Don't forget the `enctype="multipart/form-data"` in your form.
+
+```html
+
+```
+
+```javascript
+const express = require('express');
+const multer = require('multer');
+const upload = multer({ dest: 'uploads/' });
+
+const app = express();
+
+app.post('/profile', upload.single('avatar'), function (req, res, next) {
+ // req.file is the `avatar` file
+ // req.body will hold the text fields, if there were any
+});
+
+app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
+ // req.files is array of `photos` files
+ // req.body will contain the text fields, if there were any
+});
+
+const uploadMiddleware = upload.fields([
+ { name: 'avatar', maxCount: 1 },
+ { name: 'gallery', maxCount: 8 },
+]);
+app.post('/cool-profile', uploadMiddleware, function (req, res, next) {
+ // req.files is an object (String -> Array) where fieldname is the key, and the value is array of files
+ //
+ // e.g.
+ // req.files['avatar'][0] -> File
+ // req.files['gallery'] -> Array
+ //
+ // req.body will contain the text fields, if there were any
+});
+```
+
+In case you need to handle a text-only multipart form, you should use the `.none()` method:
+
+```javascript
+const express = require('express');
+const app = express();
+const multer = require('multer');
+const upload = multer();
+
+app.post('/profile', upload.none(), function (req, res, next) {
+ // req.body contains the text fields
+});
+```
+
+Here's an example on how multer is used in a HTML form. Take special note of the `enctype="multipart/form-data"` and `name="uploaded_file"` fields:
+
+```html
+
+```
+
+Then in your javascript file you would add these lines to access both the file and the body. It is important that you use the `name` field value from the form in your upload function. This tells multer which field on the request it should look for the files in. If these fields aren't the same in the HTML form and on your server, your upload will fail:
+
+```javascript
+const multer = require('multer');
+const upload = multer({ dest: './public/data/uploads/' });
+app.post('/stats', upload.single('uploaded_file'), function (req, res) {
+ // req.file is the name of your file in the form above, here 'uploaded_file'
+ // req.body will hold the text fields, if there were any
+ console.log(req.file, req.body);
+});
+```
+
+## API
+
+### File information
+
+Each file contains the following information:
+
+| Key | Description | Note |
+| -------------- | --------------------------------------------- | --------------- |
+| `fieldname` | Field name specified in the form |
+| `originalname` | Name of the file on the user's computer |
+| `encoding` | Encoding type of the file |
+| `mimetype` | Mime type of the file |
+| `size` | Size of the file in bytes |
+| `destination` | The folder to which the file has been saved | `DiskStorage` |
+| `filename` | The name of the file within the `destination` | `DiskStorage` |
+| `path` | The full path to the uploaded file | `DiskStorage` |
+| `buffer` | A `Buffer` of the entire file | `MemoryStorage` |
+
+### `multer(opts)`
+
+Multer accepts an options object, the most basic of which is the `dest`
+property, which tells Multer where to upload the files. In case you omit the
+options object, the files will be kept in memory and never written to disk.
+
+By default, Multer will rename the files so as to avoid naming conflicts. The
+renaming function can be customized according to your needs.
+
+The following are the options that can be passed to Multer.
+
+| Key | Description |
+| ------------------- | --------------------------------------------------------- |
+| `dest` or `storage` | Where to store the files |
+| `fileFilter` | Function to control which files are accepted |
+| `limits` | Limits of the uploaded data |
+| `preservePath` | Keep the full path of files instead of just the base name |
+
+In an average web app, only `dest` might be required, and configured as shown in
+the following example.
+
+```javascript
+const upload = multer({ dest: 'uploads/' });
+```
+
+If you want more control over your uploads, you'll want to use the `storage`
+option instead of `dest`. Multer ships with storage engines `DiskStorage`
+and `MemoryStorage`; More engines are available from third parties.
+
+#### `.single(fieldname)`
+
+Accept a single file with the name `fieldname`. The single file will be stored
+in `req.file`.
+
+#### `.array(fieldname[, maxCount])`
+
+Accept an array of files, all with the name `fieldname`. Optionally error out if
+more than `maxCount` files are uploaded. The array of files will be stored in
+`req.files`.
+
+#### `.fields(fields)`
+
+Accept a mix of files, specified by `fields`. An object with arrays of files
+will be stored in `req.files`.
+
+`fields` should be an array of objects with `name` and optionally a `maxCount`.
+Example:
+
+```javascript
+[
+ { name: 'avatar', maxCount: 1 },
+ { name: 'gallery', maxCount: 8 },
+];
+```
+
+#### `.none()`
+
+Accept only text fields. If any file upload is made, error with code
+"LIMIT_UNEXPECTED_FILE" will be issued.
+
+#### `.any()`
+
+Accepts all files that comes over the wire. An array of files will be stored in
+`req.files`.
+
+**WARNING:** Make sure that you always handle the files that a user uploads.
+Never add multer as a global middleware since a malicious user could upload
+files to a route that you didn't anticipate. Only use this function on routes
+where you are handling the uploaded files.
+
+### `storage`
+
+#### `DiskStorage`
+
+The disk storage engine gives you full control on storing files to disk.
+
+```javascript
+const storage = multer.diskStorage({
+ destination: function (req, file, cb) {
+ cb(null, '/tmp/my-uploads');
+ },
+ filename: function (req, file, cb) {
+ const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
+ cb(null, file.fieldname + '-' + uniqueSuffix);
+ },
+});
+
+const upload = multer({ storage: storage });
+```
+
+There are two options available, `destination` and `filename`. They are both
+functions that determine where the file should be stored.
+
+`destination` is used to determine within which folder the uploaded files should
+be stored. This can also be given as a `string` (e.g. `'/tmp/uploads'`). If no
+`destination` is given, the operating system's default directory for temporary
+files is used.
+
+**Note:** You are responsible for creating the directory when providing
+`destination` as a function. When passing a string, multer will make sure that
+the directory is created for you.
+
+`filename` is used to determine what the file should be named inside the folder.
+If no `filename` is given, each file will be given a random name that doesn't
+include any file extension.
+
+**Note:** Multer will not append any file extension for you, your function
+should return a filename complete with a file extension.
+
+Each function gets passed both the request (`req`) and some information about
+the file (`file`) to aid with the decision.
+
+Note that `req.body` might not have been fully populated yet. It depends on the
+order that the client transmits fields and files to the server.
+
+For understanding the calling convention used in the callback (needing to pass
+null as the first param), refer to
+[Node.js error handling](https://web.archive.org/web/20220417042018/https://www.joyent.com/node-js/production/design/errors)
+
+#### `MemoryStorage`
+
+The memory storage engine stores the files in memory as `Buffer` objects. It
+doesn't have any options.
+
+```javascript
+const storage = multer.memoryStorage();
+const upload = multer({ storage: storage });
+```
+
+When using memory storage, the file info will contain a field called
+`buffer` that contains the entire file.
+
+**WARNING**: Uploading very large files, or relatively small files in large
+numbers very quickly, can cause your application to run out of memory when
+memory storage is used.
+
+### `limits`
+
+An object specifying the size limits of the following optional properties. Multer passes this object into busboy directly, and the details of the properties can be found on [busboy's page](https://github.com/mscdex/busboy#busboy-methods).
+
+The following integer values are available:
+
+| Key | Description | Default |
+| --------------- | ----------------------------------------------------------------------- | --------- |
+| `fieldNameSize` | Max field name size | 100 bytes |
+| `fieldSize` | Max field value size (in bytes) | 1MB |
+| `fields` | Max number of non-file fields | Infinity |
+| `fileSize` | For multipart forms, the max file size (in bytes) | Infinity |
+| `files` | For multipart forms, the max number of file fields | Infinity |
+| `parts` | For multipart forms, the max number of parts (fields + files) | Infinity |
+| `headerPairs` | For multipart forms, the max number of header key=>value pairs to parse | 2000 |
+
+Specifying the limits can help protect your site against denial of service (DoS) attacks.
+
+### `fileFilter`
+
+Set this to a function to control which files should be uploaded and which
+should be skipped. The function should look like this:
+
+```javascript
+function fileFilter(req, file, cb) {
+ // The function should call `cb` with a boolean
+ // to indicate if the file should be accepted
+
+ // To reject this file pass `false`, like so:
+ cb(null, false);
+
+ // To accept the file pass `true`, like so:
+ cb(null, true);
+
+ // You can always pass an error if something goes wrong:
+ cb(new Error("I don't have a clue!"));
+}
+```
+
+## Error handling
+
+When encountering an error, Multer will delegate the error to Express. You can
+display a nice error page using [the standard express way](http://expressjs.com/guide/error-handling.html).
+
+If you want to catch errors specifically from Multer, you can call the
+middleware function by yourself. Also, if you want to catch only [the Multer errors](https://github.com/expressjs/multer/blob/main/lib/multer-error.js), you can use the `MulterError` class that is attached to the `multer` object itself (e.g. `err instanceof multer.MulterError`).
+
+```javascript
+const multer = require('multer');
+const upload = multer().single('avatar');
+
+app.post('/profile', function (req, res) {
+ upload(req, res, function (err) {
+ if (err instanceof multer.MulterError) {
+ // A Multer error occurred when uploading.
+ } else if (err) {
+ // An unknown error occurred when uploading.
+ }
+
+ // Everything went fine.
+ });
+});
+```
+
+## Custom storage engine
+
+For information on how to build your own storage engine, see [Multer Storage Engine](https://github.com/expressjs/multer/blob/main/StorageEngine.md).
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://github.com/expressjs/multer/actions/workflows/ci.yml/badge.svg
+[ci-url]: https://github.com/expressjs/multer/actions/workflows/ci.yml
+[test-url]: https://coveralls.io/r/expressjs/multer?branch=main
+[test-image]: https://badgen.net/coveralls/c/github/expressjs/multer/main
+[npm-downloads-image]: https://badgen.net/npm/dm/multer
+[npm-url]: https://npmjs.org/package/multer
+[npm-version-image]: https://badgen.net/npm/v/multer
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/multer/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer
diff --git a/astro/src/content/resources/es/middleware/overview.md b/astro/src/content/resources/es/middleware/overview.md
new file mode 100755
index 0000000000..46217759e7
--- /dev/null
+++ b/astro/src/content/resources/es/middleware/overview.md
@@ -0,0 +1,40 @@
+---
+title: Express middleware
+description: Explore a list of Express.js middleware modules maintained by the Express team and the community, including built-in middleware and popular third-party modules.
+module: mw-home
+---
+
+## Express middleware
+
+The Express middleware modules listed here are maintained by the
+[Expressjs team](https://github.com/orgs/expressjs/people).
+
+| Middleware module | Description |
+| ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
+| [body-parser](/en/resources/middleware/body-parser) | Parse HTTP request body. |
+| [compression](/en/resources/middleware/compression) | Compress HTTP responses. |
+| [cookie-parser](/en/resources/middleware/cookie-parser) | Parse cookie header and populate `req.cookies`. See also [cookies](https://github.com/jed/cookies). |
+| [cookie-session](/en/resources/middleware/cookie-session) | Establish cookie-based sessions. |
+| [cors](/en/resources/middleware/cors) | Enable cross-origin resource sharing (CORS) with various options. |
+| [errorhandler](/en/resources/middleware/errorhandler) | Development error-handling/debugging. |
+| [method-override](/en/resources/middleware/method-override) | Override HTTP methods using header. |
+| [morgan](/en/resources/middleware/morgan) | HTTP request logger. |
+| [multer](/en/resources/middleware/multer) | Handle multi-part form data. |
+| [response-time](/en/resources/middleware/response-time) | Record HTTP response time. |
+| [serve-favicon](/en/resources/middleware/serve-favicon) | Serve a favicon. |
+| [serve-index](/en/resources/middleware/serve-index) | Serve directory listing for a given path. |
+| [serve-static](/en/resources/middleware/serve-static) | Serve static files. |
+| [session](/en/resources/middleware/session) | Establish server-based sessions (development only). |
+| [timeout](/en/resources/middleware/timeout) | Set a timeout perioHTTP request processing. |
+| [vhost](/en/resources/middleware/vhost) | Create virtual domains. |
+
+## Additional middleware modules
+
+These are some additional popular middleware modules.
+
+{% include community-caveat.html %}
+
+| Middleware module | Description |
+| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
+| [helmet](https://github.com/helmetjs/helmet) | Helps secure your apps by setting various HTTP headers. |
+| [passport](https://github.com/jaredhanson/passport) | Authentication using "strategies" such as OAuth, OpenID and many others. See [passportjs.org](https://passportjs.org/) for more information. |
diff --git a/astro/src/content/resources/es/middleware/response-time.md b/astro/src/content/resources/es/middleware/response-time.md
new file mode 100644
index 0000000000..f911f480f5
--- /dev/null
+++ b/astro/src/content/resources/es/middleware/response-time.md
@@ -0,0 +1,314 @@
+---
+title: Express response-time middleware
+module: response-time
+---
+
+# compression
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+[![Funding][funding-image]][funding-url]
+
+Node.js compression middleware.
+
+The following compression codings are supported:
+
+- deflate
+- gzip
+- br (brotli)
+
+**Note** Brotli is supported only since Node.js versions v11.7.0 and v10.16.0.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```bash
+$ npm install compression
+```
+
+## API
+
+```js
+var compression = require('compression');
+```
+
+### compression([options])
+
+Returns the compression middleware using the given `options`. The middleware
+will attempt to compress response bodies for all requests that traverse through
+the middleware, based on the given `options`.
+
+This middleware will never compress responses that include a `Cache-Control`
+header with the [`no-transform` directive](https://tools.ietf.org/html/rfc7234#section-5.2.2.4),
+as compressing will transform the body.
+
+#### Options
+
+`compression()` accepts these properties in the options object. In addition to
+those listed below, [zlib](https://nodejs.org/api/zlib.html) options may be
+passed in to the options object or
+[brotli](https://nodejs.org/api/zlib.html#zlib_class_brotlioptions) options.
+
+##### chunkSize
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_CHUNK`, or `16384`.
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### filter
+
+Type: `Function`
+
+A function to decide if the response should be considered for compression.
+This function is called as `filter(req, res)` and is expected to return
+`true` to consider the response for compression, or `false` to not compress
+the response.
+
+The default filter function uses the [compressible](https://www.npmjs.com/package/compressible)
+module to determine if `res.getHeader('Content-Type')` is compressible.
+
+##### level
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_COMPRESSION`, or `-1`
+
+The level of zlib compression to apply to responses. A higher level will result
+in better compression, but will take longer to complete. A lower level will
+result in less compression, but will be much faster.
+
+This is an integer in the range of `0` (no compression) to `9` (maximum
+compression). The special value `-1` can be used to mean the "default
+compression level", which is a default compromise between speed and
+compression (currently equivalent to level 6).
+
+- `-1` Default compression level (also `zlib.constants.Z_DEFAULT_COMPRESSION`).
+- `0` No compression (also `zlib.constants.Z_NO_COMPRESSION`).
+- `1` Fastest compression (also `zlib.constants.Z_BEST_SPEED`).
+- `2`
+- `3`
+- `4`
+- `5`
+- `6` (currently what `zlib.constants.Z_DEFAULT_COMPRESSION` points to).
+- `7`
+- `8`
+- `9` Best compression (also `zlib.constants.Z_BEST_COMPRESSION`).
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### memLevel
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_MEMLEVEL`, or `8`
+
+This specifies how much memory should be allocated for the internal compression
+state and is an integer in the range of `1` (minimum level) and `9` (maximum
+level).
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### brotli
+
+Type: `Object`
+
+This specifies the options for configuring Brotli. See [Node.js documentation](https://nodejs.org/api/zlib.html#class-brotlioptions) for a complete list of available options.
+
+##### strategy
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_STRATEGY`
+
+This is used to tune the compression algorithm. This value only affects the
+compression ratio, not the correctness of the compressed output, even if it
+is not set appropriately.
+
+- `zlib.constants.Z_DEFAULT_STRATEGY` Use for normal data.
+- `zlib.constants.Z_FILTERED` Use for data produced by a filter (or predictor).
+ Filtered data consists mostly of small values with a somewhat random
+ distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect is to force more Huffman coding and less
+ string matching; it is somewhat intermediate between `zlib.constants.Z_DEFAULT_STRATEGY`
+ and `zlib.constants.Z_HUFFMAN_ONLY`.
+- `zlib.constants.Z_FIXED` Use to prevent the use of dynamic Huffman codes, allowing
+ for a simpler decoder for special applications.
+- `zlib.constants.Z_HUFFMAN_ONLY` Use to force Huffman encoding only (no string match).
+- `zlib.constants.Z_RLE` Use to limit match distances to one (run-length encoding).
+ This is designed to be almost as fast as `zlib.constants.Z_HUFFMAN_ONLY`, but give
+ better compression for PNG image data.
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### threshold
+
+Type: `Number` or `String`
+Default: `1kb`
+
+The byte threshold for the response body size before compression is considered
+for the response. This is a number of bytes or any string
+accepted by the [bytes](https://www.npmjs.com/package/bytes) module.
+
+**Note** this is only an advisory setting; if the response size cannot be determined
+at the time the response headers are written, then it is assumed the response is
+_over_ the threshold. To guarantee the response size can be determined, be sure
+set a `Content-Length` response header.
+
+##### windowBits
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_WINDOWBITS`, or `15`
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### enforceEncoding
+
+Type: `String`
+Default: `identity`
+
+This is the default encoding to use when the client does not specify an encoding in the request's [Accept-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) header.
+
+#### .filter
+
+The default `filter` function. This is used to construct a custom filter
+function that is an extension of the default function.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+app.use(compression({ filter: shouldCompress }));
+
+function shouldCompress(req, res) {
+ if (req.headers['x-no-compression']) {
+ // don't compress responses with this request header
+ return false;
+ }
+
+ // fallback to standard filter function
+ return compression.filter(req, res);
+}
+```
+
+### res.flush
+
+This module adds a `res.flush()` method to force the partially-compressed
+response to be flushed to the client.
+
+## Examples
+
+### express
+
+When using this module with express, simply `app.use` the module as
+high as you like. Requests that pass through the middleware will be compressed.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress all responses
+app.use(compression());
+
+// add all routes
+```
+
+### Node.js HTTP server
+
+```js
+var compression = require('compression')({ threshold: 0 });
+var http = require('http');
+
+function createServer(fn) {
+ return http.createServer(function (req, res) {
+ compression(req, res, function (err) {
+ if (err) {
+ res.statusCode = err.status || 500;
+ res.end(err.message);
+ return;
+ }
+
+ fn(req, res);
+ });
+ });
+}
+
+var server = createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello world!');
+});
+
+server.listen(3000, () => {
+ console.log('> Listening at http://localhost:3000');
+});
+```
+
+### Server-Sent Events
+
+Because of the nature of compression this module does not work out of the box
+with server-sent events. To compress content, a window of the output needs to
+be buffered up in order to get good compression. Typically when using server-sent
+events, there are certain block of data that need to reach the client.
+
+You can achieve this by calling `res.flush()` when you need the data written to
+actually make it to the client.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress responses
+app.use(compression());
+
+// server-sent event stream
+app.get('/events', function (req, res) {
+ res.setHeader('Content-Type', 'text/event-stream');
+ res.setHeader('Cache-Control', 'no-cache');
+
+ // send a ping approx every 2 seconds
+ var timer = setInterval(function () {
+ res.write('data: ping\n\n');
+
+ // !!! this is the important part
+ res.flush();
+ }, 2000);
+
+ res.on('close', function () {
+ clearInterval(timer);
+ });
+});
+```
+
+## Contributing
+
+The Express.js project welcomes all constructive contributions. Contributions take many forms,
+from code for bug fixes and enhancements, to additions and fixes to documentation, additional
+tests, triaging incoming pull requests and issues, and more!
+
+See the [Contributing Guide](https://github.com/expressjs/express/blob/master/Contributing.md) for more technical details on contributing.
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://badgen.net/npm/v/compression
+[npm-url]: https://npmjs.org/package/compression
+[downloads-image]: https://badgen.net/npm/dm/compression
+[downloads-url]: https://npmcharts.com/compare/compression?minimal=true
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/compression/master?label=CI
+[github-actions-ci-url]: https://github.com/expressjs/compression/actions?query=workflow%3Aci
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/compression/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/compression
+[funding-url]: https://opencollective.com/express
+[funding-image]: https://badgen.net/badge/icon/sponsor/pink?icon=github&label=Open%20Collective
diff --git a/astro/src/content/resources/es/middleware/serve-favicon.md b/astro/src/content/resources/es/middleware/serve-favicon.md
new file mode 100644
index 0000000000..7a77865c6b
--- /dev/null
+++ b/astro/src/content/resources/es/middleware/serve-favicon.md
@@ -0,0 +1,156 @@
+---
+title: Express serve-favicon middleware
+module: serve-favicon
+---
+
+# serve-index
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Linux Build Status][ci-image]][ci-url]
+[![Windows Build][appveyor-image]][appveyor-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+Serves pages that contain directory listings for a given path.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-index
+```
+
+## API
+
+```js
+var serveIndex = require('serve-index');
+```
+
+### serveIndex(path, options)
+
+Returns middlware that serves an index of the directory in the given `path`.
+
+The `path` is based off the `req.url` value, so a `req.url` of `'/some/dir`
+with a `path` of `'public'` will look at `'public/some/dir'`. If you are using
+something like `express`, you can change the URL "base" with `app.use` (see
+the express example).
+
+#### Options
+
+Serve index accepts these properties in the options object.
+
+##### filter
+
+Apply this filter function to files. Defaults to `false`. The `filter` function
+is called for each file, with the signature `filter(filename, index, files, dir)`
+where `filename` is the name of the file, `index` is the array index, `files` is
+the array of files and `dir` is the absolute path the file is located (and thus,
+the directory the listing is for).
+
+##### hidden
+
+Display hidden (dot) files. Defaults to `false`.
+
+##### icons
+
+Display icons. Defaults to `false`.
+
+##### stylesheet
+
+Optional path to a CSS stylesheet. Defaults to a built-in stylesheet.
+
+##### template
+
+Optional path to an HTML template or a function that will render a HTML
+string. Defaults to a built-in template.
+
+When given a string, the string is used as a file path to load and then the
+following tokens are replaced in templates:
+
+- `{directory}` with the name of the directory.
+- `{files}` with the HTML of an unordered list of file links.
+- `{linked-path}` with the HTML of a link to the directory.
+- `{style}` with the specified stylesheet and embedded images.
+
+When given as a function, the function is called as `template(locals, callback)`
+and it needs to invoke `callback(error, htmlString)`. The following are the
+provided locals:
+
+- `directory` is the directory being displayed (where `/` is the root).
+- `displayIcons` is a Boolean for if icons should be rendered or not.
+- `fileList` is a sorted array of files in the directory. The array contains
+ objects with the following properties:
+ - `name` is the relative name for the file.
+ - `stat` is a `fs.Stats` object for the file.
+- `path` is the full filesystem path to `directory`.
+- `style` is the default stylesheet or the contents of the `stylesheet` option.
+- `viewName` is the view name provided by the `view` option.
+
+##### view
+
+Display mode. `tiles` and `details` are available. Defaults to `tiles`.
+
+## Examples
+
+### Serve directory indexes with vanilla node.js http server
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var serveIndex = require('serve-index');
+var serveStatic = require('serve-static');
+
+// Serve directory indexes for public/ftp folder (with icons)
+var index = serveIndex('public/ftp', { icons: true });
+
+// Serve up public/ftp folder files
+var serve = serveStatic('public/ftp');
+
+// Create server
+var server = http.createServer(function onRequest(req, res) {
+ var done = finalhandler(req, res);
+ serve(req, res, function onNext(err) {
+ if (err) return done(err);
+ index(req, res, done);
+ });
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve directory indexes with express
+
+```js
+var express = require('express');
+var serveIndex = require('serve-index');
+
+var app = express();
+
+// Serve URLs like /ftp/thing as public/ftp/thing
+// The express.static serves the file contents
+// The serveIndex is this module serving the directory
+app.use('/ftp', express.static('public/ftp'), serveIndex('public/ftp', { icons: true }));
+
+// Listen
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE). The [Silk](http://www.famfamfam.com/lab/icons/silk/) icons
+are created by/copyright of [FAMFAMFAM](http://www.famfamfam.com/).
+
+[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/serve-index/master.svg?label=windows
+[appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index
+[ci-image]: https://badgen.net/github/checks/expressjs/serve-index/master?label=ci
+[ci-url]: https://github.com/expressjs/serve-index/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/serve-index/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-index?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/serve-index.svg
+[downloads-url]: https://npmjs.org/package/serve-index
+[npm-image]: https://img.shields.io/npm/v/serve-index.svg
+[npm-url]: https://npmjs.org/package/serve-index
diff --git a/astro/src/content/resources/es/middleware/serve-index.md b/astro/src/content/resources/es/middleware/serve-index.md
new file mode 100644
index 0000000000..da03cf94b2
--- /dev/null
+++ b/astro/src/content/resources/es/middleware/serve-index.md
@@ -0,0 +1,156 @@
+---
+title: Express serve-index middleware
+module: serve-index
+---
+
+# serve-index
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Linux Build Status][ci-image]][ci-url]
+[![Windows Build][appveyor-image]][appveyor-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+Serves pages that contain directory listings for a given path.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-index
+```
+
+## API
+
+```js
+var serveIndex = require('serve-index');
+```
+
+### serveIndex(path, options)
+
+Returns middlware that serves an index of the directory in the given `path`.
+
+The `path` is based off the `req.url` value, so a `req.url` of `'/some/dir`
+with a `path` of `'public'` will look at `'public/some/dir'`. If you are using
+something like `express`, you can change the URL "base" with `app.use` (see
+the express example).
+
+#### Options
+
+Serve index accepts these properties in the options object.
+
+##### filter
+
+Apply this filter function to files. Defaults to `false`. The `filter` function
+is called for each file, with the signature `filter(filename, index, files, dir)`
+where `filename` is the name of the file, `index` is the array index, `files` is
+the array of files and `dir` is the absolute path the file is located (and thus,
+the directory the listing is for).
+
+##### hidden
+
+Display hidden (dot) files. Defaults to `false`.
+
+##### icons
+
+Display icons. Defaults to `false`.
+
+##### stylesheet
+
+Optional path to a CSS stylesheet. Defaults to a built-in stylesheet.
+
+##### template
+
+Optional path to an HTML template or a function that will render a HTML
+string. Defaults to a built-in template.
+
+When given a string, the string is used as a file path to load and then the
+following tokens are replaced in templates:
+
+- `{directory}` with the name of the directory.
+- `{files}` with the HTML of an unordered list of file links.
+- `{linked-path}` with the HTML of a link to the directory.
+- `{style}` with the specified stylesheet and embedded images.
+
+When given as a function, the function is called as `template(locals, callback)`
+and it needs to invoke `callback(error, htmlString)`. The following are the
+provided locals:
+
+- `directory` is the directory being displayed (where `/` is the root).
+- `displayIcons` is a Boolean for if icons should be rendered or not.
+- `fileList` is a sorted array of files in the directory. The array contains
+ objects with the following properties:
+ - `name` is the relative name for the file.
+ - `stat` is a `fs.Stats` object for the file.
+- `path` is the full filesystem path to `directory`.
+- `style` is the default stylesheet or the contents of the `stylesheet` option.
+- `viewName` is the view name provided by the `view` option.
+
+##### view
+
+Display mode. `tiles` and `details` are available. Defaults to `tiles`.
+
+## Examples
+
+### Serve directory indexes with vanilla node.js http server
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var serveIndex = require('serve-index');
+var serveStatic = require('serve-static');
+
+// Serve directory indexes for public/ftp folder (with icons)
+var index = serveIndex('public/ftp', { icons: true });
+
+// Serve up public/ftp folder files
+var serve = serveStatic('public/ftp');
+
+// Create server
+var server = http.createServer(function onRequest(req, res) {
+ var done = finalhandler(req, res);
+ serve(req, res, function onNext(err) {
+ if (err) return done(err);
+ index(req, res, done);
+ });
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve directory indexes with express
+
+```js
+var express = require('express');
+var serveIndex = require('serve-index');
+
+var app = express();
+
+// Serve URLs like /ftp/thing as public/ftp/thing
+// The express.static serves the file contents
+// The serveIndex is this module serving the directory
+app.use('/ftp', express.static('public/ftp'), serveIndex('public/ftp', { icons: true }));
+
+// Listen
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE). The [Silk](http://www.famfamfam.com/lab/icons/silk/) icons
+are created by/copyright of [FAMFAMFAM](http://www.famfamfam.com/).
+
+[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/serve-index/master.svg?label=windows
+[appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index
+[ci-image]: https://badgen.net/github/checks/expressjs/serve-index/master?label=ci
+[ci-url]: https://github.com/expressjs/serve-index/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/serve-index/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-index?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/serve-index.svg
+[downloads-url]: https://npmjs.org/package/serve-index
+[npm-image]: https://img.shields.io/npm/v/serve-index.svg
+[npm-url]: https://npmjs.org/package/serve-index
diff --git a/astro/src/content/resources/es/middleware/serve-static.md b/astro/src/content/resources/es/middleware/serve-static.md
new file mode 100644
index 0000000000..b048165d7b
--- /dev/null
+++ b/astro/src/content/resources/es/middleware/serve-static.md
@@ -0,0 +1,260 @@
+---
+title: Express serve-static middleware
+module: serve-static
+---
+
+# serve-static
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![CI][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-static
+```
+
+## API
+
+```js
+const serveStatic = require('serve-static');
+```
+
+### serveStatic(root, options)
+
+Create a new middleware function to serve files from within a given root
+directory. The file to serve will be determined by combining `req.url`
+with the provided root directory. When a file is not found, instead of
+sending a 404 response, this module will instead call `next()` to move on
+to the next middleware, allowing for stacking and fall-backs.
+
+#### Options
+
+##### acceptRanges
+
+Enable or disable accepting ranged requests, defaults to true.
+Disabling this will not send `Accept-Ranges` and ignore the contents
+of the `Range` request header.
+
+##### cacheControl
+
+Enable or disable setting `Cache-Control` response header, defaults to
+true. Disabling this will ignore the `immutable` and `maxAge` options.
+
+##### dotfiles
+
+Set how "dotfiles" are treated when encountered. A dotfile is a file
+or directory that begins with a dot ("."). Note this check is done on
+the path itself without checking if the path actually exists on the
+disk. If `root` is specified, only the dotfiles above the root are
+checked (i.e. the root itself can be within a dotfile when set
+to "deny").
+
+- `'allow'` No special treatment for dotfiles.
+- `'deny'` Deny a request for a dotfile and 403/`next()`.
+- `'ignore'` Pretend like the dotfile does not exist and 404/`next()`.
+
+The default value is `'ignore'`.
+
+##### etag
+
+Enable or disable etag generation, defaults to true.
+
+##### extensions
+
+Set file extension fallbacks. When set, if a file is not found, the given
+extensions will be added to the file name and search for. The first that
+exists will be served. Example: `['html', 'htm']`.
+
+The default value is `false`.
+
+##### fallthrough
+
+Set the middleware to have client errors fall-through as just unhandled
+requests, otherwise forward a client error. The difference is that client
+errors like a bad request or a request to a non-existent file will cause
+this middleware to simply `next()` to your next middleware when this value
+is `true`. When this value is `false`, these errors (even 404s), will invoke
+`next(err)`.
+
+Typically `true` is desired such that multiple physical directories can be
+mapped to the same web address or for routes to fill in non-existent files.
+
+The value `false` can be used if this middleware is mounted at a path that
+is designed to be strictly a single file system directory, which allows for
+short-circuiting 404s for less overhead. This middleware will also reply to
+all methods.
+
+The default value is `true`.
+
+##### immutable
+
+Enable or disable the `immutable` directive in the `Cache-Control` response
+header, defaults to `false`. If set to `true`, the `maxAge` option should
+also be specified to enable caching. The `immutable` directive will prevent
+supported clients from making conditional requests during the life of the
+`maxAge` option to check if the file has changed.
+
+##### index
+
+By default this module will send "index.html" files in response to a request
+on a directory. To disable this set `false` or to supply a new index pass a
+string or an array in preferred order.
+
+##### lastModified
+
+Enable or disable `Last-Modified` header, defaults to true. Uses the file
+system's last modified value.
+
+##### maxAge
+
+Provide a max-age in milliseconds for http caching, defaults to 0. This
+can also be a string accepted by the [ms](https://www.npmjs.org/package/ms#readme)
+module.
+
+##### redirect
+
+Redirect to trailing "/" when the pathname is a dir. Defaults to `true`.
+
+##### setHeaders
+
+Function to set custom headers on response. Alterations to the headers need to
+occur synchronously. The function is called as `fn(res, path, stat)`, where
+the arguments are:
+
+- `res` the response object
+- `path` the file path that is being sent
+- `stat` the stat object of the file that is being sent
+
+## Examples
+
+### Serve files with vanilla node.js http server
+
+```js
+const finalhandler = require('finalhandler');
+const http = require('http');
+const serveStatic = require('serve-static');
+
+// Serve up public/ftp folder
+const serve = serveStatic('public/ftp', { index: ['index.html', 'index.htm'] });
+
+// Create server
+const server = http.createServer((req, res) => {
+ serve(req, res, finalhandler(req, res));
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve all files as downloads
+
+```js
+const contentDisposition = require('content-disposition');
+const finalhandler = require('finalhandler');
+const http = require('http');
+const serveStatic = require('serve-static');
+
+// Serve up public/ftp folder
+const serve = serveStatic('public/ftp', {
+ index: false,
+ setHeaders: setHeaders,
+});
+
+// Set header to force download
+function setHeaders(res, path) {
+ res.setHeader('Content-Disposition', contentDisposition(path));
+}
+
+// Create server
+const server = http.createServer((req, res) => {
+ serve(req, res, finalhandler(req, res));
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serving using express
+
+#### Simple
+
+This is a simple example of using Express.
+
+```js
+const express = require('express');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(serveStatic('public/ftp', { index: ['default.html', 'default.htm'] }));
+app.listen(3000);
+```
+
+#### Multiple roots
+
+This example shows a simple way to search through multiple directories.
+Files are searched for in `public-optimized/` first, then `public/` second
+as a fallback.
+
+```js
+const express = require('express');
+const path = require('path');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(serveStatic(path.join(__dirname, 'public-optimized')));
+app.use(serveStatic(path.join(__dirname, 'public')));
+app.listen(3000);
+```
+
+#### Different settings for paths
+
+This example shows how to set a different max age depending on the served
+file. In this example, HTML files are not cached, while everything else
+is for 1 day.
+
+```js
+const express = require('express');
+const path = require('path');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(
+ serveStatic(path.join(__dirname, 'public'), {
+ maxAge: '1d',
+ setHeaders: setCustomCacheControl,
+ })
+);
+
+app.listen(3000);
+
+function setCustomCacheControl(res, file) {
+ if (path.extname(file) === '.html') {
+ // Custom Cache-Control for HTML files
+ res.setHeader('Cache-Control', 'public, max-age=0');
+ }
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/serve-static/master
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-static?branch=master
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/serve-static/master?label=linux
+[github-actions-ci-url]: https://github.com/expressjs/serve-static/actions/workflows/ci.yml
+[node-image]: https://badgen.net/npm/node/serve-static
+[node-url]: https://nodejs.org/en/download/
+[npm-downloads-image]: https://badgen.net/npm/dm/serve-static
+[npm-url]: https://npmjs.org/package/serve-static
+[npm-version-image]: https://badgen.net/npm/v/serve-static
diff --git a/astro/src/content/resources/es/middleware/session.md b/astro/src/content/resources/es/middleware/session.md
new file mode 100644
index 0000000000..90f3837a42
--- /dev/null
+++ b/astro/src/content/resources/es/middleware/session.md
@@ -0,0 +1,1046 @@
+---
+title: Express session middleware
+module: session
+---
+
+# express-session
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][node-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install express-session
+```
+
+## API
+
+```js
+var session = require('express-session');
+```
+
+### session(options)
+
+Create a session middleware with the given `options`.
+
+**Note** Session data is _not_ saved in the cookie itself, just the session ID.
+Session data is stored server-side.
+
+**Note** Since version 1.5.0, the [`cookie-parser` middleware](https://www.npmjs.com/package/cookie-parser)
+no longer needs to be used for this module to work. This module now directly reads
+and writes cookies on `req`/`res`. Using `cookie-parser` may result in issues
+if the `secret` is not the same between this module and `cookie-parser`.
+
+**Warning** The default server-side session storage, `MemoryStore`, is _purposely_
+not designed for a production environment. It will leak memory under most
+conditions, does not scale past a single process, and is meant for debugging and
+developing.
+
+For a list of stores, see [compatible session stores](#compatible-session-stores).
+
+#### Options
+
+`express-session` accepts these properties in the options object.
+
+##### cookie
+
+Settings object for the session ID cookie. The default value is
+`{ path: '/', httpOnly: true, secure: false, maxAge: null }`.
+
+The following are options that can be set in this object.
+
+##### cookie.domain
+
+Specifies the value for the `Domain` `Set-Cookie` attribute. By default, no domain
+is set, and most clients will consider the cookie to apply to only the current
+domain.
+
+##### cookie.expires
+
+Specifies the `Date` object to be the value for the `Expires` `Set-Cookie` attribute.
+By default, no expiration is set, and most clients will consider this a
+"non-persistent cookie" and will delete it on a condition like exiting a web browser
+application.
+
+**Note** If both `expires` and `maxAge` are set in the options, then the last one
+defined in the object is what is used.
+
+**Note** The `expires` option should not be set directly; instead only use the `maxAge`
+option.
+
+##### cookie.httpOnly
+
+Specifies the `boolean` value for the `HttpOnly` `Set-Cookie` attribute. When truthy,
+the `HttpOnly` attribute is set, otherwise it is not. By default, the `HttpOnly`
+attribute is set.
+
+**Note** be careful when setting this to `true`, as compliant clients will not allow
+client-side JavaScript to see the cookie in `document.cookie`.
+
+##### cookie.maxAge
+
+Specifies the `number` (in milliseconds) to use when calculating the `Expires`
+`Set-Cookie` attribute. This is done by taking the current server time and adding
+`maxAge` milliseconds to the value to calculate an `Expires` datetime. By default,
+no maximum age is set.
+
+**Note** If both `expires` and `maxAge` are set in the options, then the last one
+defined in the object is what is used.
+
+##### cookie.partitioned
+
+Specifies the `boolean` value for the [`Partitioned` `Set-Cookie`](rfc-cutler-httpbis-partitioned-cookies)
+attribute. When truthy, the `Partitioned` attribute is set, otherwise it is not.
+By default, the `Partitioned` attribute is not set.
+
+**Note** This is an attribute that has not yet been fully standardized, and may
+change in the future. This also means many clients may ignore this attribute until
+they understand it.
+
+More information about can be found in [the proposal](https://github.com/privacycg/CHIPS).
+
+##### cookie.path
+
+Specifies the value for the `Path` `Set-Cookie`. By default, this is set to `'/'`, which
+is the root path of the domain.
+
+##### cookie.priority
+
+Specifies the `string` to be the value for the [`Priority` `Set-Cookie` attribute][rfc-west-cookie-priority-00-4.1].
+
+- `'low'` will set the `Priority` attribute to `Low`.
+- `'medium'` will set the `Priority` attribute to `Medium`, the default priority when not set.
+- `'high'` will set the `Priority` attribute to `High`.
+
+More information about the different priority levels can be found in
+[the specification][rfc-west-cookie-priority-00-4.1].
+
+**Note** This is an attribute that has not yet been fully standardized, and may change in the future.
+This also means many clients may ignore this attribute until they understand it.
+
+##### cookie.sameSite
+
+Specifies the `boolean` or `string` to be the value for the `SameSite` `Set-Cookie` attribute.
+By default, this is `false`.
+
+- `true` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
+- `false` will not set the `SameSite` attribute.
+- `'lax'` will set the `SameSite` attribute to `Lax` for lax same site enforcement.
+- `'none'` will set the `SameSite` attribute to `None` for an explicit cross-site cookie.
+- `'strict'` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
+
+More information about the different enforcement levels can be found in
+[the specification][rfc-6265bis-03-4.1.2.7].
+
+**Note** This is an attribute that has not yet been fully standardized, and may change in
+the future. This also means many clients may ignore this attribute until they understand it.
+
+**Note** There is a [draft spec](https://tools.ietf.org/html/draft-west-cookie-incrementalism-01)
+that requires that the `Secure` attribute be set to `true` when the `SameSite` attribute has been
+set to `'none'`. Some web browsers or other clients may be adopting this specification.
+
+##### cookie.secure
+
+Specifies the `boolean` value for the `Secure` `Set-Cookie` attribute. When truthy,
+the `Secure` attribute is set, otherwise it is not. By default, the `Secure`
+attribute is not set.
+
+**Note** be careful when setting this to `true`, as compliant clients will not send
+the cookie back to the server in the future if the browser does not have an HTTPS
+connection.
+
+Please note that `secure: true` is a **recommended** option. However, it requires
+an https-enabled website, i.e., HTTPS is necessary for secure cookies. If `secure`
+is set, and you access your site over HTTP, the cookie will not be set. If you
+have your node.js behind a proxy and are using `secure: true`, you need to set
+"trust proxy" in express:
+
+```js
+var app = express();
+app.set('trust proxy', 1); // trust first proxy
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ cookie: { secure: true },
+ })
+);
+```
+
+For using secure cookies in production, but allowing for testing in development,
+the following is an example of enabling this setup based on `NODE_ENV` in express:
+
+```js
+var app = express();
+var sess = {
+ secret: 'keyboard cat',
+ cookie: {},
+};
+
+if (app.get('env') === 'production') {
+ app.set('trust proxy', 1); // trust first proxy
+ sess.cookie.secure = true; // serve secure cookies
+}
+
+app.use(session(sess));
+```
+
+The `cookie.secure` option can also be set to the special value `'auto'` to have
+this setting automatically match the determined security of the connection. Be
+careful when using this setting if the site is available both as HTTP and HTTPS,
+as once the cookie is set on HTTPS, it will no longer be visible over HTTP. This
+is useful when the Express `"trust proxy"` setting is properly setup to simplify
+development vs production configuration.
+
+##### genid
+
+Function to call to generate a new session ID. Provide a function that returns
+a string that will be used as a session ID. The function is given `req` as the
+first argument if you want to use some value attached to `req` when generating
+the ID.
+
+The default value is a function which uses the `uid-safe` library to generate IDs.
+
+**NOTE** be careful to generate unique IDs so your sessions do not conflict.
+
+```js
+app.use(
+ session({
+ genid: function (req) {
+ return genuuid(); // use UUIDs for session IDs
+ },
+ secret: 'keyboard cat',
+ })
+);
+```
+
+##### name
+
+The name of the session ID cookie to set in the response (and read from in the
+request).
+
+The default value is `'connect.sid'`.
+
+**Note** if you have multiple apps running on the same hostname (this is just
+the name, i.e. `localhost` or `127.0.0.1`; different schemes and ports do not
+name a different hostname), then you need to separate the session cookies from
+each other. The simplest method is to simply set different `name`s per app.
+
+##### proxy
+
+Trust the reverse proxy when setting secure cookies (via the "X-Forwarded-Proto"
+header).
+
+The default value is `undefined`.
+
+- `true` The "X-Forwarded-Proto" header will be used.
+- `false` All headers are ignored and the connection is considered secure only
+ if there is a direct TLS/SSL connection.
+- `undefined` Uses the "trust proxy" setting from express
+
+##### resave
+
+Forces the session to be saved back to the session store, even if the session
+was never modified during the request. Depending on your store this may be
+necessary, but it can also create race conditions where a client makes two
+parallel requests to your server and changes made to the session in one
+request may get overwritten when the other request ends, even if it made no
+changes (this behavior also depends on what store you're using).
+
+The default value is `true`, but using the default has been deprecated,
+as the default will change in the future. Please research into this setting
+and choose what is appropriate to your use-case. Typically, you'll want
+`false`.
+
+How do I know if this is necessary for my store? The best way to know is to
+check with your store if it implements the `touch` method. If it does, then
+you can safely set `resave: false`. If it does not implement the `touch`
+method and your store sets an expiration date on stored sessions, then you
+likely need `resave: true`.
+
+##### rolling
+
+Force the session identifier cookie to be set on every response. The expiration
+is reset to the original [`maxAge`](#cookiemaxage), resetting the expiration
+countdown.
+
+The default value is `false`.
+
+With this enabled, the session identifier cookie will expire in
+[`maxAge`](#cookiemaxage) since the last response was sent instead of in
+[`maxAge`](#cookiemaxage) since the session was last modified by the server.
+
+This is typically used in conjunction with short, non-session-length
+[`maxAge`](#cookiemaxage) values to provide a quick timeout of the session data
+with reduced potential of it occurring during on going server interactions.
+
+**Note** When this option is set to `true` but the `saveUninitialized` option is
+set to `false`, the cookie will not be set on a response with an uninitialized
+session. This option only modifies the behavior when an existing session was
+loaded for the request.
+
+##### saveUninitialized
+
+Forces a session that is "uninitialized" to be saved to the store. A session is
+uninitialized when it is new but not modified. Choosing `false` is useful for
+implementing login sessions, reducing server storage usage, or complying with
+laws that require permission before setting a cookie. Choosing `false` will also
+help with race conditions where a client makes multiple parallel requests
+without a session.
+
+The default value is `true`, but using the default has been deprecated, as the
+default will change in the future. Please research into this setting and
+choose what is appropriate to your use-case.
+
+**Note** if you are using Session in conjunction with PassportJS, Passport
+will add an empty Passport object to the session for use after a user is
+authenticated, which will be treated as a modification to the session, causing
+it to be saved. _This has been fixed in PassportJS 0.3.0_
+
+##### secret
+
+**Required option**
+
+This is the secret used to sign the session ID cookie. The secret can be any type
+of value that is supported by Node.js `crypto.createHmac` (like a string or a
+`Buffer`). This can be either a single secret, or an array of multiple secrets. If
+an array of secrets is provided, only the first element will be used to sign the
+session ID cookie, while all the elements will be considered when verifying the
+signature in requests. The secret itself should be not easily parsed by a human and
+would best be a random set of characters. A best practice may include:
+
+- The use of environment variables to store the secret, ensuring the secret itself
+ does not exist in your repository.
+- Periodic updates of the secret, while ensuring the previous secret is in the
+ array.
+
+Using a secret that cannot be guessed will reduce the ability to hijack a session to
+only guessing the session ID (as determined by the `genid` option).
+
+Changing the secret value will invalidate all existing sessions. In order to rotate
+the secret without invalidating sessions, provide an array of secrets, with the new
+secret as first element of the array, and including previous secrets as the later
+elements.
+
+**Note** HMAC-256 is used to sign the session ID. For this reason, the secret should
+contain at least 32 bytes of entropy.
+
+##### store
+
+The session store instance, defaults to a new `MemoryStore` instance.
+
+##### unset
+
+Control the result of unsetting `req.session` (through `delete`, setting to `null`,
+etc.).
+
+The default value is `'keep'`.
+
+- `'destroy'` The session will be destroyed (deleted) when the response ends.
+- `'keep'` The session in the store will be kept, but modifications made during
+ the request are ignored and not saved.
+
+### req.session
+
+To store or access session data, simply use the request property `req.session`,
+which is (generally) serialized as JSON by the store, so nested objects
+are typically fine. For example below is a user-specific view counter:
+
+```js
+// Use the session middleware
+app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 } }));
+
+// Access the session as req.session
+app.get('/', function (req, res, next) {
+ if (req.session.views) {
+ req.session.views++;
+ res.setHeader('Content-Type', 'text/html');
+ res.write('views: ' + req.session.views + '
');
+ res.write('expires in: ' + req.session.cookie.maxAge / 1000 + 's
');
+ res.end();
+ } else {
+ req.session.views = 1;
+ res.end('welcome to the session demo. refresh!');
+ }
+});
+```
+
+#### Session.regenerate(callback)
+
+To regenerate the session simply invoke the method. Once complete,
+a new SID and `Session` instance will be initialized at `req.session`
+and the `callback` will be invoked.
+
+```js
+req.session.regenerate(function (err) {
+ // will have a new session here
+});
+```
+
+#### Session.destroy(callback)
+
+Destroys the session and will unset the `req.session` property.
+Once complete, the `callback` will be invoked.
+
+```js
+req.session.destroy(function (err) {
+ // cannot access session here
+});
+```
+
+#### Session.reload(callback)
+
+Reloads the session data from the store and re-populates the
+`req.session` object. Once complete, the `callback` will be invoked.
+
+```js
+req.session.reload(function (err) {
+ // session updated
+});
+```
+
+#### Session.save(callback)
+
+Save the session back to the store, replacing the contents on the store with the
+contents in memory (though a store may do something else--consult the store's
+documentation for exact behavior).
+
+This method is automatically called at the end of the HTTP response if the
+session data has been altered (though this behavior can be altered with various
+options in the middleware constructor). Because of this, typically this method
+does not need to be called.
+
+There are some cases where it is useful to call this method, for example,
+redirects, long-lived requests or in WebSockets.
+
+```js
+req.session.save(function (err) {
+ // session saved
+});
+```
+
+#### Session.touch()
+
+Updates the `.maxAge` property. Typically this is
+not necessary to call, as the session middleware does this for you.
+
+### req.session.id
+
+Each session has a unique ID associated with it. This property is an
+alias of [`req.sessionID`](#reqsessionid-1) and cannot be modified.
+It has been added to make the session ID accessible from the `session`
+object.
+
+### req.session.cookie
+
+Each session has a unique cookie object accompany it. This allows
+you to alter the session cookie per visitor. For example we can
+set `req.session.cookie.expires` to `false` to enable the cookie
+to remain for only the duration of the user-agent.
+
+#### Cookie.maxAge
+
+Alternatively `req.session.cookie.maxAge` will return the time
+remaining in milliseconds, which we may also re-assign a new value
+to adjust the `.expires` property appropriately. The following
+are essentially equivalent
+
+```js
+var hour = 3600000;
+req.session.cookie.expires = new Date(Date.now() + hour);
+req.session.cookie.maxAge = hour;
+```
+
+For example when `maxAge` is set to `60000` (one minute), and 30 seconds
+has elapsed it will return `30000` until the current request has completed,
+at which time `req.session.touch()` is called to reset
+`req.session.cookie.maxAge` to its original value.
+
+```js
+req.session.cookie.maxAge; // => 30000
+```
+
+#### Cookie.originalMaxAge
+
+The `req.session.cookie.originalMaxAge` property returns the original
+`maxAge` (time-to-live), in milliseconds, of the session cookie.
+
+### req.sessionID
+
+To get the ID of the loaded session, access the request property
+`req.sessionID`. This is simply a read-only value set when a session
+is loaded/created.
+
+## Session Store Implementation
+
+Every session store _must_ be an `EventEmitter` and implement specific
+methods. The following methods are the list of **required**, **recommended**,
+and **optional**.
+
+- Required methods are ones that this module will always call on the store.
+- Recommended methods are ones that this module will call on the store if
+ available.
+- Optional methods are ones this module does not call at all, but helps
+ present uniform stores to users.
+
+For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo.
+
+### store.all(callback)
+
+**Optional**
+
+This optional method is used to get all sessions in the store as an array. The
+`callback` should be called as `callback(error, sessions)`.
+
+### store.destroy(sid, callback)
+
+**Required**
+
+This required method is used to destroy/delete a session from the store given
+a session ID (`sid`). The `callback` should be called as `callback(error)` once
+the session is destroyed.
+
+### store.clear(callback)
+
+**Optional**
+
+This optional method is used to delete all sessions from the store. The
+`callback` should be called as `callback(error)` once the store is cleared.
+
+### store.length(callback)
+
+**Optional**
+
+This optional method is used to get the count of all sessions in the store.
+The `callback` should be called as `callback(error, len)`.
+
+### store.get(sid, callback)
+
+**Required**
+
+This required method is used to get a session from the store given a session
+ID (`sid`). The `callback` should be called as `callback(error, session)`.
+
+The `session` argument should be a session if found, otherwise `null` or
+`undefined` if the session was not found (and there was no error). A special
+case is made when `error.code === 'ENOENT'` to act like `callback(null, null)`.
+
+### store.set(sid, session, callback)
+
+**Required**
+
+This required method is used to upsert a session into the store given a
+session ID (`sid`) and session (`session`) object. The callback should be
+called as `callback(error)` once the session has been set in the store.
+
+### store.touch(sid, session, callback)
+
+**Recommended**
+
+This recommended method is used to "touch" a given session given a
+session ID (`sid`) and session (`session`) object. The `callback` should be
+called as `callback(error)` once the session has been touched.
+
+This is primarily used when the store will automatically delete idle sessions
+and this method is used to signal to the store the given session is active,
+potentially resetting the idle timer.
+
+## Compatible Session Stores
+
+The following modules implement a session store that is compatible with this
+module. Please make a PR to add additional modules :)
+
+[![★][aerospike-session-store-image] aerospike-session-store][aerospike-session-store-url] A session store using [Aerospike](http://www.aerospike.com/).
+
+[aerospike-session-store-url]: https://www.npmjs.com/package/aerospike-session-store
+[aerospike-session-store-image]: https://badgen.net/github/stars/aerospike/aerospike-session-store-expressjs?label=%E2%98%85
+
+[![★][better-sqlite3-session-store-image] better-sqlite3-session-store][better-sqlite3-session-store-url] A session store based on [better-sqlite3](https://github.com/JoshuaWise/better-sqlite3).
+
+[better-sqlite3-session-store-url]: https://www.npmjs.com/package/better-sqlite3-session-store
+[better-sqlite3-session-store-image]: https://badgen.net/github/stars/timdaub/better-sqlite3-session-store?label=%E2%98%85
+
+[![★][cassandra-store-image] cassandra-store][cassandra-store-url] An Apache Cassandra-based session store.
+
+[cassandra-store-url]: https://www.npmjs.com/package/cassandra-store
+[cassandra-store-image]: https://badgen.net/github/stars/webcc/cassandra-store?label=%E2%98%85
+
+[![★][cluster-store-image] cluster-store][cluster-store-url] A wrapper for using in-process / embedded
+stores - such as SQLite (via knex), leveldb, files, or memory - with node cluster (desirable for Raspberry Pi 2
+and other multi-core embedded devices).
+
+[cluster-store-url]: https://www.npmjs.com/package/cluster-store
+[cluster-store-image]: https://badgen.net/github/stars/coolaj86/cluster-store?label=%E2%98%85
+
+[![★][connect-arango-image] connect-arango][connect-arango-url] An ArangoDB-based session store.
+
+[connect-arango-url]: https://www.npmjs.com/package/connect-arango
+[connect-arango-image]: https://badgen.net/github/stars/AlexanderArvidsson/connect-arango?label=%E2%98%85
+
+[![★][connect-azuretables-image] connect-azuretables][connect-azuretables-url] An [Azure Table Storage](https://azure.microsoft.com/en-gb/services/storage/tables/)-based session store.
+
+[connect-azuretables-url]: https://www.npmjs.com/package/connect-azuretables
+[connect-azuretables-image]: https://badgen.net/github/stars/mike-goodwin/connect-azuretables?label=%E2%98%85
+
+[![★][connect-cloudant-store-image] connect-cloudant-store][connect-cloudant-store-url] An [IBM Cloudant](https://cloudant.com/)-based session store.
+
+[connect-cloudant-store-url]: https://www.npmjs.com/package/connect-cloudant-store
+[connect-cloudant-store-image]: https://badgen.net/github/stars/adriantanasa/connect-cloudant-store?label=%E2%98%85
+
+[![★][connect-cosmosdb-image] connect-cosmosdb][connect-cosmosdb-url] An Azure [Cosmos DB](https://azure.microsoft.com/en-us/products/cosmos-db/)-based session store.
+
+[connect-cosmosdb-url]: https://www.npmjs.com/package/connect-cosmosdb
+[connect-cosmosdb-image]: https://badgen.net/github/stars/thekillingspree/connect-cosmosdb?label=%E2%98%85
+
+[![★][connect-couchbase-image] connect-couchbase][connect-couchbase-url] A [couchbase](http://www.couchbase.com/)-based session store.
+
+[connect-couchbase-url]: https://www.npmjs.com/package/connect-couchbase
+[connect-couchbase-image]: https://badgen.net/github/stars/christophermina/connect-couchbase?label=%E2%98%85
+
+[![★][connect-datacache-image] connect-datacache][connect-datacache-url] An [IBM Bluemix Data Cache](http://www.ibm.com/cloud-computing/bluemix/)-based session store.
+
+[connect-datacache-url]: https://www.npmjs.com/package/connect-datacache
+[connect-datacache-image]: https://badgen.net/github/stars/adriantanasa/connect-datacache?label=%E2%98%85
+
+[![★][@google-cloud/connect-datastore-image] @google-cloud/connect-datastore][@google-cloud/connect-datastore-url] A [Google Cloud Datastore](https://cloud.google.com/datastore/docs/concepts/overview)-based session store.
+
+[@google-cloud/connect-datastore-url]: https://www.npmjs.com/package/@google-cloud/connect-datastore
+[@google-cloud/connect-datastore-image]: https://badgen.net/github/stars/GoogleCloudPlatform/cloud-datastore-session-node?label=%E2%98%85
+
+[![★][connect-db2-image] connect-db2][connect-db2-url] An IBM DB2-based session store built using [ibm_db](https://www.npmjs.com/package/ibm_db) module.
+
+[connect-db2-url]: https://www.npmjs.com/package/connect-db2
+[connect-db2-image]: https://badgen.net/github/stars/wallali/connect-db2?label=%E2%98%85
+
+[![★][connect-dynamodb-image] connect-dynamodb][connect-dynamodb-url] A DynamoDB-based session store.
+
+[connect-dynamodb-url]: https://www.npmjs.com/package/connect-dynamodb
+[connect-dynamodb-image]: https://badgen.net/github/stars/ca98am79/connect-dynamodb?label=%E2%98%85
+
+[![★][@google-cloud/connect-firestore-image] @google-cloud/connect-firestore][@google-cloud/connect-firestore-url] A [Google Cloud Firestore](https://cloud.google.com/firestore/docs/overview)-based session store.
+
+[@google-cloud/connect-firestore-url]: https://www.npmjs.com/package/@google-cloud/connect-firestore
+[@google-cloud/connect-firestore-image]: https://badgen.net/github/stars/googleapis/nodejs-firestore-session?label=%E2%98%85
+
+[![★][connect-hazelcast-image] connect-hazelcast][connect-hazelcast-url] Hazelcast session store for Connect and Express.
+
+[connect-hazelcast-url]: https://www.npmjs.com/package/connect-hazelcast
+[connect-hazelcast-image]: https://badgen.net/github/stars/huseyinbabal/connect-hazelcast?label=%E2%98%85
+
+[![★][connect-loki-image] connect-loki][connect-loki-url] A Loki.js-based session store.
+
+[connect-loki-url]: https://www.npmjs.com/package/connect-loki
+[connect-loki-image]: https://badgen.net/github/stars/Requarks/connect-loki?label=%E2%98%85
+
+[![★][connect-lowdb-image] connect-lowdb][connect-lowdb-url] A lowdb-based session store.
+
+[connect-lowdb-url]: https://www.npmjs.com/package/connect-lowdb
+[connect-lowdb-image]: https://badgen.net/github/stars/travishorn/connect-lowdb?label=%E2%98%85
+
+[![★][connect-memcached-image] connect-memcached][connect-memcached-url] A memcached-based session store.
+
+[connect-memcached-url]: https://www.npmjs.com/package/connect-memcached
+[connect-memcached-image]: https://badgen.net/github/stars/balor/connect-memcached?label=%E2%98%85
+
+[![★][connect-memjs-image] connect-memjs][connect-memjs-url] A memcached-based session store using
+[memjs](https://www.npmjs.com/package/memjs) as the memcached client.
+
+[connect-memjs-url]: https://www.npmjs.com/package/connect-memjs
+[connect-memjs-image]: https://badgen.net/github/stars/liamdon/connect-memjs?label=%E2%98%85
+
+[![★][connect-ml-image] connect-ml][connect-ml-url] A MarkLogic Server-based session store.
+
+[connect-ml-url]: https://www.npmjs.com/package/connect-ml
+[connect-ml-image]: https://badgen.net/github/stars/bluetorch/connect-ml?label=%E2%98%85
+
+[![★][connect-monetdb-image] connect-monetdb][connect-monetdb-url] A MonetDB-based session store.
+
+[connect-monetdb-url]: https://www.npmjs.com/package/connect-monetdb
+[connect-monetdb-image]: https://badgen.net/github/stars/MonetDB/npm-connect-monetdb?label=%E2%98%85
+
+[![★][connect-mongo-image] connect-mongo][connect-mongo-url] A MongoDB-based session store.
+
+[connect-mongo-url]: https://www.npmjs.com/package/connect-mongo
+[connect-mongo-image]: https://badgen.net/github/stars/kcbanner/connect-mongo?label=%E2%98%85
+
+[![★][connect-mongodb-session-image] connect-mongodb-session][connect-mongodb-session-url] Lightweight MongoDB-based session store built and maintained by MongoDB.
+
+[connect-mongodb-session-url]: https://www.npmjs.com/package/connect-mongodb-session
+[connect-mongodb-session-image]: https://badgen.net/github/stars/mongodb-js/connect-mongodb-session?label=%E2%98%85
+
+[![★][connect-mssql-v2-image] connect-mssql-v2][connect-mssql-v2-url] A Microsoft SQL Server-based session store based on [connect-mssql](https://www.npmjs.com/package/connect-mssql).
+
+[connect-mssql-v2-url]: https://www.npmjs.com/package/connect-mssql-v2
+[connect-mssql-v2-image]: https://badgen.net/github/stars/jluboff/connect-mssql-v2?label=%E2%98%85
+
+[![★][connect-neo4j-image] connect-neo4j][connect-neo4j-url] A [Neo4j](https://neo4j.com)-based session store.
+
+[connect-neo4j-url]: https://www.npmjs.com/package/connect-neo4j
+[connect-neo4j-image]: https://badgen.net/github/stars/MaxAndersson/connect-neo4j?label=%E2%98%85
+
+[![★][connect-ottoman-image] connect-ottoman][connect-ottoman-url] A [couchbase ottoman](http://www.couchbase.com/)-based session store.
+
+[connect-ottoman-url]: https://www.npmjs.com/package/connect-ottoman
+[connect-ottoman-image]: https://badgen.net/github/stars/noiissyboy/connect-ottoman?label=%E2%98%85
+
+[![★][connect-pg-simple-image] connect-pg-simple][connect-pg-simple-url] A PostgreSQL-based session store.
+
+[connect-pg-simple-url]: https://www.npmjs.com/package/connect-pg-simple
+[connect-pg-simple-image]: https://badgen.net/github/stars/voxpelli/node-connect-pg-simple?label=%E2%98%85
+
+[![★][connect-redis-image] connect-redis][connect-redis-url] A Redis-based session store.
+
+[connect-redis-url]: https://www.npmjs.com/package/connect-redis
+[connect-redis-image]: https://badgen.net/github/stars/tj/connect-redis?label=%E2%98%85
+
+[![★][connect-session-firebase-image] connect-session-firebase][connect-session-firebase-url] A session store based on the [Firebase Realtime Database](https://firebase.google.com/docs/database/)
+
+[connect-session-firebase-url]: https://www.npmjs.com/package/connect-session-firebase
+[connect-session-firebase-image]: https://badgen.net/github/stars/benweier/connect-session-firebase?label=%E2%98%85
+
+[![★][connect-session-knex-image] connect-session-knex][connect-session-knex-url] A session store using
+[Knex.js](http://knexjs.org/), which is a SQL query builder for PostgreSQL, MySQL, MariaDB, SQLite3, and Oracle.
+
+[connect-session-knex-url]: https://www.npmjs.com/package/connect-session-knex
+[connect-session-knex-image]: https://badgen.net/github/stars/llambda/connect-session-knex?label=%E2%98%85
+
+[![★][connect-session-sequelize-image] connect-session-sequelize][connect-session-sequelize-url] A session store using
+[Sequelize.js](http://sequelizejs.com/), which is a Node.js / io.js ORM for PostgreSQL, MySQL, SQLite and MSSQL.
+
+[connect-session-sequelize-url]: https://www.npmjs.com/package/connect-session-sequelize
+[connect-session-sequelize-image]: https://badgen.net/github/stars/mweibel/connect-session-sequelize?label=%E2%98%85
+
+[![★][connect-sqlite3-image] connect-sqlite3][connect-sqlite3-url] A [SQLite3](https://github.com/mapbox/node-sqlite3) session store modeled after the TJ's `connect-redis` store.
+
+[connect-sqlite3-url]: https://www.npmjs.com/package/connect-sqlite3
+[connect-sqlite3-image]: https://badgen.net/github/stars/rawberg/connect-sqlite3?label=%E2%98%85
+
+[![★][connect-typeorm-image] connect-typeorm][connect-typeorm-url] A [TypeORM](https://github.com/typeorm/typeorm)-based session store.
+
+[connect-typeorm-url]: https://www.npmjs.com/package/connect-typeorm
+[connect-typeorm-image]: https://badgen.net/github/stars/makepost/connect-typeorm?label=%E2%98%85
+
+[![★][couchdb-expression-image] couchdb-expression][couchdb-expression-url] A [CouchDB](https://couchdb.apache.org/)-based session store.
+
+[couchdb-expression-url]: https://www.npmjs.com/package/couchdb-expression
+[couchdb-expression-image]: https://badgen.net/github/stars/tkshnwesper/couchdb-expression?label=%E2%98%85
+
+[![★][dynamodb-store-image] dynamodb-store][dynamodb-store-url] A DynamoDB-based session store.
+
+[dynamodb-store-url]: https://www.npmjs.com/package/dynamodb-store
+[dynamodb-store-image]: https://badgen.net/github/stars/rafaelrpinto/dynamodb-store?label=%E2%98%85
+
+[![★][dynamodb-store-v3-image] dynamodb-store-v3][dynamodb-store-v3-url] Implementation of a session store using DynamoDB backed by the [AWS SDK for JavaScript v3](https://github.com/aws/aws-sdk-js-v3).
+
+[dynamodb-store-v3-url]: https://www.npmjs.com/package/dynamodb-store-v3
+[dynamodb-store-v3-image]: https://badgen.net/github/stars/FryDay/dynamodb-store-v3?label=%E2%98%85
+
+[![★][express-etcd-image] express-etcd][express-etcd-url] An [etcd](https://github.com/stianeikeland/node-etcd) based session store.
+
+[express-etcd-url]: https://www.npmjs.com/package/express-etcd
+[express-etcd-image]: https://badgen.net/github/stars/gildean/express-etcd?label=%E2%98%85
+
+[![★][express-mysql-session-image] express-mysql-session][express-mysql-session-url] A session store using native
+[MySQL](https://www.mysql.com/) via the [node-mysql](https://github.com/felixge/node-mysql) module.
+
+[express-mysql-session-url]: https://www.npmjs.com/package/express-mysql-session
+[express-mysql-session-image]: https://badgen.net/github/stars/chill117/express-mysql-session?label=%E2%98%85
+
+[![★][express-nedb-session-image] express-nedb-session][express-nedb-session-url] A NeDB-based session store.
+
+[express-nedb-session-url]: https://www.npmjs.com/package/express-nedb-session
+[express-nedb-session-image]: https://badgen.net/github/stars/louischatriot/express-nedb-session?label=%E2%98%85
+
+[![★][express-oracle-session-image] express-oracle-session][express-oracle-session-url] A session store using native
+[oracle](https://www.oracle.com/) via the [node-oracledb](https://www.npmjs.com/package/oracledb) module.
+
+[express-oracle-session-url]: https://www.npmjs.com/package/express-oracle-session
+[express-oracle-session-image]: https://badgen.net/github/stars/slumber86/express-oracle-session?label=%E2%98%85
+
+[![★][express-session-cache-manager-image] express-session-cache-manager][express-session-cache-manager-url]
+A store that implements [cache-manager](https://www.npmjs.com/package/cache-manager), which supports
+a [variety of storage types](https://www.npmjs.com/package/cache-manager#store-engines).
+
+[express-session-cache-manager-url]: https://www.npmjs.com/package/express-session-cache-manager
+[express-session-cache-manager-image]: https://badgen.net/github/stars/theogravity/express-session-cache-manager?label=%E2%98%85
+
+[![★][express-session-etcd3-image] express-session-etcd3][express-session-etcd3-url] An [etcd3](https://github.com/mixer/etcd3) based session store.
+
+[express-session-etcd3-url]: https://www.npmjs.com/package/express-session-etcd3
+[express-session-etcd3-image]: https://badgen.net/github/stars/willgm/express-session-etcd3?label=%E2%98%85
+
+[![★][express-session-level-image] express-session-level][express-session-level-url] A [LevelDB](https://github.com/Level/levelup) based session store.
+
+[express-session-level-url]: https://www.npmjs.com/package/express-session-level
+[express-session-level-image]: https://badgen.net/github/stars/tgohn/express-session-level?label=%E2%98%85
+
+[![★][express-session-rsdb-image] express-session-rsdb][express-session-rsdb-url] Session store based on Rocket-Store: A very simple, super fast and yet powerful, flat file database.
+
+[express-session-rsdb-url]: https://www.npmjs.com/package/express-session-rsdb
+[express-session-rsdb-image]: https://badgen.net/github/stars/paragi/express-session-rsdb?label=%E2%98%85
+
+[![★][express-sessions-image] express-sessions][express-sessions-url] A session store supporting both MongoDB and Redis.
+
+[express-sessions-url]: https://www.npmjs.com/package/express-sessions
+[express-sessions-image]: https://badgen.net/github/stars/konteck/express-sessions?label=%E2%98%85
+
+[![★][firestore-store-image] firestore-store][firestore-store-url] A [Firestore](https://github.com/hendrysadrak/firestore-store)-based session store.
+
+[firestore-store-url]: https://www.npmjs.com/package/firestore-store
+[firestore-store-image]: https://badgen.net/github/stars/hendrysadrak/firestore-store?label=%E2%98%85
+
+[![★][fortune-session-image] fortune-session][fortune-session-url] A [Fortune.js](https://github.com/fortunejs/fortune)
+based session store. Supports all backends supported by Fortune (MongoDB, Redis, Postgres, NeDB).
+
+[fortune-session-url]: https://www.npmjs.com/package/fortune-session
+[fortune-session-image]: https://badgen.net/github/stars/aliceklipper/fortune-session?label=%E2%98%85
+
+[![★][hazelcast-store-image] hazelcast-store][hazelcast-store-url] A Hazelcast-based session store built on the [Hazelcast Node Client](https://www.npmjs.com/package/hazelcast-client).
+
+[hazelcast-store-url]: https://www.npmjs.com/package/hazelcast-store
+[hazelcast-store-image]: https://badgen.net/github/stars/jackspaniel/hazelcast-store?label=%E2%98%85
+
+[![★][level-session-store-image] level-session-store][level-session-store-url] A LevelDB-based session store.
+
+[level-session-store-url]: https://www.npmjs.com/package/level-session-store
+[level-session-store-image]: https://badgen.net/github/stars/toddself/level-session-store?label=%E2%98%85
+
+[![★][lowdb-session-store-image] lowdb-session-store][lowdb-session-store-url] A [lowdb](https://www.npmjs.com/package/lowdb)-based session store.
+
+[lowdb-session-store-url]: https://www.npmjs.com/package/lowdb-session-store
+[lowdb-session-store-image]: https://badgen.net/github/stars/fhellwig/lowdb-session-store?label=%E2%98%85
+
+[![★][medea-session-store-image] medea-session-store][medea-session-store-url] A Medea-based session store.
+
+[medea-session-store-url]: https://www.npmjs.com/package/medea-session-store
+[medea-session-store-image]: https://badgen.net/github/stars/BenjaminVadant/medea-session-store?label=%E2%98%85
+
+[![★][memorystore-image] memorystore][memorystore-url] A memory session store made for production.
+
+[memorystore-url]: https://www.npmjs.com/package/memorystore
+[memorystore-image]: https://badgen.net/github/stars/roccomuso/memorystore?label=%E2%98%85
+
+[![★][mssql-session-store-image] mssql-session-store][mssql-session-store-url] A SQL Server-based session store.
+
+[mssql-session-store-url]: https://www.npmjs.com/package/mssql-session-store
+[mssql-session-store-image]: https://badgen.net/github/stars/jwathen/mssql-session-store?label=%E2%98%85
+
+[![★][nedb-session-store-image] nedb-session-store][nedb-session-store-url] An alternate NeDB-based (either in-memory or file-persisted) session store.
+
+[nedb-session-store-url]: https://www.npmjs.com/package/nedb-session-store
+[nedb-session-store-image]: https://badgen.net/github/stars/JamesMGreene/nedb-session-store?label=%E2%98%85
+
+[![★][@quixo3/prisma-session-store-image] @quixo3/prisma-session-store][@quixo3/prisma-session-store-url] A session store for the [Prisma Framework](https://www.prisma.io).
+
+[@quixo3/prisma-session-store-url]: https://www.npmjs.com/package/@quixo3/prisma-session-store
+[@quixo3/prisma-session-store-image]: https://badgen.net/github/stars/kleydon/prisma-session-store?label=%E2%98%85
+
+[![★][restsession-image] restsession][restsession-url] Store sessions utilizing a RESTful API
+
+[restsession-url]: https://www.npmjs.com/package/restsession
+[restsession-image]: https://badgen.net/github/stars/jankal/restsession?label=%E2%98%85
+
+[![★][sequelstore-connect-image] sequelstore-connect][sequelstore-connect-url] A session store using [Sequelize.js](http://sequelizejs.com/).
+
+[sequelstore-connect-url]: https://www.npmjs.com/package/sequelstore-connect
+[sequelstore-connect-image]: https://badgen.net/github/stars/MattMcFarland/sequelstore-connect?label=%E2%98%85
+
+[![★][session-file-store-image] session-file-store][session-file-store-url] A file system-based session store.
+
+[session-file-store-url]: https://www.npmjs.com/package/session-file-store
+[session-file-store-image]: https://badgen.net/github/stars/valery-barysok/session-file-store?label=%E2%98%85
+
+[![★][session-pouchdb-store-image] session-pouchdb-store][session-pouchdb-store-url] Session store for PouchDB / CouchDB. Accepts embedded, custom, or remote PouchDB instance and realtime synchronization.
+
+[session-pouchdb-store-url]: https://www.npmjs.com/package/session-pouchdb-store
+[session-pouchdb-store-image]: https://badgen.net/github/stars/solzimer/session-pouchdb-store?label=%E2%98%85
+
+[![★][@cyclic.sh/session-store-image] @cyclic.sh/session-store][@cyclic.sh/session-store-url] A DynamoDB-based session store for [Cyclic.sh](https://www.cyclic.sh/) apps.
+
+[@cyclic.sh/session-store-url]: https://www.npmjs.com/package/@cyclic.sh/session-store
+[@cyclic.sh/session-store-image]: https://badgen.net/github/stars/cyclic-software/session-store?label=%E2%98%85
+
+[![★][@databunker/session-store-image] @databunker/session-store][@databunker/session-store-url] A [Databunker](https://databunker.org/)-based encrypted session store.
+
+[@databunker/session-store-url]: https://www.npmjs.com/package/@databunker/session-store
+[@databunker/session-store-image]: https://badgen.net/github/stars/securitybunker/databunker-session-store?label=%E2%98%85
+
+[![★][sessionstore-image] sessionstore][sessionstore-url] A session store that works with various databases.
+
+[sessionstore-url]: https://www.npmjs.com/package/sessionstore
+[sessionstore-image]: https://badgen.net/github/stars/adrai/sessionstore?label=%E2%98%85
+
+[![★][tch-nedb-session-image] tch-nedb-session][tch-nedb-session-url] A file system session store based on NeDB.
+
+[tch-nedb-session-url]: https://www.npmjs.com/package/tch-nedb-session
+[tch-nedb-session-image]: https://badgen.net/github/stars/tomaschyly/NeDBSession?label=%E2%98%85
+
+## Examples
+
+### View counter
+
+A simple example using `express-session` to store page views for a user.
+
+```js
+var express = require('express');
+var parseurl = require('parseurl');
+var session = require('express-session');
+
+var app = express();
+
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ })
+);
+
+app.use(function (req, res, next) {
+ if (!req.session.views) {
+ req.session.views = {};
+ }
+
+ // get the url pathname
+ var pathname = parseurl(req).pathname;
+
+ // count the views
+ req.session.views[pathname] = (req.session.views[pathname] || 0) + 1;
+
+ next();
+});
+
+app.get('/foo', function (req, res, next) {
+ res.send('you viewed this page ' + req.session.views['/foo'] + ' times');
+});
+
+app.get('/bar', function (req, res, next) {
+ res.send('you viewed this page ' + req.session.views['/bar'] + ' times');
+});
+
+app.listen(3000);
+```
+
+### User login
+
+A simple example using `express-session` to keep a user log in session.
+
+```js
+var escapeHtml = require('escape-html');
+var express = require('express');
+var session = require('express-session');
+
+var app = express();
+
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ })
+);
+
+// middleware to test if authenticated
+function isAuthenticated(req, res, next) {
+ if (req.session.user) next();
+ else next('route');
+}
+
+app.get('/', isAuthenticated, function (req, res) {
+ // this is only called when there is an authentication user due to isAuthenticated
+ res.send('hello, ' + escapeHtml(req.session.user) + '!' + ' Logout ');
+});
+
+app.get('/', function (req, res) {
+ res.send(
+ ''
+ );
+});
+
+app.post('/login', express.urlencoded({ extended: false }), function (req, res) {
+ // login logic to validate req.body.user and req.body.pass
+ // would be implemented here. for this example any combo works
+
+ // regenerate the session, which is good practice to help
+ // guard against forms of session fixation
+ req.session.regenerate(function (err) {
+ if (err) next(err);
+
+ // store user information in session, typically a user id
+ req.session.user = req.body.user;
+
+ // save the session before redirection to ensure page
+ // load does not happen before session is saved
+ req.session.save(function (err) {
+ if (err) return next(err);
+ res.redirect('/');
+ });
+ });
+});
+
+app.get('/logout', function (req, res, next) {
+ // logout logic
+
+ // clear the user from the session object and save.
+ // this will ensure that re-using the old session id
+ // does not have a logged in user
+ req.session.user = null;
+ req.session.save(function (err) {
+ if (err) next(err);
+
+ // regenerate the session, which is good practice to help
+ // guard against forms of session fixation
+ req.session.regenerate(function (err) {
+ if (err) next(err);
+ res.redirect('/');
+ });
+ });
+});
+
+app.listen(3000);
+```
+
+## Debugging
+
+This module uses the [debug](https://www.npmjs.com/package/debug) module
+internally to log information about session operations.
+
+To see all the internal logs, set the `DEBUG` environment variable to
+`express-session` when launching your app (`npm start`, in this example):
+
+```sh
+$ DEBUG=express-session npm start
+```
+
+On Windows, use the corresponding command;
+
+```sh
+> set DEBUG=express-session & npm start
+```
+
+## License
+
+[MIT](LICENSE)
+
+[rfc-6265bis-03-4.1.2.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7
+[rfc-cutler-httpbis-partitioned-cookies]: https://tools.ietf.org/html/draft-cutler-httpbis-partitioned-cookies/
+[rfc-west-cookie-priority-00-4.1]: https://tools.ietf.org/html/draft-west-cookie-priority-00#section-4.1
+[ci-image]: https://badgen.net/github/checks/expressjs/session/master?label=ci
+[ci-url]: https://github.com/expressjs/session/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/session/master
+[coveralls-url]: https://coveralls.io/r/expressjs/session?branch=master
+[node-url]: https://nodejs.org/en/download
+[npm-downloads-image]: https://badgen.net/npm/dm/express-session
+[npm-url]: https://npmjs.org/package/express-session
+[npm-version-image]: https://badgen.net/npm/v/express-session
diff --git a/astro/src/content/resources/es/middleware/timeout.md b/astro/src/content/resources/es/middleware/timeout.md
new file mode 100644
index 0000000000..f6057aedfd
--- /dev/null
+++ b/astro/src/content/resources/es/middleware/timeout.md
@@ -0,0 +1,176 @@
+---
+title: Express timeout middleware
+module: timeout
+---
+
+# connect-timeout
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][travis-image]][travis-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Times out a request in the Connect/Express application framework.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install connect-timeout
+```
+
+## API
+
+**NOTE** This module is not recommend as a "top-level" middleware (i.e.
+`app.use(timeout('5s'))`) unless you take precautions to halt your own
+middleware processing. See [as top-level middleware](#as-top-level-middleware)
+for how to use as a top-level middleware.
+
+While the library will emit a 'timeout' event when requests exceed the given
+timeout, node will continue processing the slow request until it terminates.
+Slow requests will continue to use CPU and memory, even if you are returning
+a HTTP response in the timeout callback. For better control over CPU/memory,
+you may need to find the events that are taking a long time (3rd party HTTP
+requests, disk I/O, database calls) and find a way to cancel them, and/or
+close the attached sockets.
+
+### timeout(time, [options])
+
+Returns middleware that times out in `time` milliseconds. `time` can also
+be a string accepted by the [ms](https://www.npmjs.org/package/ms#readme)
+module. On timeout, `req` will emit `"timeout"`.
+
+#### Options
+
+The `timeout` function takes an optional `options` object that may contain
+any of the following keys:
+
+##### respond
+
+Controls if this module will "respond" in the form of forwarding an error.
+If `true`, the timeout error is passed to `next()` so that you may customize
+the response behavior. This error has a `.timeout` property as well as
+`.status == 503`. This defaults to `true`.
+
+### req.clearTimeout()
+
+Clears the timeout on the request. The timeout is completely removed and
+will not fire for this request in the future.
+
+### req.timedout
+
+`true` if timeout fired; `false` otherwise.
+
+## Examples
+
+### as top-level middleware
+
+Because of the way middleware processing works, once this module
+passes the request to the next middleware (which it has to do in order
+for you to do work), it can no longer stop the flow, so you must take
+care to check if the request has timedout before you continue to act
+on the request.
+
+```javascript
+var bodyParser = require('body-parser');
+var cookieParser = require('cookie-parser');
+var express = require('express');
+var timeout = require('connect-timeout');
+
+// example of using this top-level; note the use of haltOnTimedout
+// after every middleware; it will stop the request flow on a timeout
+var app = express();
+app.use(timeout('5s'));
+app.use(bodyParser());
+app.use(haltOnTimedout);
+app.use(cookieParser());
+app.use(haltOnTimedout);
+
+// Add your routes here, etc.
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+app.listen(3000);
+```
+
+### express 3.x
+
+```javascript
+var express = require('express');
+var bodyParser = require('body-parser');
+var timeout = require('connect-timeout');
+
+var app = express();
+app.post('/save', timeout('5s'), bodyParser.json(), haltOnTimedout, function (req, res, next) {
+ savePost(req.body, function (err, id) {
+ if (err) return next(err);
+ if (req.timedout) return;
+ res.send('saved as id ' + id);
+ });
+});
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+function savePost(post, cb) {
+ setTimeout(
+ function () {
+ cb(null, (Math.random() * 40000) >>> 0);
+ },
+ (Math.random() * 7000) >>> 0
+ );
+}
+
+app.listen(3000);
+```
+
+### connect
+
+```javascript
+var bodyParser = require('body-parser');
+var connect = require('connect');
+var timeout = require('connect-timeout');
+
+var app = connect();
+app.use('/save', timeout('5s'), bodyParser.json(), haltOnTimedout, function (req, res, next) {
+ savePost(req.body, function (err, id) {
+ if (err) return next(err);
+ if (req.timedout) return;
+ res.send('saved as id ' + id);
+ });
+});
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+function savePost(post, cb) {
+ setTimeout(
+ function () {
+ cb(null, (Math.random() * 40000) >>> 0);
+ },
+ (Math.random() * 7000) >>> 0
+ );
+}
+
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/connect-timeout.svg
+[npm-url]: https://npmjs.org/package/connect-timeout
+[travis-image]: https://img.shields.io/travis/expressjs/timeout/master.svg
+[travis-url]: https://travis-ci.org/expressjs/timeout
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/timeout/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/timeout?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/connect-timeout.svg
+[downloads-url]: https://npmjs.org/package/connect-timeout
diff --git a/astro/src/content/resources/es/middleware/vhost.md b/astro/src/content/resources/es/middleware/vhost.md
new file mode 100644
index 0000000000..72f49d7f93
--- /dev/null
+++ b/astro/src/content/resources/es/middleware/vhost.md
@@ -0,0 +1,174 @@
+---
+title: Express vhost middleware
+module: vhost
+---
+
+# vhost
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Install
+
+```sh
+$ npm install vhost
+```
+
+## API
+
+```js
+var vhost = require('vhost');
+```
+
+### vhost(hostname, handle)
+
+Create a new middleware function to hand off request to `handle` when the incoming
+host for the request matches `hostname`. The function is called as
+`handle(req, res, next)`, like a standard middleware.
+
+`hostname` can be a string or a RegExp object. When `hostname` is a string it can
+contain `*` to match 1 or more characters in that section of the hostname. When
+`hostname` is a RegExp, it will be forced to case-insensitive (since hostnames are)
+and will be forced to match based on the start and end of the hostname.
+
+When host is matched and the request is sent down to a vhost handler, the `req.vhost`
+property will be populated with an object. This object will have numeric properties
+corresponding to each wildcard (or capture group if RegExp object provided) and the
+`hostname` that was matched.
+
+```js
+var connect = require('connect');
+var vhost = require('vhost');
+var app = connect();
+
+app.use(
+ vhost('*.*.example.com', function handle(req, res, next) {
+ // for match of "foo.bar.example.com:8080" against "*.*.example.com":
+ console.dir(req.vhost.host); // => 'foo.bar.example.com:8080'
+ console.dir(req.vhost.hostname); // => 'foo.bar.example.com'
+ console.dir(req.vhost.length); // => 2
+ console.dir(req.vhost[0]); // => 'foo'
+ console.dir(req.vhost[1]); // => 'bar'
+ })
+);
+```
+
+## Examples
+
+### using with connect for static serving
+
+```js
+var connect = require('connect');
+var serveStatic = require('serve-static');
+var vhost = require('vhost');
+
+var mailapp = connect();
+
+// add middlewares to mailapp for mail.example.com
+
+// create app to serve static files on subdomain
+var staticapp = connect();
+staticapp.use(serveStatic('public'));
+
+// create main app
+var app = connect();
+
+// add vhost routing to main app for mail
+app.use(vhost('mail.example.com', mailapp));
+
+// route static assets for "assets-*" subdomain to get
+// around max host connections limit on browsers
+app.use(vhost('assets-*.example.com', staticapp));
+
+// add middlewares and main usage to app
+
+app.listen(3000);
+```
+
+### using with connect for user subdomains
+
+```js
+var connect = require('connect');
+var serveStatic = require('serve-static');
+var vhost = require('vhost');
+
+var mainapp = connect();
+
+// add middlewares to mainapp for the main web site
+
+// create app that will server user content from public/{username}/
+var userapp = connect();
+
+userapp.use(function (req, res, next) {
+ var username = req.vhost[0]; // username is the "*"
+
+ // pretend request was for /{username}/* for file serving
+ req.originalUrl = req.url;
+ req.url = '/' + username + req.url;
+
+ next();
+});
+userapp.use(serveStatic('public'));
+
+// create main app
+var app = connect();
+
+// add vhost routing for main app
+app.use(vhost('userpages.local', mainapp));
+app.use(vhost('www.userpages.local', mainapp));
+
+// listen on all subdomains for user pages
+app.use(vhost('*.userpages.local', userapp));
+
+app.listen(3000);
+```
+
+### using with any generic request handler
+
+```js
+var connect = require('connect');
+var http = require('http');
+var vhost = require('vhost');
+
+// create main app
+var app = connect();
+
+app.use(
+ vhost('mail.example.com', function (req, res) {
+ // handle req + res belonging to mail.example.com
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello from mail!');
+ })
+);
+
+// an external api server in any framework
+var httpServer = http.createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello from the api!');
+});
+
+app.use(
+ vhost('api.example.com', function (req, res) {
+ // handle req + res belonging to api.example.com
+ // pass the request to a standard Node.js HTTP server
+ httpServer.emit('request', req, res);
+ })
+);
+
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/vhost.svg
+[npm-url]: https://npmjs.org/package/vhost
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/vhost/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/vhost
+[downloads-image]: https://img.shields.io/npm/dm/vhost.svg
+[downloads-url]: https://npmjs.org/package/vhost
+[github-actions-ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/vhost/ci.yml?branch=master&label=ci
+[github-actions-ci-url]: https://github.com/expressjs/vhost/actions/workflows/ci.yml
diff --git a/astro/src/content/resources/es/utils.md b/astro/src/content/resources/es/utils.md
new file mode 100644
index 0000000000..546b2f09b4
--- /dev/null
+++ b/astro/src/content/resources/es/utils.md
@@ -0,0 +1,22 @@
+---
+title: Express utilities
+description: Discover utility modules related to Express.js and Node.js, including tools for cookies, CSRF protection, URL parsing, routing, and more to enhance your applications.
+---
+
+## Express utility functions
+
+The [pillarjs](https://github.com/pillarjs) GitHub organization contains a number of modules
+for utility functions that may be generally useful.
+
+| Utility modules | Description |
+| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| [cookies](https://www.npmjs.com/package/cookies) | Get and set HTTP(S) cookies that can be signed to prevent tampering, using Keygrip. Can be used with the Node.js HTTP library or as Express middleware. |
+| [csrf](https://www.npmjs.com/package/csrf) | Contains the logic behind CSRF token creation and verification. Use this module to create custom CSRF middleware. |
+| [finalhandler](https://www.npmjs.com/package/finalhandler) | Function to invoke as the final step to respond to HTTP request. |
+| [parseurl](https://www.npmjs.com/package/parseurl) | Parse a URL with caching. |
+| [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) | Turn an Express-style path string such as ``/user/:name` into a regular expression. |
+| [resolve-path](https://www.npmjs.com/package/resolve-path) | Resolves a relative path against a root path with validation. |
+| [router](https://www.npmjs.com/package/router) | Simple middleware-style router. |
+| [send](https://www.npmjs.com/package/send) | Library for streaming files as a HTTP response, with support for partial responses (ranges), conditional-GET negotiation, and granular events. |
+
+For additional low-level HTTP-related modules, see [jshttp](https://github.com/jshttp).
diff --git a/astro/src/content/resources/fr/community.md b/astro/src/content/resources/fr/community.md
new file mode 100755
index 0000000000..e40d97e421
--- /dev/null
+++ b/astro/src/content/resources/fr/community.md
@@ -0,0 +1,70 @@
+---
+title: Express community
+description: Connect with the Express.js community, learn about the technical committee, find resources, explore community-contributed modules, and get involved in discussions.
+---
+
+# Community
+
+## Technical committee
+
+The Express technical committee meets online every two weeks (as needed) to discuss development and maintenance of Express,
+and other issues relevant to the Express project. Each meeting is typically announced in an
+[expressjs/discussions issue](https://github.com/expressjs/discussions/issues) with a link to join or view the meeting, which is
+open to all observers.
+
+The meetings are recorded; for a list of the recordings, see the [Express.js YouTube channel](https://www.youtube.com/channel/UCYjxjAeH6TRik9Iwy5nXw7g).
+
+Members of the Express technical committee are:
+
+**Active:**
+
+- [@blakeembrey](https://github.com/blakeembrey) - Blake Embrey
+- [@crandmck](https://github.com/crandmck) - Rand McKinney
+- [@LinusU](https://github.com/LinusU) - Linus Unnebäck
+- [@ulisesgascon](https://github.com/ulisesGascon) - Ulises Gascón
+- [@sheplu](https://github.com/sheplu) - Jean Burellier
+- [@wesleytodd](https://github.com/wesleytodd) - Wes Todd
+- [@jonchurch](https://github.com/jonchurch) - Jon Church
+- [@ctcpip](https://github.com/ctcpip/) - Chris de Almeida
+
+**Inactive:**
+
+- [@dougwilson](https://github.com/dougwilson) - Douglas Wilson
+- [@hacksparrow](https://github.com/hacksparrow) - Hage Yaapa
+- [@jonathanong](https://github.com/jonathanong) - jongleberry
+- [@niftylettuce](https://github.com/niftylettuce) - niftylettuce
+- [@troygoode](https://github.com/troygoode) - Troy Goode
+
+## Express is made of many modules
+
+Our vibrant community has created a large variety of extensions,
+[middleware modules](/en/resources/middleware) and higher-level frameworks.
+
+Additionally, the Express community maintains modules in these two GitHub orgs:
+
+- [jshttp](https://github.com/jshttp) modules providing useful utility functions; see [Utility modules](/en/resources/utils).
+- [pillarjs](https://github.com/pillarjs): low-level modules that Express uses internally.
+
+To keep up with what is going on in the whole community, check out the [ExpressJS StatusBoard](https://expressjs.github.io/statusboard/).
+
+## Issues
+
+If you've come across what you think is a bug, or just want to make
+a feature request open a ticket in the [issue queue](https://github.com/expressjs/express/issues).
+
+## Examples
+
+View dozens of Express application [examples](https://github.com/expressjs/express/tree/master/examples)
+in the repository covering everything from API design and authentication to template engine integration.
+
+## Github Discussions
+
+The [GitHub Discussions](https://github.com/expressjs/discussions) section is an excellent space to engage in conversations about the development and maintenance of Express, as well as to share ideas and discuss topics related to its usage.
+
+# Branding of Express.js
+
+## Express.js Logo
+
+Express is a project of the OpenJS Foundation. Please review the [trademark policy](https://trademark-policy.openjsf.org/) for information about permissible use of Express.js logos and marks.
+
+
diff --git a/astro/src/content/resources/fr/contributing.md b/astro/src/content/resources/fr/contributing.md
new file mode 100644
index 0000000000..82c6b8fed7
--- /dev/null
+++ b/astro/src/content/resources/fr/contributing.md
@@ -0,0 +1,482 @@
+---
+title: Contributing to Express
+description: Find out how to contribute to Express.js, including guidelines for reporting issues, submitting pull requests, becoming a collaborator, and understanding security policies.
+---
+
+# Contributing to Express
+
+### Looking to contribute to Expressjs.com? Click [here](#expressjs-website-contributing).
+
+Express and the other projects in the [expressjs organization on GitHub](https://github.com/expressjs) are projects of the [OpenJs Foundation](https://openjsf.org/).
+These projects are governed under the general policies and guidelines of the Node.js Foundation along with the additional guidelines below.
+
+- [Technical committee](#technical-committee)
+- [Community contributing guide](#community-contributing-guide)
+- [Collaborator's guide](#collaborators-guide)
+- [Security policies and procedures](#security-policies-and-procedures)
+
+## Technical committee
+
+The Express technical committee consists of active project members, and guides development and maintenance of the Express project. For more information, see [Express Community - Technical committee](/en/resources/community/#technical-committee).
+
+## Community contributing guide
+
+
+
+The goal of this document is to create a contribution process that:
+
+- Encourages new contributions.
+- Encourages contributors to remain involved.
+- Avoids unnecessary processes and bureaucracy whenever possible.
+- Creates a transparent decision making process that makes it clear how
+ contributors can be involved in decision making.
+
+### Vocabulary
+
+- A **Contributor** is any individual creating or commenting on an issue or pull request.
+- A **Committer** is a subset of contributors who have been given write access to the repository.
+- A **Project Captain** is the lead maintainer of a repository.
+- A **TC (Technical Committee)** is a group of committers representing the required technical
+ expertise to resolve rare disputes.
+- A **Triager** is a subset of contributors who have been given triage access to the repository.
+
+### Logging Issues
+
+Log an issue for any question or problem you might have. When in doubt, log an issue, and
+any additional policies about what to include will be provided in the responses. The only
+exception is security disclosures which should be sent privately.
+
+Committers may direct you to another repository, ask for additional clarifications, and
+add appropriate metadata before the issue is addressed.
+
+Please be courteous and respectful. Every participant is expected to follow the
+project's Code of Conduct.
+
+### Contributions
+
+Any change to resources in this repository must be through pull requests. This applies to all changes
+to documentation, code, binary files, etc. Even long term committers and TC members must use
+pull requests.
+
+No pull request can be merged without being reviewed.
+
+For non-trivial contributions, pull requests should sit for at least 36 hours to ensure that
+contributors in other timezones have time to review. Consideration should also be given to
+weekends and other holiday periods to ensure active committers all have reasonable time to
+become involved in the discussion and review process if they wish.
+
+The default for each contribution is that it is accepted once no committer has an objection.
+During a review, committers may also request that a specific contributor who is most versed in a
+particular area gives a "LGTM" before the PR can be merged. There is no additional "sign off"
+process for contributions to land. Once all issues brought by committers are addressed it can
+be landed by any committer.
+
+In the case of an objection being raised in a pull request by another committer, all involved
+committers should seek to arrive at a consensus by way of addressing concerns being expressed
+by discussion, compromise on the proposed change, or withdrawal of the proposed change.
+
+If a contribution is controversial and committers cannot agree about how to get it to land
+or if it should land then it should be escalated to the TC. TC members should regularly
+discuss pending contributions in order to find a resolution. It is expected that only a
+small minority of issues be brought to the TC for resolution and that discussion and
+compromise among committers be the default resolution mechanism.
+
+### Becoming a Triager
+
+Anyone can become a triager! Read more about the process of being a triager in
+[the triage process document](https://github.com/expressjs/discussions/blob/master/Triager-Guide.md).
+
+Currently, any existing [organization member](https://github.com/orgs/expressjs/people) can nominate
+a new triager. If you are interested in becoming a triager, our best advice is to actively participate
+in the community by helping triaging issues and pull requests. As well we recommend
+to engage in other community activities like attending the TC meetings, and participating in the Slack
+discussions. If you feel ready and have been helping triage some issues, reach out to an active member of the organization to ask if they'd
+be willing to support you. If they agree, they can create a pull request to formalize your nomination. In the case of an objection to the nomination, the triage team is responsible for working with the individuals involved and finding a resolution.
+
+You can also reach out to any of the [organization members](https://github.com/orgs/expressjs/people)
+if you have questions or need guidance.
+
+### Becoming a Committer
+
+All contributors who have landed significant and valuable contributions should be onboarded in a timely manner,
+and added as a committer, and be given write access to the repository.
+
+Committers are expected to follow this policy and continue to send pull requests, go through
+proper review, and have other committers merge their pull requests.
+
+### TC Process
+
+The TC uses a "consensus seeking" process for issues that are escalated to the TC.
+The group tries to find a resolution that has no open objections among TC members.
+If a consensus cannot be reached that has no objections then a majority wins vote
+is called. It is also expected that the majority of decisions made by the TC are via
+a consensus seeking process and that voting is only used as a last-resort.
+
+Resolution may involve returning the issue to project captains with suggestions on
+how to move forward towards a consensus. It is not expected that a meeting of the TC
+will resolve all issues on its agenda during that meeting and may prefer to continue
+the discussion happening among the project captains.
+
+Members can be added to the TC at any time. Any TC member can nominate another committer
+to the TC and the TC uses its standard consensus seeking process to evaluate whether or
+not to add this new member. The TC will consist of a minimum of 3 active members and a
+maximum of 10. If the TC should drop below 5 members the active TC members should nominate
+someone new. If a TC member is stepping down, they are encouraged (but not required) to
+nominate someone to take their place.
+
+TC members will be added as admin's on the Github orgs, npm orgs, and other resources as
+necessary to be effective in the role.
+
+To remain "active" a TC member should have participation within the last 12 months and miss
+no more than six consecutive TC meetings. Our goal is to increase participation, not punish
+people for any lack of participation, this guideline should be only be used as such
+(replace an inactive member with a new active one, for example). Members who do not meet this
+are expected to step down. If A TC member does not step down, an issue can be opened in the
+discussions repo to move them to inactive status. TC members who step down or are removed due
+to inactivity will be moved into inactive status.
+
+Inactive status members can become active members by self nomination if the TC is not already
+larger than the maximum of 10. They will also be given preference if, while at max size, an
+active member steps down.
+
+### Project Captains
+
+The Express TC can designate captains for individual projects/repos in the
+organizations. These captains are responsible for being the primary
+day-to-day maintainers of the repo on a technical and community front.
+Repo captains are empowered with repo ownership and package publication rights.
+When there are conflicts, especially on topics that effect the Express project
+at large, captains are responsible to raise it up to the TC and drive
+those conflicts to resolution. Captains are also responsible for making sure
+community members follow the community guidelines, maintaining the repo
+and the published package, as well as in providing user support.
+
+Like TC members, Repo captains are a subset of committers.
+
+To become a captain for a project the candidate is expected to participate in that
+project for at least 6 months as a committer prior to the request. They should have
+helped with code contributions as well as triaging issues. They are also required to
+have 2FA enabled on both their GitHub and npm accounts.
+
+Any TC member or an existing captain on the **same** repo can nominate another committer
+to the captain role. To do so, they should submit a PR to this document, updating the
+**Active Project Captains** section (while maintaining the sort order) with the project
+name, the nominee's GitHub handle, and their npm username (if different).
+
+- Repos can have as many captains as make sense for the scope of work.
+- A TC member or an existing repo captain **on the same project** can nominate a new captain.
+ Repo captains from other projects should not nominate captains for a different project.
+
+The PR will require at least 2 approvals from TC members and 2 weeks hold time to allow
+for comment and/or dissent. When the PR is merged, a TC member will add them to the
+proper GitHub/npm groups.
+
+#### Active Projects and Captains
+
+The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members)
+
+#### Current Initiative Captains
+
+The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains)
+
+### Inactivity and Emeritus Policy for Any Role
+
+To support the health and continuity of the project, all individuals holding a role within the community (such as Triager, Committer, WG member, Project Captain, or TC member) are encouraged to maintain active participation.
+
+Inactivity is defined as the absence of meaningful involvement in the project—such as contributions, code reviews, triage, meeting attendance, or discussion participation—for a continuous period of 6 months.
+
+#### Exceptions
+
+Anyone may request a temporary leave from active participation due to personal or professional reasons. In such cases, the individual should inform the relevant team or the Technical Committee (TC). During this time, the inactivity policy is paused, and the individual will not be flagged as inactive.
+
+#### Inactivity Process
+
+- If someone is deemed inactive, the individual may be transitioned to an emeritus role that reflects their past contributions. A best effort will be made to inform them that this has occurred. They may request to be reinstated when they are ready to be active again.
+- The emeritus status helps preserve a clear record of contributors who have meaningfully shaped the project over time.
+
+#### Accountability
+
+- The Technical Committee (TC) and the respective captains of each package/team are responsible for assessing activity levels and enacting this policy fairly and transparently, in coordination with other relevant teams.
+- In case of disagreement, the situation can be discussed and resolved by consensus within the TC or appropriate team.
+
+### Developer's Certificate of Origin 1.1
+
+```text
+By making a contribution to this project, I certify that:
+
+ (a) The contribution was created in whole or in part by me and I
+ have the right to submit it under the open source license
+ indicated in the file; or
+
+ (b) The contribution is based upon previous work that, to the best
+ of my knowledge, is covered under an appropriate open source
+ license and I have the right under that license to submit that
+ work with modifications, whether created in whole or in part
+ by me, under the same open source license (unless I am
+ permitted to submit under a different license), as indicated
+ in the file; or
+
+ (c) The contribution was provided directly to me by some other
+ person who certified (a), (b) or (c) and I have not modified
+ it.
+
+ (d) I understand and agree that this project and the contribution
+ are public and that a record of the contribution (including all
+ personal information I submit with it, including my sign-off) is
+ maintained indefinitely and may be redistributed consistent with
+ this project or the open source license(s) involved.
+```
+
+## Collaborator's guide
+
+
+
+### Website Issues
+
+Open issues for the expressjs.com website in https://github.com/expressjs/expressjs.com.
+
+For issues in other Express managed repos (everything in `expressjs`, `pillarjs` or `jshttp` other than `expressjs/express`), be sure to check their contributing guide and open issues and PRs in the appropriate repository.
+
+### PRs and Code contributions
+
+- Tests must pass.
+- Follow the [JavaScript Standard Style](https://standardjs.com/) and `npm run lint`.
+- If you fix a bug, add a test.
+
+### Branches
+
+Use the `master` branch for bug fixes or minor work that is intended for the
+current release stream.
+
+Use the correspondingly named branch, e.g. `6.x`, for anything intended for
+a future release of Express.
+
+### Steps for contributing
+
+1. Create an issue for the
+ bug you want to fix or the feature that you want to add.
+2. Create your own fork on GitHub, then
+ checkout your fork.
+3. Write your code in your local copy. It's good practice to create a branch for
+ each new issue you work on, although not compulsory.
+4. To run the test suite, first install the dependencies by running `npm install`,
+ then run `npm test`.
+5. Ensure your code is linted by running `npm run lint` -- fix any issue you
+ see listed.
+6. If the tests pass, you can commit your changes to your fork and then create
+ a pull request from there. Make sure to reference your issue from the pull
+ request comments by including the issue number e.g. `#123`.
+
+### Issues which are questions
+
+We will typically close any vague issues or questions that are specific to some
+app you are writing. Please double check the docs and other references before
+being trigger happy with posting a question issue.
+
+Things that will help get your question issue looked at:
+
+- Full and runnable JS code.
+- Clear description of the problem or unexpected behavior.
+- Clear description of the expected result.
+- Steps you have taken to debug it yourself.
+
+If you post a question and do not outline the above items or make it easy for
+us to understand and reproduce your issue, it will be closed.
+
+If your question meets all of the above requirements but you do not believe it needs to be looked at
+by the maintainers
+(for example, if you are just looking for community input) please open it as a discussion topic instead
+of an issue. If you
+are unsure and open an issue, we may move it to discussions if we triage them and decide they do
+not need high
+visibility or maintainer input.
+
+## Security Policies and Procedures
+
+
+
+This document outlines security procedures and general policies for the Express
+project.
+
+- [Reporting a Bug](#reporting-a-bug)
+- [Disclosure Policy](#disclosure-policy)
+- [Comments on this Policy](#comments-on-this-policy)
+
+### Reporting a Bug
+
+The Express team and community take all security bugs in Express seriously.
+Thank you for improving the security of Express. We appreciate your efforts and
+responsible disclosure and will make every effort to acknowledge your
+contributions.
+
+Report security bugs by emailing `express-security@lists.openjsf.org`.
+
+To ensure the timely response to your report, please ensure that the entirety
+of the report is contained within the email body and not solely behind a web
+link or an attachment.
+
+The lead maintainer will acknowledge your email within 48 hours, and will send a
+more detailed response within 48 hours indicating the next steps in handling
+your report. After the initial reply to your report, the security team will
+endeavor to keep you informed of the progress towards a fix and full
+announcement, and may ask for additional information or guidance.
+
+Report security bugs in third-party modules to the person or team maintaining
+the module.
+
+### Pre-release Versions
+
+Alpha and Beta releases are unstable and **not suitable for production use**.
+Vulnerabilities found in pre-releases should be reported according to the [Reporting a Bug](#reporting-a-bug) section.
+Due to the unstable nature of the branch it is not guaranteed that any fixes will be released in the next pre-release.
+
+### Disclosure Policy
+
+When the security team receives a security bug report, they will assign it to a
+primary handler. This person will coordinate the fix and release process,
+involving the following steps:
+
+- Confirm the problem and determine the affected versions.
+- Audit code to find any potential similar problems.
+- Prepare fixes for all releases still under maintenance. These fixes will be
+ released as fast as possible to npm.
+
+### The Express Threat Model
+
+We are currently working on a new version of the security model, the most updated version can be found [here](https://github.com/expressjs/security-wg/blob/main/docs/ThreatModel.md)
+
+### Comments on this Policy
+
+If you have suggestions on how this process could be improved please submit a
+pull request.
+
+---
+
+# Contributing to Expressjs.com {#expressjs-website-contributing}
+
+
+
+### The Official Documentation of the Express.js Framework
+
+This is the contribution documentation for the [expressjs.com](https://github.com/expressjs/expressjs.com) website.
+
+#### Need some ideas? These are some typical issues.
+
+1. **Website issues**: If you see anything on the site that could use a tune-up, think about how to fix it.
+ - Display or screen sizing problems
+ - Mobile responsiveness issues
+ - Missing or broken accessibility features
+ - Website outages
+ - Broken links
+ - Page structure or user interface enhancements
+
+2. **Content Issues**: Fix anything related to site content or typos.
+ - Spelling errors
+ - Incorrect/outdated Express.js documentation
+ - Missing content
+
+3. **Translation Issues**: Fix any translation errors or contribute new content.
+ - Fix spelling errors
+ - Fix incorrect/poorly translated words
+ - Check out the [Contributing translations](#contributing-translations) section below for a contributing guide.
+
+#### Want to work on a backlog issue?
+
+We often have bugs or enhancements that need work. You can find these under our repo's [Issues tab](https://github.com/expressjs/expressjs.com/issues). Check out the tags to find something that's a good match for you.
+
+#### Have an idea? Found a bug?
+
+If you've found a bug or a typo, or if you have an idea for an enhancement, you can:
+
+- Submit a [new issue](https://github.com/expressjs/expressjs.com/issues/new/choose) on our repo. Do this for larger proposals, or if you'd like to discuss or get feedback first.
+
+- Make a [GitHub pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). If you have already done work, and it's ready to go, feel free to send it our way.
+
+## Getting Started
+
+The steps below will guide you through the Expressjs.com contribution process.
+
+#### Step 1: (OPTIONAL) Open a New Issue
+
+So you've found a problem that you want to fix, or have a site enhancement you want to make.
+
+1. If you want to get feedback or discuss, open a discussion [issue](https://github.com/expressjs/expressjs.com/issues/new/choose) prior to starting work. This is not required, but encouraged for larger proposals.
+ - While we highly encourage this step, it is only for submissions proposing significant change. It helps us to clarify and focus the work, and ensure it aligns with overall project priorities.
+ - For submissions proposing minor improvements or corrections, this is not needed. You can skip this step.
+ - When opening an issue please give it a title and fill in the description section. The more details you provide, the more feedback we can give.
+
+2. After receiving your issue the Express.js documentation team will respond with feedback. We read every submission and always try to respond quickly with feedback.
+ - For submissions proposing significant change, we encourage you to follow the review process before starting work.
+
+#### Step 2: Get the Application Code Base
+
+Clone the repo and get the code:
+
+```sh
+git clone https://github.com/expressjs/expressjs.com.git
+```
+
+After you've got the code you're ready to start making your changes!
+
+But just in case you need a little extra explanation, this section below outlines the main sections of the code base, where most changes are likely to be made.
+
+**Markdown Page Files**:
+
+- These files render to html and make up the individual pages of the site. Most of the site's documentation text content is written in `md` files.
+- Change these to make changes to individual pages' content/text or markup.
+- Each language has its own complete set of pages, located under their respective language directories - all the Spanish markdown content is found in the `es` directory, for example.
+
+**Includes Partials and Layout Templates**
+
+- `_includes` are partials that are imported and reused across multiple pages.
+ - These are used to import text content for reuse across pages, such as the API documentation, e.g., `_includes > api > en > 5x`, which is included in every language.
+ - These are used to include the page components that make up site-wide user interface and periphery structure, e.g., Header, Footer, etc.
+- `_layouts` are the templates used to wrap the site's individual pages.
+ - These are used to display the structure of the site's periphery, such as the header and footer, and for injecting and displaying individual markdown pages inside the `content` tag.
+
+**Blog Markdown Files**
+
+- These files make up the individual blog posts. If you want to contribute a blog post please
+ follow the specific instructions for [How to write a blog post.](https://expressjs.com/en/blog/write-post)
+- Located under the `_posts` directory.
+
+**CSS or Javascript**
+
+- All css and js files are kept in `css` and `js` folders on the project root.
+
+The Express.js website is built using [Jekyll](https://jekyllrb.com/) and is hosted on [GitHub Pages](https://pages.github.com/).
+
+#### Step 3: Running the Application
+
+Now you'll need a way to see your changes, which means you'll need a running version of the application. You have two options.
+
+1. **Run Locally**: This gets the local version of the application up and running on your machine. Follow our [Local Setup Guide](https://github.com/expressjs/expressjs.com?tab=readme-ov-file#build-the-website-locally) to use this option.
+ - This is the recommended option for moderate to complex work.
+
+2. **Run using Deploy Preview**: Use this option if you don't want to bother with a local installation. Part of our continuous integration pipeline includes [Netlify Deploy Preview](https://docs.netlify.com/deploy/deploy-types/deploy-previews/).
+ 1. To use this you'll need to get your changes online - after you've made your first commit on your feature branch, make a _draft_ pull request.
+ 2. After the build steps are complete, you'll have access to a **Deploy Preview** tab that will run your changes on the web, rebuilding after each commit is pushed.
+ 3. After you are completely done your work, and it's ready for review, remove the draft status on your pull request and submit your work.
+
+## Contributing translations
+
+We use Crowdin to manage our translations in multiple languages and achieve automatic translation with artificial intelligence. Since these translations can be inefficient in some cases, we need help from the community to provide accurate and helpful translations.
+
+The documentation is translated into these languages:
+
+- Chinese Simplified (`zh-cn`)
+- Chinese Traditional (`zh-tw`)
+- English (`en`)
+- French (`fr`)
+- German (`de`)
+- Italian (`it`)
+- Japanese (`ja`)
+- Korean (`ko`)
+- Brazilian Portuguese (`pt-br`)
+- Spanish (`es`)
+
+### How to translate
+
+1. Request to join the Express.js Website project on [Crowdin](https://express.crowdin.com/website)
+2. [Select the language you want to translate](https://support.crowdin.com/for-translators/#starting-translation)
+3. [Start translating](https://support.crowdin.com/online-editor/)
diff --git a/astro/src/content/resources/fr/glossary.md b/astro/src/content/resources/fr/glossary.md
new file mode 100755
index 0000000000..8b45bf01eb
--- /dev/null
+++ b/astro/src/content/resources/fr/glossary.md
@@ -0,0 +1,62 @@
+---
+title: Express glossary
+description: A comprehensive glossary of terms related to Express.js, Node.js, middleware, routing, and other key concepts to help you understand and use Express effectively.
+---
+
+# Glossary
+
+### application
+
+In general, one or more programs that are designed to carry out operations for a specific purpose. In the context of Express, a program that uses the Express API running on the Node.js platform. Might also refer to an [app object](/en/api#express).
+
+### API
+
+Application programming interface. Spell out the abbreviation when it is first used.
+
+### Express
+
+A fast, un-opinionated, minimalist web framework for Node.js applications. In general, "Express" is preferred to "Express.js," though the latter is acceptable.
+
+### libuv
+
+A multi-platform support library which focuses on asynchronous I/O, primarily developed for use by Node.js.
+
+### middleware
+
+A function that is invoked by the Express routing layer before the final request handler, and thus sits in the middle between a raw request and the final intended route. A few fine points of terminology around middleware:
+
+- `var foo = require('middleware')` is called _requiring_ or _using_ a Node.js module. Then the statement `var mw = foo()` typically returns the middleware.
+- `app.use(mw)` is called _adding the middleware to the global processing stack_.
+- `app.get('/foo', mw, function (req, res) { ... })` is called _adding the middleware to the "GET /foo" processing stack_.
+
+### Node.js
+
+A software platform that is used to build scalable network applications. Node.js uses JavaScript as its scripting language, and achieves high throughput via non-blocking I/O and a single-threaded event loop. See [nodejs.org](https://nodejs.org/en/). **Usage note**: Initially, "Node.js," thereafter "Node".
+
+### open-source, open source
+
+When used as an adjective, hyphenate; for example: "This is open-source software." See [Open-source software on Wikipedia](http://en.wikipedia.org/wiki/Open-source_software).
+
+{% capture english-rules %}
+
+Although it is common not to hyphenate this term, we are using the standard English rules for hyphenating a compound adjective.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=english-rules %}
+
+### request
+
+An HTTP request. A client submits an HTTP request message to a server, which returns a response. The request must use one of several [request methods](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods) such as GET, POST, and so on.
+
+### response
+
+An HTTP response. A server returns an HTTP response message to the client. The response contains completion status information about the request and might also contain requested content in its message body.
+
+### route
+
+Part of a URL that identifies a resource. For example, in `http://foo.com/products/id`, "/products/id" is the route.
+
+### router
+
+See [router](/en/api#router) in the API reference.
diff --git a/astro/src/content/resources/fr/middleware/body-parser.md b/astro/src/content/resources/fr/middleware/body-parser.md
new file mode 100644
index 0000000000..e82649a95c
--- /dev/null
+++ b/astro/src/content/resources/fr/middleware/body-parser.md
@@ -0,0 +1,498 @@
+---
+title: Express body-parser middleware
+module: body-parser
+---
+
+# body-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+
+Node.js body parsing middleware.
+
+Parse incoming request bodies in a middleware before your handlers, available
+under the `req.body` property.
+
+**Note** As `req.body`'s shape is based on user-controlled input, all
+properties and values in this object are untrusted and should be validated
+before trusting. For example, `req.body.foo.toString()` may fail in multiple
+ways, for example the `foo` property may not be there or may not be a string,
+and `toString` may not be a function and instead a string or other user input.
+
+[Learn about the anatomy of an HTTP transaction in Node.js](https://nodejs.org/en/learn/http/anatomy-of-an-http-transaction).
+
+_This does not handle multipart bodies_, due to their complex and typically
+large nature. For multipart bodies, you may be interested in the following
+modules:
+
+- [busboy](https://www.npmjs.com/package/busboy#readme) and
+ [connect-busboy](https://www.npmjs.com/package/connect-busboy#readme)
+- [multiparty](https://www.npmjs.com/package/multiparty#readme) and
+ [connect-multiparty](https://www.npmjs.com/package/connect-multiparty#readme)
+- [formidable](https://www.npmjs.com/package/formidable#readme)
+- [multer](https://www.npmjs.com/package/multer#readme)
+
+This module provides the following parsers:
+
+- [JSON body parser](#bodyparserjsonoptions)
+- [Raw body parser](#bodyparserrawoptions)
+- [Text body parser](#bodyparsertextoptions)
+- [URL-encoded form body parser](#bodyparserurlencodedoptions)
+
+Other body parsers you might be interested in:
+
+- [body](https://www.npmjs.com/package/body#readme)
+- [co-body](https://www.npmjs.com/package/co-body#readme)
+
+## Installation
+
+```sh
+$ npm install body-parser
+```
+
+## API
+
+```js
+const bodyParser = require('body-parser');
+```
+
+The `bodyParser` object exposes various factories to create middlewares. All
+middlewares will populate the `req.body` property with the parsed body when
+the `Content-Type` request header matches the `type` option.
+
+The various errors returned by this module are described in the
+[errors section](#errors).
+
+### bodyParser.json([options])
+
+Returns middleware that only parses `json` and only looks at requests where
+the `Content-Type` header matches the `type` option. This parser accepts any
+Unicode encoding of the body and supports automatic inflation of `gzip`,
+`br` (brotli) and `deflate` encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`).
+
+#### Options
+
+The `json` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### defaultCharset
+
+Specify the default character set for the json content if the charset is not
+specified in the `Content-Type` header of the request. Defaults to `utf-8`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### reviver
+
+The `reviver` option is passed directly to `JSON.parse` as the second
+argument. You can find more information on this argument
+[in the MDN documentation about JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Example.3A_Using_the_reviver_parameter).
+
+##### strict
+
+When set to `true`, will only accept arrays and objects; when `false` will
+accept anything `JSON.parse` accepts. Defaults to `true`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not a
+function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `json`), a mime type (like `application/json`), or
+a mime type with a wildcard (like `*/*` or `*/json`). If a function, the `type`
+option is called as `fn(req)` and the request is parsed if it returns a truthy
+value. Defaults to `application/json`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.raw([options])
+
+Returns middleware that parses all bodies as a `Buffer` and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser supports automatic inflation of `gzip`, `br` (brotli) and `deflate`
+encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This will be a `Buffer` object
+of the body.
+
+#### Options
+
+The `raw` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function.
+If not a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this
+can be an extension name (like `bin`), a mime type (like
+`application/octet-stream`), or a mime type with a wildcard (like `*/*` or
+`application/*`). If a function, the `type` option is called as `fn(req)`
+and the request is parsed if it returns a truthy value. Defaults to
+`application/octet-stream`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.text([options])
+
+Returns middleware that parses all bodies as a string and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser supports automatic inflation of `gzip`, `br` (brotli) and `deflate`
+encodings.
+
+A new `body` string containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This will be a string of the
+body.
+
+#### Options
+
+The `text` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### defaultCharset
+
+Specify the default character set for the text content if the charset is not
+specified in the `Content-Type` header of the request. Defaults to `utf-8`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not
+a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `txt`), a mime type (like `text/plain`), or a mime
+type with a wildcard (like `*/*` or `text/*`). If a function, the `type`
+option is called as `fn(req)` and the request is parsed if it returns a
+truthy value. Defaults to `text/plain`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.urlencoded([options])
+
+Returns middleware that only parses `urlencoded` bodies and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser accepts only UTF-8 encoding of the body and supports automatic
+inflation of `gzip`, `br` (brotli) and `deflate` encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This object will contain
+key-value pairs, where the value can be a string or array (when `extended` is
+`false`), or any type (when `extended` is `true`).
+
+#### Options
+
+The `urlencoded` function takes an optional `options` object that may contain
+any of the following keys:
+
+##### extended
+
+The "extended" syntax allows for rich objects and arrays to be encoded into the
+URL-encoded format, allowing for a JSON-like experience with URL-encoded. For
+more information, please [see the qs
+library](https://www.npmjs.com/package/qs#readme).
+
+Defaults to `false`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### parameterLimit
+
+The `parameterLimit` option controls the maximum number of parameters that
+are allowed in the URL-encoded data. If a request contains more parameters
+than this value, a 413 will be returned to the client. Defaults to `1000`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not
+a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `urlencoded`), a mime type (like
+`application/x-www-form-urlencoded`), or a mime type with a wildcard (like
+`*/x-www-form-urlencoded`). If a function, the `type` option is called as
+`fn(req)` and the request is parsed if it returns a truthy value. Defaults
+to `application/x-www-form-urlencoded`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+##### defaultCharset
+
+The default charset to parse as, if not specified in content-type. Must be
+either `utf-8` or `iso-8859-1`. Defaults to `utf-8`.
+
+##### charsetSentinel
+
+Whether to let the value of the `utf8` parameter take precedence as the charset
+selector. It requires the form to contain a parameter named `utf8` with a value
+of `✓`. Defaults to `false`.
+
+##### interpretNumericEntities
+
+Whether to decode numeric entities such as `☺` when parsing an iso-8859-1
+form. Defaults to `false`.
+
+##### depth
+
+The `depth` option is used to configure the maximum depth of the `qs` library when `extended` is `true`. This allows you to limit the amount of keys that are parsed and can be useful to prevent certain types of abuse. Defaults to `32`. It is recommended to keep this value as low as possible.
+
+## Errors
+
+The middlewares provided by this module create errors using the
+[`http-errors` module](https://www.npmjs.com/package/http-errors). The errors
+will typically have a `status`/`statusCode` property that contains the suggested
+HTTP response code, an `expose` property to determine if the `message` property
+should be displayed to the client, a `type` property to determine the type of
+error without matching against the `message`, and a `body` property containing
+the read body, if available.
+
+The following are the common errors created, though any error can come through
+for various reasons.
+
+### content encoding unsupported
+
+This error will occur when the request had a `Content-Encoding` header that
+contained an encoding but the "inflation" option was set to `false`. The
+`status` property is set to `415`, the `type` property is set to
+`'encoding.unsupported'`, and the `charset` property will be set to the
+encoding that is unsupported.
+
+### entity parse failed
+
+This error will occur when the request contained an entity that could not be
+parsed by the middleware. The `status` property is set to `400`, the `type`
+property is set to `'entity.parse.failed'`, and the `body` property is set to
+the entity value that failed parsing.
+
+### entity verify failed
+
+This error will occur when the request contained an entity that could not be
+failed verification by the defined `verify` option. The `status` property is
+set to `403`, the `type` property is set to `'entity.verify.failed'`, and the
+`body` property is set to the entity value that failed verification.
+
+### request aborted
+
+This error will occur when the request is aborted by the client before reading
+the body has finished. The `received` property will be set to the number of
+bytes received before the request was aborted and the `expected` property is
+set to the number of expected bytes. The `status` property is set to `400`
+and `type` property is set to `'request.aborted'`.
+
+### request entity too large
+
+This error will occur when the request body's size is larger than the "limit"
+option. The `limit` property will be set to the byte limit and the `length`
+property will be set to the request body's length. The `status` property is
+set to `413` and the `type` property is set to `'entity.too.large'`.
+
+### request size did not match content length
+
+This error will occur when the request's length did not match the length from
+the `Content-Length` header. This typically occurs when the request is malformed,
+typically when the `Content-Length` header was calculated based on characters
+instead of bytes. The `status` property is set to `400` and the `type` property
+is set to `'request.size.invalid'`.
+
+### stream encoding should not be set
+
+This error will occur when something called the `req.setEncoding` method prior
+to this middleware. This module operates directly on bytes only and you cannot
+call `req.setEncoding` when using this module. The `status` property is set to
+`500` and the `type` property is set to `'stream.encoding.set'`.
+
+### stream is not readable
+
+This error will occur when the request is no longer readable when this middleware
+attempts to read it. This typically means something other than a middleware from
+this module read the request body already and the middleware was also configured to
+read the same request. The `status` property is set to `500` and the `type`
+property is set to `'stream.not.readable'`.
+
+### too many parameters
+
+This error will occur when the content of the request exceeds the configured
+`parameterLimit` for the `urlencoded` parser. The `status` property is set to
+`413` and the `type` property is set to `'parameters.too.many'`.
+
+### unsupported charset "BOGUS"
+
+This error will occur when the request had a charset parameter in the
+`Content-Type` header, but the `iconv-lite` module does not support it OR the
+parser does not support it. The charset is contained in the message as well
+as in the `charset` property. The `status` property is set to `415`, the
+`type` property is set to `'charset.unsupported'`, and the `charset` property
+is set to the charset that is unsupported.
+
+### unsupported content encoding "bogus"
+
+This error will occur when the request had a `Content-Encoding` header that
+contained an unsupported encoding. The encoding is contained in the message
+as well as in the `encoding` property. The `status` property is set to `415`,
+the `type` property is set to `'encoding.unsupported'`, and the `encoding`
+property is set to the encoding that is unsupported.
+
+### The input exceeded the depth
+
+This error occurs when using `bodyParser.urlencoded` with the `extended` property set to `true` and the input exceeds the configured `depth` option. The `status` property is set to `400`. It is recommended to review the `depth` option and evaluate if it requires a higher value. When the `depth` option is set to `32` (default value), the error will not be thrown.
+
+## Examples
+
+### Express/Connect top-level generic
+
+This example demonstrates adding a generic JSON and URL-encoded parser as a
+top-level middleware, which will parse the bodies of all incoming requests.
+This is the simplest setup.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// parse application/x-www-form-urlencoded
+app.use(bodyParser.urlencoded());
+
+// parse application/json
+app.use(bodyParser.json());
+
+app.use(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.write('you posted:\n');
+ res.end(String(JSON.stringify(req.body, null, 2)));
+});
+```
+
+### Express route-specific
+
+This example demonstrates adding body parsers specifically to the routes that
+need them. In general, this is the most recommended way to use body-parser with
+Express.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// create application/json parser
+const jsonParser = bodyParser.json();
+
+// create application/x-www-form-urlencoded parser
+const urlencodedParser = bodyParser.urlencoded();
+
+// POST /login gets urlencoded bodies
+app.post('/login', urlencodedParser, function (req, res) {
+ if (!req.body || !req.body.username) res.sendStatus(400);
+ res.send('welcome, ' + req.body.username);
+});
+
+// POST /api/users gets JSON bodies
+app.post('/api/users', jsonParser, function (req, res) {
+ if (!req.body) res.sendStatus(400);
+ // create user in req.body
+});
+```
+
+### Change accepted type for parsers
+
+All the parsers accept a `type` option which allows you to change the
+`Content-Type` that the middleware will parse.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// parse various different custom JSON types as JSON
+app.use(bodyParser.json({ type: 'application/*+json' }));
+
+// parse some custom thing into a Buffer
+app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }));
+
+// parse an HTML body into a string
+app.use(bodyParser.text({ type: 'text/html' }));
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/body-parser/ci.yml?branch=master&label=ci
+[ci-url]: https://github.com/expressjs/body-parser/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coverallsCoverage/github/expressjs/body-parser?branch=master
+[coveralls-url]: https://coveralls.io/r/expressjs/body-parser?branch=master
+[npm-downloads-image]: https://img.shields.io/npm/dm/body-parser
+[npm-url]: https://npmjs.com/package/body-parser
+[npm-version-image]: https://img.shields.io/npm/v/body-parser
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/body-parser/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/body-parser
diff --git a/astro/src/content/resources/fr/middleware/compression.md b/astro/src/content/resources/fr/middleware/compression.md
new file mode 100644
index 0000000000..6ac63fcb7a
--- /dev/null
+++ b/astro/src/content/resources/fr/middleware/compression.md
@@ -0,0 +1,314 @@
+---
+title: Express compression middleware
+module: compression
+---
+
+# compression
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+[![Funding][funding-image]][funding-url]
+
+Node.js compression middleware.
+
+The following compression codings are supported:
+
+- deflate
+- gzip
+- br (brotli)
+
+**Note** Brotli is supported only since Node.js versions v11.7.0 and v10.16.0.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```bash
+$ npm install compression
+```
+
+## API
+
+```js
+var compression = require('compression');
+```
+
+### compression([options])
+
+Returns the compression middleware using the given `options`. The middleware
+will attempt to compress response bodies for all requests that traverse through
+the middleware, based on the given `options`.
+
+This middleware will never compress responses that include a `Cache-Control`
+header with the [`no-transform` directive](https://tools.ietf.org/html/rfc7234#section-5.2.2.4),
+as compressing will transform the body.
+
+#### Options
+
+`compression()` accepts these properties in the options object. In addition to
+those listed below, [zlib](https://nodejs.org/api/zlib.html) options may be
+passed in to the options object or
+[brotli](https://nodejs.org/api/zlib.html#zlib_class_brotlioptions) options.
+
+##### chunkSize
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_CHUNK`, or `16384`.
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### filter
+
+Type: `Function`
+
+A function to decide if the response should be considered for compression.
+This function is called as `filter(req, res)` and is expected to return
+`true` to consider the response for compression, or `false` to not compress
+the response.
+
+The default filter function uses the [compressible](https://www.npmjs.com/package/compressible)
+module to determine if `res.getHeader('Content-Type')` is compressible.
+
+##### level
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_COMPRESSION`, or `-1`
+
+The level of zlib compression to apply to responses. A higher level will result
+in better compression, but will take longer to complete. A lower level will
+result in less compression, but will be much faster.
+
+This is an integer in the range of `0` (no compression) to `9` (maximum
+compression). The special value `-1` can be used to mean the "default
+compression level", which is a default compromise between speed and
+compression (currently equivalent to level 6).
+
+- `-1` Default compression level (also `zlib.constants.Z_DEFAULT_COMPRESSION`).
+- `0` No compression (also `zlib.constants.Z_NO_COMPRESSION`).
+- `1` Fastest compression (also `zlib.constants.Z_BEST_SPEED`).
+- `2`
+- `3`
+- `4`
+- `5`
+- `6` (currently what `zlib.constants.Z_DEFAULT_COMPRESSION` points to).
+- `7`
+- `8`
+- `9` Best compression (also `zlib.constants.Z_BEST_COMPRESSION`).
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### memLevel
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_MEMLEVEL`, or `8`
+
+This specifies how much memory should be allocated for the internal compression
+state and is an integer in the range of `1` (minimum level) and `9` (maximum
+level).
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### brotli
+
+Type: `Object`
+
+This specifies the options for configuring Brotli. See [Node.js documentation](https://nodejs.org/api/zlib.html#class-brotlioptions) for a complete list of available options.
+
+##### strategy
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_STRATEGY`
+
+This is used to tune the compression algorithm. This value only affects the
+compression ratio, not the correctness of the compressed output, even if it
+is not set appropriately.
+
+- `zlib.constants.Z_DEFAULT_STRATEGY` Use for normal data.
+- `zlib.constants.Z_FILTERED` Use for data produced by a filter (or predictor).
+ Filtered data consists mostly of small values with a somewhat random
+ distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect is to force more Huffman coding and less
+ string matching; it is somewhat intermediate between `zlib.constants.Z_DEFAULT_STRATEGY`
+ and `zlib.constants.Z_HUFFMAN_ONLY`.
+- `zlib.constants.Z_FIXED` Use to prevent the use of dynamic Huffman codes, allowing
+ for a simpler decoder for special applications.
+- `zlib.constants.Z_HUFFMAN_ONLY` Use to force Huffman encoding only (no string match).
+- `zlib.constants.Z_RLE` Use to limit match distances to one (run-length encoding).
+ This is designed to be almost as fast as `zlib.constants.Z_HUFFMAN_ONLY`, but give
+ better compression for PNG image data.
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### threshold
+
+Type: `Number` or `String`
+Default: `1kb`
+
+The byte threshold for the response body size before compression is considered
+for the response. This is a number of bytes or any string
+accepted by the [bytes](https://www.npmjs.com/package/bytes) module.
+
+**Note** this is only an advisory setting; if the response size cannot be determined
+at the time the response headers are written, then it is assumed the response is
+_over_ the threshold. To guarantee the response size can be determined, be sure
+set a `Content-Length` response header.
+
+##### windowBits
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_WINDOWBITS`, or `15`
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### enforceEncoding
+
+Type: `String`
+Default: `identity`
+
+This is the default encoding to use when the client does not specify an encoding in the request's [Accept-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) header.
+
+#### .filter
+
+The default `filter` function. This is used to construct a custom filter
+function that is an extension of the default function.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+app.use(compression({ filter: shouldCompress }));
+
+function shouldCompress(req, res) {
+ if (req.headers['x-no-compression']) {
+ // don't compress responses with this request header
+ return false;
+ }
+
+ // fallback to standard filter function
+ return compression.filter(req, res);
+}
+```
+
+### res.flush
+
+This module adds a `res.flush()` method to force the partially-compressed
+response to be flushed to the client.
+
+## Examples
+
+### express
+
+When using this module with express, simply `app.use` the module as
+high as you like. Requests that pass through the middleware will be compressed.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress all responses
+app.use(compression());
+
+// add all routes
+```
+
+### Node.js HTTP server
+
+```js
+var compression = require('compression')({ threshold: 0 });
+var http = require('http');
+
+function createServer(fn) {
+ return http.createServer(function (req, res) {
+ compression(req, res, function (err) {
+ if (err) {
+ res.statusCode = err.status || 500;
+ res.end(err.message);
+ return;
+ }
+
+ fn(req, res);
+ });
+ });
+}
+
+var server = createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello world!');
+});
+
+server.listen(3000, () => {
+ console.log('> Listening at http://localhost:3000');
+});
+```
+
+### Server-Sent Events
+
+Because of the nature of compression this module does not work out of the box
+with server-sent events. To compress content, a window of the output needs to
+be buffered up in order to get good compression. Typically when using server-sent
+events, there are certain block of data that need to reach the client.
+
+You can achieve this by calling `res.flush()` when you need the data written to
+actually make it to the client.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress responses
+app.use(compression());
+
+// server-sent event stream
+app.get('/events', function (req, res) {
+ res.setHeader('Content-Type', 'text/event-stream');
+ res.setHeader('Cache-Control', 'no-cache');
+
+ // send a ping approx every 2 seconds
+ var timer = setInterval(function () {
+ res.write('data: ping\n\n');
+
+ // !!! this is the important part
+ res.flush();
+ }, 2000);
+
+ res.on('close', function () {
+ clearInterval(timer);
+ });
+});
+```
+
+## Contributing
+
+The Express.js project welcomes all constructive contributions. Contributions take many forms,
+from code for bug fixes and enhancements, to additions and fixes to documentation, additional
+tests, triaging incoming pull requests and issues, and more!
+
+See the [Contributing Guide](https://github.com/expressjs/express/blob/master/Contributing.md) for more technical details on contributing.
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://badgen.net/npm/v/compression
+[npm-url]: https://npmjs.org/package/compression
+[downloads-image]: https://badgen.net/npm/dm/compression
+[downloads-url]: https://npmcharts.com/compare/compression?minimal=true
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/compression/master?label=CI
+[github-actions-ci-url]: https://github.com/expressjs/compression/actions?query=workflow%3Aci
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/compression/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/compression
+[funding-url]: https://opencollective.com/express
+[funding-image]: https://badgen.net/badge/icon/sponsor/pink?icon=github&label=Open%20Collective
diff --git a/astro/src/content/resources/fr/middleware/cookie-parser.md b/astro/src/content/resources/fr/middleware/cookie-parser.md
new file mode 100644
index 0000000000..2a59496387
--- /dev/null
+++ b/astro/src/content/resources/fr/middleware/cookie-parser.md
@@ -0,0 +1,124 @@
+---
+title: Express cookie-parser middleware
+module: cookie-parser
+---
+
+# cookie-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Parse `Cookie` header and populate `req.cookies` with an object keyed by the
+cookie names. Optionally you may enable signed cookie support by passing a
+`secret` string, which assigns `req.secret` so it may be used by other
+middleware.
+
+## Installation
+
+```sh
+$ npm install cookie-parser
+```
+
+## API
+
+```js
+var cookieParser = require('cookie-parser');
+```
+
+### cookieParser(secret, options)
+
+Create a new cookie parser middleware function using the given `secret` and
+`options`.
+
+- `secret` a string or array used for signing cookies. This is optional and if
+ not specified, will not parse signed cookies. If a string is provided, this
+ is used as the secret. If an array is provided, an attempt will be made to
+ unsign the cookie with each secret in order.
+- `options` an object that is passed to `cookie.parse` as the second option. See
+ [cookie](https://www.npmjs.org/package/cookie) for more information.
+ - `decode` a function to decode the value of the cookie
+
+The middleware will parse the `Cookie` header on the request and expose the
+cookie data as the property `req.cookies` and, if a `secret` was provided, as
+the property `req.signedCookies`. These properties are name value pairs of the
+cookie name to cookie value.
+
+When `secret` is provided, this module will unsign and validate any signed cookie
+values and move those name value pairs from `req.cookies` into `req.signedCookies`.
+A signed cookie is a cookie that has a value prefixed with `s:`. Signed cookies
+that fail signature validation will have the value `false` instead of the tampered
+value.
+
+In addition, this module supports special "JSON cookies". These are cookie where
+the value is prefixed with `j:`. When these values are encountered, the value will
+be exposed as the result of `JSON.parse`. If parsing fails, the original value will
+remain.
+
+### cookieParser.JSONCookie(str)
+
+Parse a cookie value as a JSON cookie. This will return the parsed JSON value
+if it was a JSON cookie, otherwise, it will return the passed value.
+
+### cookieParser.JSONCookies(cookies)
+
+Given an object, this will iterate over the keys and call `JSONCookie` on each
+value, replacing the original value with the parsed value. This returns the
+same object that was passed in.
+
+### cookieParser.signedCookie(str, secret)
+
+Parse a cookie value as a signed cookie. This will return the parsed unsigned
+value if it was a signed cookie and the signature was valid. If the value was
+not signed, the original value is returned. If the value was signed but the
+signature could not be validated, `false` is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+### cookieParser.signedCookies(cookies, secret)
+
+Given an object, this will iterate over the keys and check if any value is a
+signed cookie. If it is a signed cookie and the signature is valid, the key
+will be deleted from the object and added to the new object that is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+## Example
+
+```js
+var express = require('express');
+var cookieParser = require('cookie-parser');
+
+var app = express();
+app.use(cookieParser());
+
+app.get('/', function (req, res) {
+ // Cookies that have not been signed
+ console.log('Cookies: ', req.cookies);
+
+ // Cookies that have been signed
+ console.log('Signed Cookies: ', req.signedCookies);
+});
+
+app.listen(8080);
+
+// curl command that sends an HTTP request with two cookies
+// curl http://127.0.0.1:8080 --cookie "Cho=Kim;Greet=Hello"
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/cookie-parser/master?label=ci
+[ci-url]: https://github.com/expressjs/cookie-parser/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/cookie-parser/master
+[coveralls-url]: https://coveralls.io/r/expressjs/cookie-parser?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/cookie-parser
+[npm-url]: https://npmjs.org/package/cookie-parser
+[npm-version-image]: https://badgen.net/npm/v/cookie-parser
diff --git a/astro/src/content/resources/fr/middleware/cookie-session.md b/astro/src/content/resources/fr/middleware/cookie-session.md
new file mode 100644
index 0000000000..2d6d1f885b
--- /dev/null
+++ b/astro/src/content/resources/fr/middleware/cookie-session.md
@@ -0,0 +1,124 @@
+---
+title: Express cookie-session middleware
+module: cookie-session
+---
+
+# cookie-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Parse `Cookie` header and populate `req.cookies` with an object keyed by the
+cookie names. Optionally you may enable signed cookie support by passing a
+`secret` string, which assigns `req.secret` so it may be used by other
+middleware.
+
+## Installation
+
+```sh
+$ npm install cookie-parser
+```
+
+## API
+
+```js
+var cookieParser = require('cookie-parser');
+```
+
+### cookieParser(secret, options)
+
+Create a new cookie parser middleware function using the given `secret` and
+`options`.
+
+- `secret` a string or array used for signing cookies. This is optional and if
+ not specified, will not parse signed cookies. If a string is provided, this
+ is used as the secret. If an array is provided, an attempt will be made to
+ unsign the cookie with each secret in order.
+- `options` an object that is passed to `cookie.parse` as the second option. See
+ [cookie](https://www.npmjs.org/package/cookie) for more information.
+ - `decode` a function to decode the value of the cookie
+
+The middleware will parse the `Cookie` header on the request and expose the
+cookie data as the property `req.cookies` and, if a `secret` was provided, as
+the property `req.signedCookies`. These properties are name value pairs of the
+cookie name to cookie value.
+
+When `secret` is provided, this module will unsign and validate any signed cookie
+values and move those name value pairs from `req.cookies` into `req.signedCookies`.
+A signed cookie is a cookie that has a value prefixed with `s:`. Signed cookies
+that fail signature validation will have the value `false` instead of the tampered
+value.
+
+In addition, this module supports special "JSON cookies". These are cookie where
+the value is prefixed with `j:`. When these values are encountered, the value will
+be exposed as the result of `JSON.parse`. If parsing fails, the original value will
+remain.
+
+### cookieParser.JSONCookie(str)
+
+Parse a cookie value as a JSON cookie. This will return the parsed JSON value
+if it was a JSON cookie, otherwise, it will return the passed value.
+
+### cookieParser.JSONCookies(cookies)
+
+Given an object, this will iterate over the keys and call `JSONCookie` on each
+value, replacing the original value with the parsed value. This returns the
+same object that was passed in.
+
+### cookieParser.signedCookie(str, secret)
+
+Parse a cookie value as a signed cookie. This will return the parsed unsigned
+value if it was a signed cookie and the signature was valid. If the value was
+not signed, the original value is returned. If the value was signed but the
+signature could not be validated, `false` is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+### cookieParser.signedCookies(cookies, secret)
+
+Given an object, this will iterate over the keys and check if any value is a
+signed cookie. If it is a signed cookie and the signature is valid, the key
+will be deleted from the object and added to the new object that is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+## Example
+
+```js
+var express = require('express');
+var cookieParser = require('cookie-parser');
+
+var app = express();
+app.use(cookieParser());
+
+app.get('/', function (req, res) {
+ // Cookies that have not been signed
+ console.log('Cookies: ', req.cookies);
+
+ // Cookies that have been signed
+ console.log('Signed Cookies: ', req.signedCookies);
+});
+
+app.listen(8080);
+
+// curl command that sends an HTTP request with two cookies
+// curl http://127.0.0.1:8080 --cookie "Cho=Kim;Greet=Hello"
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/cookie-parser/master?label=ci
+[ci-url]: https://github.com/expressjs/cookie-parser/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/cookie-parser/master
+[coveralls-url]: https://coveralls.io/r/expressjs/cookie-parser?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/cookie-parser
+[npm-url]: https://npmjs.org/package/cookie-parser
+[npm-version-image]: https://badgen.net/npm/v/cookie-parser
diff --git a/astro/src/content/resources/fr/middleware/cors.md b/astro/src/content/resources/fr/middleware/cors.md
new file mode 100644
index 0000000000..55d70922cb
--- /dev/null
+++ b/astro/src/content/resources/fr/middleware/cors.md
@@ -0,0 +1,261 @@
+---
+title: Express cors middleware
+module: cors
+---
+
+# cors
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+CORS is a [Node.js](https://nodejs.org/en/) package for providing a [Connect](https://github.com/senchalabs/connect)/[Express](https://expressjs.com/) middleware that can be used to enable [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS) with various options.
+
+- [Installation](#installation)
+- [Usage](#usage)
+ - [Simple Usage](#simple-usage-enable-all-cors-requests)
+ - [Enable CORS for a Single Route](#enable-cors-for-a-single-route)
+ - [Configuring CORS](#configuring-cors)
+ - [Configuring CORS w/ Dynamic Origin](#configuring-cors-w-dynamic-origin)
+ - [Enabling CORS Pre-Flight](#enabling-cors-pre-flight)
+ - [Customizing CORS Settings Dynamically per Request](#customizing-cors-settings-dynamically-per-request)
+- [Configuration Options](#configuration-options)
+- [License](#license)
+- [Original Author](#original-author)
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/downloading-and-installing-packages-locally):
+
+```sh
+$ npm install cors
+```
+
+## Usage
+
+### Simple Usage (Enable _All_ CORS Requests)
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.use(cors());
+
+app.get('/products/:id', function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for all origins!' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Enable CORS for a Single Route
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.get('/products/:id', cors(), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for a Single Route' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Configuring CORS
+
+See the [configuration options](#configuration-options) for details.
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+var corsOptions = {
+ origin: 'http://example.com',
+ optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
+};
+
+app.get('/products/:id', cors(corsOptions), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for only example.com.' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Configuring CORS w/ Dynamic Origin
+
+This module supports validating the origin dynamically using a function provided
+to the `origin` option. This function will be passed a string that is the origin
+(or `undefined` if the request has no origin), and a `callback` with the signature
+`callback(error, origin)`.
+
+The `origin` argument to the callback can be any value allowed for the `origin`
+option of the middleware, except a function. See the
+[configuration options](#configuration-options) section for more information on all
+the possible value types.
+
+This function is designed to allow the dynamic loading of allowed origin(s) from
+a backing datasource, like a database.
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+var corsOptions = {
+ origin: function (origin, callback) {
+ // db.loadOrigins is an example call to load
+ // a list of origins from a backing database
+ db.loadOrigins(function (error, origins) {
+ callback(error, origins);
+ });
+ },
+};
+
+app.get('/products/:id', cors(corsOptions), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for an allowed domain.' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Enabling CORS Pre-Flight
+
+Certain CORS requests are considered 'complex' and require an initial
+`OPTIONS` request (called the "pre-flight request"). An example of a
+'complex' CORS request is one that uses an HTTP verb other than
+GET/HEAD/POST (such as DELETE) or that uses custom headers. To enable
+pre-flighting, you must add a new OPTIONS handler for the route you want
+to support:
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.options('/products/:id', cors()); // enable pre-flight request for DELETE request
+app.del('/products/:id', cors(), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for all origins!' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+You can also enable pre-flight across-the-board like so:
+
+```javascript
+app.options('*', cors()); // include before other routes
+```
+
+NOTE: When using this middleware as an application level middleware (for
+example, `app.use(cors())`), pre-flight requests are already handled for all
+routes.
+
+### Customizing CORS Settings Dynamically per Request
+
+For APIs that require different CORS configurations for specific routes or requests, you can dynamically generate CORS options based on the incoming request. The `cors` middleware allows you to achieve this by passing a function instead of static options. This function is called for each incoming request and must use the callback pattern to return the appropriate CORS options.
+
+The function accepts:
+
+1. **`req`**:
+ - The incoming request object.
+
+2. **`callback(error, corsOptions)`**:
+ - A function used to return the computed CORS options.
+ - **Arguments**:
+ - **`error`**: Pass `null` if there’s no error, or an error object to indicate a failure.
+ - **`corsOptions`**: An object specifying the CORS policy for the current request.
+
+Here’s an example that handles both public routes and restricted, credential-sensitive routes:
+
+```javascript
+var dynamicCorsOptions = function (req, callback) {
+ var corsOptions;
+ if (req.path.startsWith('/auth/connect/')) {
+ corsOptions = {
+ origin: 'http://mydomain.com', // Allow only a specific origin
+ credentials: true, // Enable cookies and credentials
+ };
+ } else {
+ corsOptions = { origin: '*' }; // Allow all origins for other routes
+ }
+ callback(null, corsOptions);
+};
+
+app.use(cors(dynamicCorsOptions));
+
+app.get('/auth/connect/twitter', function (req, res) {
+ res.send('CORS dynamically applied for Twitter authentication.');
+});
+
+app.get('/public', function (req, res) {
+ res.send('Public data with open CORS.');
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+## Configuration Options
+
+- `origin`: Configures the **Access-Control-Allow-Origin** CORS header. Possible values:
+ - `Boolean` - set `origin` to `true` to reflect the [request origin](https://datatracker.ietf.org/doc/html/draft-abarth-origin-09), as defined by `req.header('Origin')`, or set it to `false` to disable CORS.
+ - `String` - set `origin` to a specific origin. For example, if you set it to
+ - `"http://example.com"` only requests from "http://example.com" will be allowed.
+ - `"*"` for all domains to be allowed.
+ - `RegExp` - set `origin` to a regular expression pattern which will be used to test the request origin. If it's a match, the request origin will be reflected. For example the pattern `/example\.com$/` will reflect any request that is coming from an origin ending with "example.com".
+ - `Array` - set `origin` to an array of valid origins. Each origin can be a `String` or a `RegExp`. For example `["http://example1.com", /\.example2\.com$/]` will accept any request from "http://example1.com" or from a subdomain of "example2.com".
+ - `Function` - set `origin` to a function implementing some custom logic. The function takes the request origin as the first parameter and a callback (called as `callback(err, origin)`, where `origin` is a non-function value of the `origin` option) as the second.
+- `methods`: Configures the **Access-Control-Allow-Methods** CORS header. Expects a comma-delimited string (ex: 'GET,PUT,POST') or an array (ex: `['GET', 'PUT', 'POST']`).
+- `allowedHeaders`: Configures the **Access-Control-Allow-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Type,Authorization') or an array (ex: `['Content-Type', 'Authorization']`). If not specified, defaults to reflecting the headers specified in the request's **Access-Control-Request-Headers** header.
+- `exposedHeaders`: Configures the **Access-Control-Expose-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Range,X-Content-Range') or an array (ex: `['Content-Range', 'X-Content-Range']`). If not specified, no custom headers are exposed.
+- `credentials`: Configures the **Access-Control-Allow-Credentials** CORS header. Set to `true` to pass the header, otherwise it is omitted.
+- `maxAge`: Configures the **Access-Control-Max-Age** CORS header. Set to an integer to pass the header, otherwise it is omitted.
+- `preflightContinue`: Pass the CORS preflight response to the next handler.
+- `optionsSuccessStatus`: Provides a status code to use for successful `OPTIONS` requests, since some legacy browsers (IE11, various SmartTVs) choke on `204`.
+
+The default configuration is the equivalent of:
+
+```json
+{
+ "origin": "*",
+ "methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
+ "preflightContinue": false,
+ "optionsSuccessStatus": 204
+}
+```
+
+For details on the effect of each CORS header, read [this](https://web.dev/articles/cross-origin-resource-sharing) article.
+
+## License
+
+[MIT License](http://www.opensource.org/licenses/mit-license.php)
+
+## Original Author
+
+[Troy Goode](https://github.com/TroyGoode) ([troygoode@gmail.com](mailto:troygoode@gmail.com))
+
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/cors/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/cors?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/cors.svg
+[downloads-url]: https://npmjs.com/package/cors
+[github-actions-ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/cors/ci.yml?branch=master&label=ci
+[github-actions-ci-url]: https://github.com/expressjs/cors?query=workflow%3Aci
+[npm-image]: https://img.shields.io/npm/v/cors.svg
+[npm-url]: https://npmjs.com/package/cors
diff --git a/astro/src/content/resources/fr/middleware/errorhandler.md b/astro/src/content/resources/fr/middleware/errorhandler.md
new file mode 100644
index 0000000000..20df618320
--- /dev/null
+++ b/astro/src/content/resources/fr/middleware/errorhandler.md
@@ -0,0 +1,133 @@
+---
+title: Express errorhandler middleware
+module: errorhandler
+---
+
+# errorhandler
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Development-only error handler middleware.
+
+This middleware is only intended to be used in a development environment, as
+the _full error stack traces and internal details of any object passed to this
+module_ will be sent back to the client when an error occurs.
+
+When an object is provided to Express as an error, this module will display
+as much about this object as possible, and will do so by using content negotiation
+for the response between HTML, JSON, and plain text.
+
+- When the object is a standard `Error` object, the string provided by the
+ `stack` property will be returned in HTML/text responses.
+- When the object is a non-`Error` object, the result of
+ [util.inspect](https://nodejs.org/api/util.html#util_util_inspect_object_options)
+ will be returned in HTML/text responses.
+- For JSON responses, the result will be an object with all enumerable properties
+ from the object in the response.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install errorhandler
+```
+
+## API
+
+
+
+```js
+var errorhandler = require('errorhandler');
+```
+
+### errorhandler(options)
+
+Create new middleware to handle errors and respond with content negotiation.
+
+#### Options
+
+Error handler accepts these properties in the options object.
+
+##### log
+
+Provide a function to be called with the error and a string representation of
+the error. Can be used to write the error to any desired location, or set to
+`false` to only send the error back in the response. Called as
+`log(err, str, req, res)` where `err` is the `Error` object, `str` is a string
+representation of the error, `req` is the request object and `res` is the
+response object (note, this function is invoked _after_ the response has been
+written).
+
+The default value for this option is `true` unless `process.env.NODE_ENV === 'test'`.
+
+Possible values:
+
+- `true`: Log errors using `console.error(str)`.
+- `false`: Only send the error back in the response.
+- A function: pass the error to a function for handling.
+
+## Examples
+
+### Simple example
+
+Basic example of adding this middleware as the error handler only in development
+with `connect` (`express` also can be used in this example).
+
+```js
+var connect = require('connect');
+var errorhandler = require('errorhandler');
+
+var app = connect();
+
+// assumes NODE_ENV is set by the user
+if (process.env.NODE_ENV === 'development') {
+ // only use in development
+ app.use(errorhandler());
+}
+```
+
+### Custom output location
+
+Sometimes you may want to output the errors to a different location than STDERR
+during development, like a system notification, for example.
+
+
+
+```js
+var connect = require('connect');
+var errorhandler = require('errorhandler');
+var notifier = require('node-notifier');
+
+var app = connect();
+
+// assumes NODE_ENV is set by the user
+if (process.env.NODE_ENV === 'development') {
+ // only use in development
+ app.use(errorhandler({ log: errorNotification }));
+}
+
+function errorNotification(err, str, req) {
+ var title = 'Error in ' + req.method + ' ' + req.url;
+
+ notifier.notify({
+ title: title,
+ message: str,
+ });
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/errorhandler/master
+[coveralls-url]: https://coveralls.io/r/expressjs/errorhandler?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/errorhandler
+[npm-url]: https://npmjs.org/package/errorhandler
+[npm-version-image]: https://badgen.net/npm/v/errorhandler
diff --git a/astro/src/content/resources/fr/middleware/method-override.md b/astro/src/content/resources/fr/middleware/method-override.md
new file mode 100644
index 0000000000..7b97ab855e
--- /dev/null
+++ b/astro/src/content/resources/fr/middleware/method-override.md
@@ -0,0 +1,187 @@
+---
+title: Express method-override middleware
+module: method-override
+---
+
+# method-override
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][travis-image]][travis-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Lets you use HTTP verbs such as PUT or DELETE in places where the client doesn't support it.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install method-override
+```
+
+## API
+
+**NOTE** It is very important that this module is used **before** any module that
+needs to know the method of the request (for example, it _must_ be used prior to
+the `csurf` module).
+
+### methodOverride(getter, options)
+
+Create a new middleware function to override the `req.method` property with a new
+value. This value will be pulled from the provided `getter`.
+
+- `getter` - The getter to use to look up the overridden request method for the request. (default: `X-HTTP-Method-Override`)
+- `options.methods` - The allowed methods the original request must be in to check for a method override value. (default: `['POST']`)
+
+If the found method is supported by node.js core, then `req.method` will be set to
+this value, as if it has originally been that value. The previous `req.method`
+value will be stored in `req.originalMethod`.
+
+#### getter
+
+This is the method of getting the override value from the request. If a function is provided,
+the `req` is passed as the first argument, the `res` as the second argument and the method is
+expected to be returned. If a string is provided, the string is used to look up the method
+with the following rules:
+
+- If the string starts with `X-`, then it is treated as the name of a header and that header
+ is used for the method override. If the request contains the same header multiple times, the
+ first occurrence is used.
+- All other strings are treated as a key in the URL query string.
+
+#### options.methods
+
+This allows the specification of what methods(s) the request _MUST_ be in in order to check for
+the method override value. This defaults to only `POST` methods, which is the only method the
+override should arrive in. More methods may be specified here, but it may introduce security
+issues and cause weird behavior when requests travel through caches. This value is an array
+of methods in upper-case. `null` can be specified to allow all methods.
+
+## Examples
+
+### override using a header
+
+To use a header to override the method, specify the header name
+as a string argument to the `methodOverride` function. To then make
+the call, send a `POST` request to a URL with the overridden method
+as the value of that header. This method of using a header would
+typically be used in conjunction with `XMLHttpRequest` on implementations
+that do not support the method you are trying to use.
+
+```js
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// override with the X-HTTP-Method-Override header in the request
+app.use(methodOverride('X-HTTP-Method-Override'));
+```
+
+Example call with header override using `XMLHttpRequest`:
+
+
+
+```js
+const xhr = new XMLHttpRequest();
+xhr.onload = onload;
+xhr.open('post', '/resource', true);
+xhr.setRequestHeader('X-HTTP-Method-Override', 'DELETE');
+xhr.send();
+
+function onload() {
+ alert('got response: ' + this.responseText);
+}
+```
+
+### override using a query value
+
+To use a query string value to override the method, specify the query
+string key as a string argument to the `methodOverride` function. To
+then make the call, send a `POST` request to a URL with the overridden
+method as the value of that query string key. This method of using a
+query value would typically be used in conjunction with plain HTML
+`
+```
+
+### multiple format support
+
+```js
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// override with different headers; last one takes precedence
+app.use(methodOverride('X-HTTP-Method')); // Microsoft
+app.use(methodOverride('X-HTTP-Method-Override')); // Google/GData
+app.use(methodOverride('X-Method-Override')); // IBM
+```
+
+### custom logic
+
+You can implement any kind of custom logic with a function for the `getter`. The following
+implements the logic for looking in `req.body` that was in `method-override@1`:
+
+```js
+const bodyParser = require('body-parser');
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// NOTE: when using req.body, you must fully parse the request body
+// before you call methodOverride() in your middleware stack,
+// otherwise req.body will not be populated.
+app.use(bodyParser.urlencoded());
+app.use(
+ methodOverride(function (req, res) {
+ if (req.body && typeof req.body === 'object' && '_method' in req.body) {
+ // look in urlencoded POST bodies and delete it
+ const method = req.body._method;
+ delete req.body._method;
+ return method;
+ }
+ })
+);
+```
+
+Example call with query override using HTML `
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/method-override.svg
+[npm-url]: https://npmjs.org/package/method-override
+[travis-image]: https://img.shields.io/travis/expressjs/method-override/master.svg
+[travis-url]: https://travis-ci.org/expressjs/method-override
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/method-override/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/method-override?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/method-override.svg
+[downloads-url]: https://npmjs.org/package/method-override
diff --git a/astro/src/content/resources/fr/middleware/morgan.md b/astro/src/content/resources/fr/middleware/morgan.md
new file mode 100644
index 0000000000..5319d93d57
--- /dev/null
+++ b/astro/src/content/resources/fr/middleware/morgan.md
@@ -0,0 +1,458 @@
+---
+title: Express morgan middleware
+module: morgan
+---
+
+# morgan
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+HTTP request logger middleware for node.js
+
+> Named after [Dexter](http://en.wikipedia.org/wiki/Dexter_Morgan), a show you should not watch until completion.
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install morgan
+```
+
+## API
+
+
+
+```js
+var morgan = require('morgan');
+```
+
+### morgan(format, options)
+
+Create a new morgan logger middleware function using the given `format` and `options`.
+The `format` argument may be a string of a predefined name (see below for the names),
+a string of a format string, or a function that will produce a log entry.
+
+The `format` function will be called with three arguments `tokens`, `req`, and `res`,
+where `tokens` is an object with all defined tokens, `req` is the HTTP request and `res`
+is the HTTP response. The function is expected to return a string that will be the log
+line, or `undefined` / `null` to skip logging.
+
+#### Using a predefined format string
+
+
+
+```js
+morgan('tiny');
+```
+
+#### Using format string of predefined tokens
+
+
+
+```js
+morgan(':method :url :status :res[content-length] - :response-time ms');
+```
+
+#### Using a custom format function
+
+
+
+```js
+morgan(function (tokens, req, res) {
+ return [
+ tokens.method(req, res),
+ tokens.url(req, res),
+ tokens.status(req, res),
+ tokens.res(req, res, 'content-length'),
+ '-',
+ tokens['response-time'](req, res),
+ 'ms',
+ ].join(' ');
+});
+```
+
+#### Options
+
+Morgan accepts these properties in the options object.
+
+##### immediate
+
+Write log line on request instead of response. This means that a requests will
+be logged even if the server crashes, _but data from the response (like the
+response code, content length, etc.) cannot be logged_.
+
+##### skip
+
+Function to determine if logging is skipped, defaults to `false`. This function
+will be called as `skip(req, res)`.
+
+
+
+```js
+// EXAMPLE: only log error responses
+morgan('combined', {
+ skip: function (req, res) {
+ return res.statusCode < 400;
+ },
+});
+```
+
+##### stream
+
+Output stream for writing log lines, defaults to `process.stdout`.
+
+#### Predefined Formats
+
+There are various pre-defined formats provided:
+
+##### combined
+
+Standard Apache combined log output.
+
+```
+:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"
+# will output
+::1 - - [27/Nov/2024:06:21:42 +0000] "GET /combined HTTP/1.1" 200 2 "-" "curl/8.7.1"
+```
+
+##### common
+
+Standard Apache common log output.
+
+```
+:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length]
+# will output
+::1 - - [27/Nov/2024:06:21:46 +0000] "GET /common HTTP/1.1" 200 2
+```
+
+##### dev
+
+Concise output colored by response status for development use. The `:status`
+token will be colored green for success codes, red for server error codes,
+yellow for client error codes, cyan for redirection codes, and uncolored
+for information codes.
+
+```
+:method :url :status :response-time ms - :res[content-length]
+# will output
+GET /dev 200 0.224 ms - 2
+```
+
+##### short
+
+Shorter than default, also including response time.
+
+```
+:remote-addr :remote-user :method :url HTTP/:http-version :status :res[content-length] - :response-time ms
+# will output
+::1 - GET /short HTTP/1.1 200 2 - 0.283 ms
+```
+
+##### tiny
+
+The minimal output.
+
+```
+:method :url :status :res[content-length] - :response-time ms
+# will output
+GET /tiny 200 2 - 0.188 ms
+```
+
+#### Tokens
+
+##### Creating new tokens
+
+To define a token, simply invoke `morgan.token()` with the name and a callback function.
+This callback function is expected to return a string value. The value returned is then
+available as ":type" in this case:
+
+
+
+```js
+morgan.token('type', function (req, res) {
+ return req.headers['content-type'];
+});
+```
+
+Calling `morgan.token()` using the same name as an existing token will overwrite that
+token definition.
+
+The token function is expected to be called with the arguments `req` and `res`, representing
+the HTTP request and HTTP response. Additionally, the token can accept further arguments of
+it's choosing to customize behavior.
+
+##### :date[format]
+
+The current date and time in UTC. The available formats are:
+
+- `clf` for the common log format (`"10/Oct/2000:13:55:36 +0000"`)
+- `iso` for the common ISO 8601 date time format (`2000-10-10T13:55:36.000Z`)
+- `web` for the common RFC 1123 date time format (`Tue, 10 Oct 2000 13:55:36 GMT`)
+
+If no format is given, then the default is `web`.
+
+##### :http-version
+
+The HTTP version of the request.
+
+##### :method
+
+The HTTP method of the request.
+
+##### :pid
+
+The process ID of the Node.js process handling the request.
+
+##### :referrer
+
+The Referrer header of the request. This will use the standard mis-spelled Referer header if exists, otherwise Referrer.
+
+##### :remote-addr
+
+The remote address of the request. This will use `req.ip`, otherwise the standard `req.connection.remoteAddress` value (socket address).
+
+##### :remote-user
+
+The user authenticated as part of Basic auth for the request.
+
+##### :req[header]
+
+The given `header` of the request. If the header is not present, the
+value will be displayed as `"-"` in the log.
+
+##### :res[header]
+
+The given `header` of the response. If the header is not present, the
+value will be displayed as `"-"` in the log.
+
+##### :response-time[digits]
+
+The time between the request coming into `morgan` and when the response
+headers are written, in milliseconds.
+
+The `digits` argument is a number that specifies the number of digits to
+include on the number, defaulting to `3`, which provides microsecond precision.
+
+##### :status
+
+The status code of the response.
+
+If the request/response cycle completes before a response was sent to the
+client (for example, the TCP socket closed prematurely by a client aborting
+the request), then the status will be empty (displayed as `"-"` in the log).
+
+##### :total-time[digits]
+
+The time between the request coming into `morgan` and when the response
+has finished being written out to the connection, in milliseconds.
+
+The `digits` argument is a number that specifies the number of digits to
+include on the number, defaulting to `3`, which provides microsecond precision.
+
+##### :url
+
+The URL of the request. This will use `req.originalUrl` if exists, otherwise `req.url`.
+
+##### :user-agent
+
+The contents of the User-Agent header of the request.
+
+### morgan.compile(format)
+
+Compile a format string into a `format` function for use by `morgan`. A format string
+is a string that represents a single log line and can utilize token syntax.
+Tokens are references by `:token-name`. If tokens accept arguments, they can
+be passed using `[]`, for example: `:token-name[pretty]` would pass the string
+`'pretty'` as an argument to the token `token-name`.
+
+The function returned from `morgan.compile` takes three arguments `tokens`, `req`, and
+`res`, where `tokens` is object with all defined tokens, `req` is the HTTP request and
+`res` is the HTTP response. The function will return a string that will be the log line,
+or `undefined` / `null` to skip logging.
+
+Normally formats are defined using `morgan.format(name, format)`, but for certain
+advanced uses, this compile function is directly available.
+
+## Examples
+
+### express/connect
+
+Sample app that will log all request in the Apache combined format to STDOUT
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+
+var app = express();
+
+app.use(morgan('combined'));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### vanilla http server
+
+Sample app that will log all request in the Apache combined format to STDOUT
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var morgan = require('morgan');
+
+// create "middleware"
+var logger = morgan('combined');
+
+http.createServer(function (req, res) {
+ var done = finalhandler(req, res);
+ logger(req, res, function (err) {
+ if (err) return done(err);
+
+ // respond to request
+ res.setHeader('content-type', 'text/plain');
+ res.end('hello, world!');
+ });
+});
+```
+
+### write logs to a file
+
+#### single file
+
+Sample app that will log all requests in the Apache combined format to the file
+`access.log`.
+
+```js
+var express = require('express');
+var fs = require('fs');
+var morgan = require('morgan');
+var path = require('path');
+
+var app = express();
+
+// create a write stream (in append mode)
+var accessLogStream = fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' });
+
+// setup the logger
+app.use(morgan('combined', { stream: accessLogStream }));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+#### log file rotation
+
+Sample app that will log all requests in the Apache combined format to one log
+file per day in the `log/` directory using the
+[rotating-file-stream module](https://www.npmjs.com/package/rotating-file-stream).
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+var path = require('path');
+var rfs = require('rotating-file-stream'); // version 2.x
+
+var app = express();
+
+// create a rotating write stream
+var accessLogStream = rfs.createStream('access.log', {
+ interval: '1d', // rotate daily
+ path: path.join(__dirname, 'log'),
+});
+
+// setup the logger
+app.use(morgan('combined', { stream: accessLogStream }));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### split / dual logging
+
+The `morgan` middleware can be used as many times as needed, enabling
+combinations like:
+
+- Log entry on request and one on response
+- Log all requests to file, but errors to console
+- ... and more!
+
+Sample app that will log all requests to a file using Apache format, but
+error responses are logged to the console:
+
+```js
+var express = require('express');
+var fs = require('fs');
+var morgan = require('morgan');
+var path = require('path');
+
+var app = express();
+
+// log only 4xx and 5xx responses to console
+app.use(
+ morgan('dev', {
+ skip: function (req, res) {
+ return res.statusCode < 400;
+ },
+ })
+);
+
+// log all requests to access.log
+app.use(
+ morgan('common', {
+ stream: fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' }),
+ })
+);
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### use custom token formats
+
+Sample app that will use custom token formats. This adds an ID to all requests and displays it using the `:id` token.
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+var uuid = require('node-uuid');
+
+morgan.token('id', function getId(req) {
+ return req.id;
+});
+
+var app = express();
+
+app.use(assignId);
+app.use(morgan(':id :method :url :response-time'));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+
+function assignId(req, res, next) {
+ req.id = uuid.v4();
+ next();
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/morgan/master?label=ci
+[ci-url]: https://github.com/expressjs/morgan/actions/workflows/ci.yml
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/morgan/master
+[coveralls-url]: https://coveralls.io/r/expressjs/morgan?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/morgan
+[npm-url]: https://npmjs.org/package/morgan
+[npm-version-image]: https://badgen.net/npm/v/morgan
diff --git a/astro/src/content/resources/fr/middleware/multer.md b/astro/src/content/resources/fr/middleware/multer.md
new file mode 100644
index 0000000000..326786ab3d
--- /dev/null
+++ b/astro/src/content/resources/fr/middleware/multer.md
@@ -0,0 +1,352 @@
+---
+title: Express multer middleware
+module: multer
+---
+
+# Multer [![NPM Version][npm-version-image]][npm-url] [![NPM Downloads][npm-downloads-image]][npm-url] [![Build Status][ci-image]][ci-url] [![Test Coverage][test-image]][test-url] [![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+
+Multer is a node.js middleware for handling `multipart/form-data`, which is primarily used for uploading files. It is written
+on top of [busboy](https://github.com/mscdex/busboy) for maximum efficiency.
+
+**NOTE**: Multer will not process any form which is not multipart (`multipart/form-data`).
+
+## Translations
+
+This README is also available in other languages:
+
+| | |
+| ------------------------------------------------------------------------------ | --------------- |
+| [العربية](https://github.com/expressjs/multer/blob/main/doc/README-ar.md) | Arabic |
+| [简体中文](https://github.com/expressjs/multer/blob/main/doc/README-zh-cn.md) | Chinese |
+| [Français](https://github.com/expressjs/multer/blob/main/doc/README-fr.md) | French |
+| [한국어](https://github.com/expressjs/multer/blob/main/doc/README-ko.md) | Korean |
+| [Português](https://github.com/expressjs/multer/blob/main/doc/README-pt-br.md) | Portuguese (BR) |
+| [Русский язык](https://github.com/expressjs/multer/blob/main/doc/README-ru.md) | Russian |
+| [Español](https://github.com/expressjs/multer/blob/main/doc/README-es.md) | Spanish |
+| [O'zbek tili](https://github.com/expressjs/multer/blob/main/doc/README-uz.md) | Uzbek |
+| [Việt Nam](https://github.com/expressjs/multer/blob/main/doc/README-vi.md) | Vietnamese |
+
+## Installation
+
+```sh
+$ npm install multer
+```
+
+## Usage
+
+Multer adds a `body` object and a `file` or `files` object to the `request` object. The `body` object contains the values of the text fields of the form, the `file` or `files` object contains the files uploaded via the form.
+
+Basic usage example:
+
+Don't forget the `enctype="multipart/form-data"` in your form.
+
+```html
+
+```
+
+```javascript
+const express = require('express');
+const multer = require('multer');
+const upload = multer({ dest: 'uploads/' });
+
+const app = express();
+
+app.post('/profile', upload.single('avatar'), function (req, res, next) {
+ // req.file is the `avatar` file
+ // req.body will hold the text fields, if there were any
+});
+
+app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
+ // req.files is array of `photos` files
+ // req.body will contain the text fields, if there were any
+});
+
+const uploadMiddleware = upload.fields([
+ { name: 'avatar', maxCount: 1 },
+ { name: 'gallery', maxCount: 8 },
+]);
+app.post('/cool-profile', uploadMiddleware, function (req, res, next) {
+ // req.files is an object (String -> Array) where fieldname is the key, and the value is array of files
+ //
+ // e.g.
+ // req.files['avatar'][0] -> File
+ // req.files['gallery'] -> Array
+ //
+ // req.body will contain the text fields, if there were any
+});
+```
+
+In case you need to handle a text-only multipart form, you should use the `.none()` method:
+
+```javascript
+const express = require('express');
+const app = express();
+const multer = require('multer');
+const upload = multer();
+
+app.post('/profile', upload.none(), function (req, res, next) {
+ // req.body contains the text fields
+});
+```
+
+Here's an example on how multer is used in a HTML form. Take special note of the `enctype="multipart/form-data"` and `name="uploaded_file"` fields:
+
+```html
+
+```
+
+Then in your javascript file you would add these lines to access both the file and the body. It is important that you use the `name` field value from the form in your upload function. This tells multer which field on the request it should look for the files in. If these fields aren't the same in the HTML form and on your server, your upload will fail:
+
+```javascript
+const multer = require('multer');
+const upload = multer({ dest: './public/data/uploads/' });
+app.post('/stats', upload.single('uploaded_file'), function (req, res) {
+ // req.file is the name of your file in the form above, here 'uploaded_file'
+ // req.body will hold the text fields, if there were any
+ console.log(req.file, req.body);
+});
+```
+
+## API
+
+### File information
+
+Each file contains the following information:
+
+| Key | Description | Note |
+| -------------- | --------------------------------------------- | --------------- |
+| `fieldname` | Field name specified in the form |
+| `originalname` | Name of the file on the user's computer |
+| `encoding` | Encoding type of the file |
+| `mimetype` | Mime type of the file |
+| `size` | Size of the file in bytes |
+| `destination` | The folder to which the file has been saved | `DiskStorage` |
+| `filename` | The name of the file within the `destination` | `DiskStorage` |
+| `path` | The full path to the uploaded file | `DiskStorage` |
+| `buffer` | A `Buffer` of the entire file | `MemoryStorage` |
+
+### `multer(opts)`
+
+Multer accepts an options object, the most basic of which is the `dest`
+property, which tells Multer where to upload the files. In case you omit the
+options object, the files will be kept in memory and never written to disk.
+
+By default, Multer will rename the files so as to avoid naming conflicts. The
+renaming function can be customized according to your needs.
+
+The following are the options that can be passed to Multer.
+
+| Key | Description |
+| ------------------- | --------------------------------------------------------- |
+| `dest` or `storage` | Where to store the files |
+| `fileFilter` | Function to control which files are accepted |
+| `limits` | Limits of the uploaded data |
+| `preservePath` | Keep the full path of files instead of just the base name |
+
+In an average web app, only `dest` might be required, and configured as shown in
+the following example.
+
+```javascript
+const upload = multer({ dest: 'uploads/' });
+```
+
+If you want more control over your uploads, you'll want to use the `storage`
+option instead of `dest`. Multer ships with storage engines `DiskStorage`
+and `MemoryStorage`; More engines are available from third parties.
+
+#### `.single(fieldname)`
+
+Accept a single file with the name `fieldname`. The single file will be stored
+in `req.file`.
+
+#### `.array(fieldname[, maxCount])`
+
+Accept an array of files, all with the name `fieldname`. Optionally error out if
+more than `maxCount` files are uploaded. The array of files will be stored in
+`req.files`.
+
+#### `.fields(fields)`
+
+Accept a mix of files, specified by `fields`. An object with arrays of files
+will be stored in `req.files`.
+
+`fields` should be an array of objects with `name` and optionally a `maxCount`.
+Example:
+
+```javascript
+[
+ { name: 'avatar', maxCount: 1 },
+ { name: 'gallery', maxCount: 8 },
+];
+```
+
+#### `.none()`
+
+Accept only text fields. If any file upload is made, error with code
+"LIMIT_UNEXPECTED_FILE" will be issued.
+
+#### `.any()`
+
+Accepts all files that comes over the wire. An array of files will be stored in
+`req.files`.
+
+**WARNING:** Make sure that you always handle the files that a user uploads.
+Never add multer as a global middleware since a malicious user could upload
+files to a route that you didn't anticipate. Only use this function on routes
+where you are handling the uploaded files.
+
+### `storage`
+
+#### `DiskStorage`
+
+The disk storage engine gives you full control on storing files to disk.
+
+```javascript
+const storage = multer.diskStorage({
+ destination: function (req, file, cb) {
+ cb(null, '/tmp/my-uploads');
+ },
+ filename: function (req, file, cb) {
+ const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
+ cb(null, file.fieldname + '-' + uniqueSuffix);
+ },
+});
+
+const upload = multer({ storage: storage });
+```
+
+There are two options available, `destination` and `filename`. They are both
+functions that determine where the file should be stored.
+
+`destination` is used to determine within which folder the uploaded files should
+be stored. This can also be given as a `string` (e.g. `'/tmp/uploads'`). If no
+`destination` is given, the operating system's default directory for temporary
+files is used.
+
+**Note:** You are responsible for creating the directory when providing
+`destination` as a function. When passing a string, multer will make sure that
+the directory is created for you.
+
+`filename` is used to determine what the file should be named inside the folder.
+If no `filename` is given, each file will be given a random name that doesn't
+include any file extension.
+
+**Note:** Multer will not append any file extension for you, your function
+should return a filename complete with a file extension.
+
+Each function gets passed both the request (`req`) and some information about
+the file (`file`) to aid with the decision.
+
+Note that `req.body` might not have been fully populated yet. It depends on the
+order that the client transmits fields and files to the server.
+
+For understanding the calling convention used in the callback (needing to pass
+null as the first param), refer to
+[Node.js error handling](https://web.archive.org/web/20220417042018/https://www.joyent.com/node-js/production/design/errors)
+
+#### `MemoryStorage`
+
+The memory storage engine stores the files in memory as `Buffer` objects. It
+doesn't have any options.
+
+```javascript
+const storage = multer.memoryStorage();
+const upload = multer({ storage: storage });
+```
+
+When using memory storage, the file info will contain a field called
+`buffer` that contains the entire file.
+
+**WARNING**: Uploading very large files, or relatively small files in large
+numbers very quickly, can cause your application to run out of memory when
+memory storage is used.
+
+### `limits`
+
+An object specifying the size limits of the following optional properties. Multer passes this object into busboy directly, and the details of the properties can be found on [busboy's page](https://github.com/mscdex/busboy#busboy-methods).
+
+The following integer values are available:
+
+| Key | Description | Default |
+| --------------- | ----------------------------------------------------------------------- | --------- |
+| `fieldNameSize` | Max field name size | 100 bytes |
+| `fieldSize` | Max field value size (in bytes) | 1MB |
+| `fields` | Max number of non-file fields | Infinity |
+| `fileSize` | For multipart forms, the max file size (in bytes) | Infinity |
+| `files` | For multipart forms, the max number of file fields | Infinity |
+| `parts` | For multipart forms, the max number of parts (fields + files) | Infinity |
+| `headerPairs` | For multipart forms, the max number of header key=>value pairs to parse | 2000 |
+
+Specifying the limits can help protect your site against denial of service (DoS) attacks.
+
+### `fileFilter`
+
+Set this to a function to control which files should be uploaded and which
+should be skipped. The function should look like this:
+
+```javascript
+function fileFilter(req, file, cb) {
+ // The function should call `cb` with a boolean
+ // to indicate if the file should be accepted
+
+ // To reject this file pass `false`, like so:
+ cb(null, false);
+
+ // To accept the file pass `true`, like so:
+ cb(null, true);
+
+ // You can always pass an error if something goes wrong:
+ cb(new Error("I don't have a clue!"));
+}
+```
+
+## Error handling
+
+When encountering an error, Multer will delegate the error to Express. You can
+display a nice error page using [the standard express way](http://expressjs.com/guide/error-handling.html).
+
+If you want to catch errors specifically from Multer, you can call the
+middleware function by yourself. Also, if you want to catch only [the Multer errors](https://github.com/expressjs/multer/blob/main/lib/multer-error.js), you can use the `MulterError` class that is attached to the `multer` object itself (e.g. `err instanceof multer.MulterError`).
+
+```javascript
+const multer = require('multer');
+const upload = multer().single('avatar');
+
+app.post('/profile', function (req, res) {
+ upload(req, res, function (err) {
+ if (err instanceof multer.MulterError) {
+ // A Multer error occurred when uploading.
+ } else if (err) {
+ // An unknown error occurred when uploading.
+ }
+
+ // Everything went fine.
+ });
+});
+```
+
+## Custom storage engine
+
+For information on how to build your own storage engine, see [Multer Storage Engine](https://github.com/expressjs/multer/blob/main/StorageEngine.md).
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://github.com/expressjs/multer/actions/workflows/ci.yml/badge.svg
+[ci-url]: https://github.com/expressjs/multer/actions/workflows/ci.yml
+[test-url]: https://coveralls.io/r/expressjs/multer?branch=main
+[test-image]: https://badgen.net/coveralls/c/github/expressjs/multer/main
+[npm-downloads-image]: https://badgen.net/npm/dm/multer
+[npm-url]: https://npmjs.org/package/multer
+[npm-version-image]: https://badgen.net/npm/v/multer
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/multer/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer
diff --git a/astro/src/content/resources/fr/middleware/overview.md b/astro/src/content/resources/fr/middleware/overview.md
new file mode 100755
index 0000000000..46217759e7
--- /dev/null
+++ b/astro/src/content/resources/fr/middleware/overview.md
@@ -0,0 +1,40 @@
+---
+title: Express middleware
+description: Explore a list of Express.js middleware modules maintained by the Express team and the community, including built-in middleware and popular third-party modules.
+module: mw-home
+---
+
+## Express middleware
+
+The Express middleware modules listed here are maintained by the
+[Expressjs team](https://github.com/orgs/expressjs/people).
+
+| Middleware module | Description |
+| ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
+| [body-parser](/en/resources/middleware/body-parser) | Parse HTTP request body. |
+| [compression](/en/resources/middleware/compression) | Compress HTTP responses. |
+| [cookie-parser](/en/resources/middleware/cookie-parser) | Parse cookie header and populate `req.cookies`. See also [cookies](https://github.com/jed/cookies). |
+| [cookie-session](/en/resources/middleware/cookie-session) | Establish cookie-based sessions. |
+| [cors](/en/resources/middleware/cors) | Enable cross-origin resource sharing (CORS) with various options. |
+| [errorhandler](/en/resources/middleware/errorhandler) | Development error-handling/debugging. |
+| [method-override](/en/resources/middleware/method-override) | Override HTTP methods using header. |
+| [morgan](/en/resources/middleware/morgan) | HTTP request logger. |
+| [multer](/en/resources/middleware/multer) | Handle multi-part form data. |
+| [response-time](/en/resources/middleware/response-time) | Record HTTP response time. |
+| [serve-favicon](/en/resources/middleware/serve-favicon) | Serve a favicon. |
+| [serve-index](/en/resources/middleware/serve-index) | Serve directory listing for a given path. |
+| [serve-static](/en/resources/middleware/serve-static) | Serve static files. |
+| [session](/en/resources/middleware/session) | Establish server-based sessions (development only). |
+| [timeout](/en/resources/middleware/timeout) | Set a timeout perioHTTP request processing. |
+| [vhost](/en/resources/middleware/vhost) | Create virtual domains. |
+
+## Additional middleware modules
+
+These are some additional popular middleware modules.
+
+{% include community-caveat.html %}
+
+| Middleware module | Description |
+| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
+| [helmet](https://github.com/helmetjs/helmet) | Helps secure your apps by setting various HTTP headers. |
+| [passport](https://github.com/jaredhanson/passport) | Authentication using "strategies" such as OAuth, OpenID and many others. See [passportjs.org](https://passportjs.org/) for more information. |
diff --git a/astro/src/content/resources/fr/middleware/response-time.md b/astro/src/content/resources/fr/middleware/response-time.md
new file mode 100644
index 0000000000..f911f480f5
--- /dev/null
+++ b/astro/src/content/resources/fr/middleware/response-time.md
@@ -0,0 +1,314 @@
+---
+title: Express response-time middleware
+module: response-time
+---
+
+# compression
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+[![Funding][funding-image]][funding-url]
+
+Node.js compression middleware.
+
+The following compression codings are supported:
+
+- deflate
+- gzip
+- br (brotli)
+
+**Note** Brotli is supported only since Node.js versions v11.7.0 and v10.16.0.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```bash
+$ npm install compression
+```
+
+## API
+
+```js
+var compression = require('compression');
+```
+
+### compression([options])
+
+Returns the compression middleware using the given `options`. The middleware
+will attempt to compress response bodies for all requests that traverse through
+the middleware, based on the given `options`.
+
+This middleware will never compress responses that include a `Cache-Control`
+header with the [`no-transform` directive](https://tools.ietf.org/html/rfc7234#section-5.2.2.4),
+as compressing will transform the body.
+
+#### Options
+
+`compression()` accepts these properties in the options object. In addition to
+those listed below, [zlib](https://nodejs.org/api/zlib.html) options may be
+passed in to the options object or
+[brotli](https://nodejs.org/api/zlib.html#zlib_class_brotlioptions) options.
+
+##### chunkSize
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_CHUNK`, or `16384`.
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### filter
+
+Type: `Function`
+
+A function to decide if the response should be considered for compression.
+This function is called as `filter(req, res)` and is expected to return
+`true` to consider the response for compression, or `false` to not compress
+the response.
+
+The default filter function uses the [compressible](https://www.npmjs.com/package/compressible)
+module to determine if `res.getHeader('Content-Type')` is compressible.
+
+##### level
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_COMPRESSION`, or `-1`
+
+The level of zlib compression to apply to responses. A higher level will result
+in better compression, but will take longer to complete. A lower level will
+result in less compression, but will be much faster.
+
+This is an integer in the range of `0` (no compression) to `9` (maximum
+compression). The special value `-1` can be used to mean the "default
+compression level", which is a default compromise between speed and
+compression (currently equivalent to level 6).
+
+- `-1` Default compression level (also `zlib.constants.Z_DEFAULT_COMPRESSION`).
+- `0` No compression (also `zlib.constants.Z_NO_COMPRESSION`).
+- `1` Fastest compression (also `zlib.constants.Z_BEST_SPEED`).
+- `2`
+- `3`
+- `4`
+- `5`
+- `6` (currently what `zlib.constants.Z_DEFAULT_COMPRESSION` points to).
+- `7`
+- `8`
+- `9` Best compression (also `zlib.constants.Z_BEST_COMPRESSION`).
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### memLevel
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_MEMLEVEL`, or `8`
+
+This specifies how much memory should be allocated for the internal compression
+state and is an integer in the range of `1` (minimum level) and `9` (maximum
+level).
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### brotli
+
+Type: `Object`
+
+This specifies the options for configuring Brotli. See [Node.js documentation](https://nodejs.org/api/zlib.html#class-brotlioptions) for a complete list of available options.
+
+##### strategy
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_STRATEGY`
+
+This is used to tune the compression algorithm. This value only affects the
+compression ratio, not the correctness of the compressed output, even if it
+is not set appropriately.
+
+- `zlib.constants.Z_DEFAULT_STRATEGY` Use for normal data.
+- `zlib.constants.Z_FILTERED` Use for data produced by a filter (or predictor).
+ Filtered data consists mostly of small values with a somewhat random
+ distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect is to force more Huffman coding and less
+ string matching; it is somewhat intermediate between `zlib.constants.Z_DEFAULT_STRATEGY`
+ and `zlib.constants.Z_HUFFMAN_ONLY`.
+- `zlib.constants.Z_FIXED` Use to prevent the use of dynamic Huffman codes, allowing
+ for a simpler decoder for special applications.
+- `zlib.constants.Z_HUFFMAN_ONLY` Use to force Huffman encoding only (no string match).
+- `zlib.constants.Z_RLE` Use to limit match distances to one (run-length encoding).
+ This is designed to be almost as fast as `zlib.constants.Z_HUFFMAN_ONLY`, but give
+ better compression for PNG image data.
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### threshold
+
+Type: `Number` or `String`
+Default: `1kb`
+
+The byte threshold for the response body size before compression is considered
+for the response. This is a number of bytes or any string
+accepted by the [bytes](https://www.npmjs.com/package/bytes) module.
+
+**Note** this is only an advisory setting; if the response size cannot be determined
+at the time the response headers are written, then it is assumed the response is
+_over_ the threshold. To guarantee the response size can be determined, be sure
+set a `Content-Length` response header.
+
+##### windowBits
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_WINDOWBITS`, or `15`
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### enforceEncoding
+
+Type: `String`
+Default: `identity`
+
+This is the default encoding to use when the client does not specify an encoding in the request's [Accept-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) header.
+
+#### .filter
+
+The default `filter` function. This is used to construct a custom filter
+function that is an extension of the default function.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+app.use(compression({ filter: shouldCompress }));
+
+function shouldCompress(req, res) {
+ if (req.headers['x-no-compression']) {
+ // don't compress responses with this request header
+ return false;
+ }
+
+ // fallback to standard filter function
+ return compression.filter(req, res);
+}
+```
+
+### res.flush
+
+This module adds a `res.flush()` method to force the partially-compressed
+response to be flushed to the client.
+
+## Examples
+
+### express
+
+When using this module with express, simply `app.use` the module as
+high as you like. Requests that pass through the middleware will be compressed.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress all responses
+app.use(compression());
+
+// add all routes
+```
+
+### Node.js HTTP server
+
+```js
+var compression = require('compression')({ threshold: 0 });
+var http = require('http');
+
+function createServer(fn) {
+ return http.createServer(function (req, res) {
+ compression(req, res, function (err) {
+ if (err) {
+ res.statusCode = err.status || 500;
+ res.end(err.message);
+ return;
+ }
+
+ fn(req, res);
+ });
+ });
+}
+
+var server = createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello world!');
+});
+
+server.listen(3000, () => {
+ console.log('> Listening at http://localhost:3000');
+});
+```
+
+### Server-Sent Events
+
+Because of the nature of compression this module does not work out of the box
+with server-sent events. To compress content, a window of the output needs to
+be buffered up in order to get good compression. Typically when using server-sent
+events, there are certain block of data that need to reach the client.
+
+You can achieve this by calling `res.flush()` when you need the data written to
+actually make it to the client.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress responses
+app.use(compression());
+
+// server-sent event stream
+app.get('/events', function (req, res) {
+ res.setHeader('Content-Type', 'text/event-stream');
+ res.setHeader('Cache-Control', 'no-cache');
+
+ // send a ping approx every 2 seconds
+ var timer = setInterval(function () {
+ res.write('data: ping\n\n');
+
+ // !!! this is the important part
+ res.flush();
+ }, 2000);
+
+ res.on('close', function () {
+ clearInterval(timer);
+ });
+});
+```
+
+## Contributing
+
+The Express.js project welcomes all constructive contributions. Contributions take many forms,
+from code for bug fixes and enhancements, to additions and fixes to documentation, additional
+tests, triaging incoming pull requests and issues, and more!
+
+See the [Contributing Guide](https://github.com/expressjs/express/blob/master/Contributing.md) for more technical details on contributing.
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://badgen.net/npm/v/compression
+[npm-url]: https://npmjs.org/package/compression
+[downloads-image]: https://badgen.net/npm/dm/compression
+[downloads-url]: https://npmcharts.com/compare/compression?minimal=true
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/compression/master?label=CI
+[github-actions-ci-url]: https://github.com/expressjs/compression/actions?query=workflow%3Aci
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/compression/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/compression
+[funding-url]: https://opencollective.com/express
+[funding-image]: https://badgen.net/badge/icon/sponsor/pink?icon=github&label=Open%20Collective
diff --git a/astro/src/content/resources/fr/middleware/serve-favicon.md b/astro/src/content/resources/fr/middleware/serve-favicon.md
new file mode 100644
index 0000000000..7a77865c6b
--- /dev/null
+++ b/astro/src/content/resources/fr/middleware/serve-favicon.md
@@ -0,0 +1,156 @@
+---
+title: Express serve-favicon middleware
+module: serve-favicon
+---
+
+# serve-index
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Linux Build Status][ci-image]][ci-url]
+[![Windows Build][appveyor-image]][appveyor-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+Serves pages that contain directory listings for a given path.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-index
+```
+
+## API
+
+```js
+var serveIndex = require('serve-index');
+```
+
+### serveIndex(path, options)
+
+Returns middlware that serves an index of the directory in the given `path`.
+
+The `path` is based off the `req.url` value, so a `req.url` of `'/some/dir`
+with a `path` of `'public'` will look at `'public/some/dir'`. If you are using
+something like `express`, you can change the URL "base" with `app.use` (see
+the express example).
+
+#### Options
+
+Serve index accepts these properties in the options object.
+
+##### filter
+
+Apply this filter function to files. Defaults to `false`. The `filter` function
+is called for each file, with the signature `filter(filename, index, files, dir)`
+where `filename` is the name of the file, `index` is the array index, `files` is
+the array of files and `dir` is the absolute path the file is located (and thus,
+the directory the listing is for).
+
+##### hidden
+
+Display hidden (dot) files. Defaults to `false`.
+
+##### icons
+
+Display icons. Defaults to `false`.
+
+##### stylesheet
+
+Optional path to a CSS stylesheet. Defaults to a built-in stylesheet.
+
+##### template
+
+Optional path to an HTML template or a function that will render a HTML
+string. Defaults to a built-in template.
+
+When given a string, the string is used as a file path to load and then the
+following tokens are replaced in templates:
+
+- `{directory}` with the name of the directory.
+- `{files}` with the HTML of an unordered list of file links.
+- `{linked-path}` with the HTML of a link to the directory.
+- `{style}` with the specified stylesheet and embedded images.
+
+When given as a function, the function is called as `template(locals, callback)`
+and it needs to invoke `callback(error, htmlString)`. The following are the
+provided locals:
+
+- `directory` is the directory being displayed (where `/` is the root).
+- `displayIcons` is a Boolean for if icons should be rendered or not.
+- `fileList` is a sorted array of files in the directory. The array contains
+ objects with the following properties:
+ - `name` is the relative name for the file.
+ - `stat` is a `fs.Stats` object for the file.
+- `path` is the full filesystem path to `directory`.
+- `style` is the default stylesheet or the contents of the `stylesheet` option.
+- `viewName` is the view name provided by the `view` option.
+
+##### view
+
+Display mode. `tiles` and `details` are available. Defaults to `tiles`.
+
+## Examples
+
+### Serve directory indexes with vanilla node.js http server
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var serveIndex = require('serve-index');
+var serveStatic = require('serve-static');
+
+// Serve directory indexes for public/ftp folder (with icons)
+var index = serveIndex('public/ftp', { icons: true });
+
+// Serve up public/ftp folder files
+var serve = serveStatic('public/ftp');
+
+// Create server
+var server = http.createServer(function onRequest(req, res) {
+ var done = finalhandler(req, res);
+ serve(req, res, function onNext(err) {
+ if (err) return done(err);
+ index(req, res, done);
+ });
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve directory indexes with express
+
+```js
+var express = require('express');
+var serveIndex = require('serve-index');
+
+var app = express();
+
+// Serve URLs like /ftp/thing as public/ftp/thing
+// The express.static serves the file contents
+// The serveIndex is this module serving the directory
+app.use('/ftp', express.static('public/ftp'), serveIndex('public/ftp', { icons: true }));
+
+// Listen
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE). The [Silk](http://www.famfamfam.com/lab/icons/silk/) icons
+are created by/copyright of [FAMFAMFAM](http://www.famfamfam.com/).
+
+[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/serve-index/master.svg?label=windows
+[appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index
+[ci-image]: https://badgen.net/github/checks/expressjs/serve-index/master?label=ci
+[ci-url]: https://github.com/expressjs/serve-index/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/serve-index/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-index?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/serve-index.svg
+[downloads-url]: https://npmjs.org/package/serve-index
+[npm-image]: https://img.shields.io/npm/v/serve-index.svg
+[npm-url]: https://npmjs.org/package/serve-index
diff --git a/astro/src/content/resources/fr/middleware/serve-index.md b/astro/src/content/resources/fr/middleware/serve-index.md
new file mode 100644
index 0000000000..da03cf94b2
--- /dev/null
+++ b/astro/src/content/resources/fr/middleware/serve-index.md
@@ -0,0 +1,156 @@
+---
+title: Express serve-index middleware
+module: serve-index
+---
+
+# serve-index
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Linux Build Status][ci-image]][ci-url]
+[![Windows Build][appveyor-image]][appveyor-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+Serves pages that contain directory listings for a given path.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-index
+```
+
+## API
+
+```js
+var serveIndex = require('serve-index');
+```
+
+### serveIndex(path, options)
+
+Returns middlware that serves an index of the directory in the given `path`.
+
+The `path` is based off the `req.url` value, so a `req.url` of `'/some/dir`
+with a `path` of `'public'` will look at `'public/some/dir'`. If you are using
+something like `express`, you can change the URL "base" with `app.use` (see
+the express example).
+
+#### Options
+
+Serve index accepts these properties in the options object.
+
+##### filter
+
+Apply this filter function to files. Defaults to `false`. The `filter` function
+is called for each file, with the signature `filter(filename, index, files, dir)`
+where `filename` is the name of the file, `index` is the array index, `files` is
+the array of files and `dir` is the absolute path the file is located (and thus,
+the directory the listing is for).
+
+##### hidden
+
+Display hidden (dot) files. Defaults to `false`.
+
+##### icons
+
+Display icons. Defaults to `false`.
+
+##### stylesheet
+
+Optional path to a CSS stylesheet. Defaults to a built-in stylesheet.
+
+##### template
+
+Optional path to an HTML template or a function that will render a HTML
+string. Defaults to a built-in template.
+
+When given a string, the string is used as a file path to load and then the
+following tokens are replaced in templates:
+
+- `{directory}` with the name of the directory.
+- `{files}` with the HTML of an unordered list of file links.
+- `{linked-path}` with the HTML of a link to the directory.
+- `{style}` with the specified stylesheet and embedded images.
+
+When given as a function, the function is called as `template(locals, callback)`
+and it needs to invoke `callback(error, htmlString)`. The following are the
+provided locals:
+
+- `directory` is the directory being displayed (where `/` is the root).
+- `displayIcons` is a Boolean for if icons should be rendered or not.
+- `fileList` is a sorted array of files in the directory. The array contains
+ objects with the following properties:
+ - `name` is the relative name for the file.
+ - `stat` is a `fs.Stats` object for the file.
+- `path` is the full filesystem path to `directory`.
+- `style` is the default stylesheet or the contents of the `stylesheet` option.
+- `viewName` is the view name provided by the `view` option.
+
+##### view
+
+Display mode. `tiles` and `details` are available. Defaults to `tiles`.
+
+## Examples
+
+### Serve directory indexes with vanilla node.js http server
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var serveIndex = require('serve-index');
+var serveStatic = require('serve-static');
+
+// Serve directory indexes for public/ftp folder (with icons)
+var index = serveIndex('public/ftp', { icons: true });
+
+// Serve up public/ftp folder files
+var serve = serveStatic('public/ftp');
+
+// Create server
+var server = http.createServer(function onRequest(req, res) {
+ var done = finalhandler(req, res);
+ serve(req, res, function onNext(err) {
+ if (err) return done(err);
+ index(req, res, done);
+ });
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve directory indexes with express
+
+```js
+var express = require('express');
+var serveIndex = require('serve-index');
+
+var app = express();
+
+// Serve URLs like /ftp/thing as public/ftp/thing
+// The express.static serves the file contents
+// The serveIndex is this module serving the directory
+app.use('/ftp', express.static('public/ftp'), serveIndex('public/ftp', { icons: true }));
+
+// Listen
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE). The [Silk](http://www.famfamfam.com/lab/icons/silk/) icons
+are created by/copyright of [FAMFAMFAM](http://www.famfamfam.com/).
+
+[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/serve-index/master.svg?label=windows
+[appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index
+[ci-image]: https://badgen.net/github/checks/expressjs/serve-index/master?label=ci
+[ci-url]: https://github.com/expressjs/serve-index/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/serve-index/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-index?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/serve-index.svg
+[downloads-url]: https://npmjs.org/package/serve-index
+[npm-image]: https://img.shields.io/npm/v/serve-index.svg
+[npm-url]: https://npmjs.org/package/serve-index
diff --git a/astro/src/content/resources/fr/middleware/serve-static.md b/astro/src/content/resources/fr/middleware/serve-static.md
new file mode 100644
index 0000000000..b048165d7b
--- /dev/null
+++ b/astro/src/content/resources/fr/middleware/serve-static.md
@@ -0,0 +1,260 @@
+---
+title: Express serve-static middleware
+module: serve-static
+---
+
+# serve-static
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![CI][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-static
+```
+
+## API
+
+```js
+const serveStatic = require('serve-static');
+```
+
+### serveStatic(root, options)
+
+Create a new middleware function to serve files from within a given root
+directory. The file to serve will be determined by combining `req.url`
+with the provided root directory. When a file is not found, instead of
+sending a 404 response, this module will instead call `next()` to move on
+to the next middleware, allowing for stacking and fall-backs.
+
+#### Options
+
+##### acceptRanges
+
+Enable or disable accepting ranged requests, defaults to true.
+Disabling this will not send `Accept-Ranges` and ignore the contents
+of the `Range` request header.
+
+##### cacheControl
+
+Enable or disable setting `Cache-Control` response header, defaults to
+true. Disabling this will ignore the `immutable` and `maxAge` options.
+
+##### dotfiles
+
+Set how "dotfiles" are treated when encountered. A dotfile is a file
+or directory that begins with a dot ("."). Note this check is done on
+the path itself without checking if the path actually exists on the
+disk. If `root` is specified, only the dotfiles above the root are
+checked (i.e. the root itself can be within a dotfile when set
+to "deny").
+
+- `'allow'` No special treatment for dotfiles.
+- `'deny'` Deny a request for a dotfile and 403/`next()`.
+- `'ignore'` Pretend like the dotfile does not exist and 404/`next()`.
+
+The default value is `'ignore'`.
+
+##### etag
+
+Enable or disable etag generation, defaults to true.
+
+##### extensions
+
+Set file extension fallbacks. When set, if a file is not found, the given
+extensions will be added to the file name and search for. The first that
+exists will be served. Example: `['html', 'htm']`.
+
+The default value is `false`.
+
+##### fallthrough
+
+Set the middleware to have client errors fall-through as just unhandled
+requests, otherwise forward a client error. The difference is that client
+errors like a bad request or a request to a non-existent file will cause
+this middleware to simply `next()` to your next middleware when this value
+is `true`. When this value is `false`, these errors (even 404s), will invoke
+`next(err)`.
+
+Typically `true` is desired such that multiple physical directories can be
+mapped to the same web address or for routes to fill in non-existent files.
+
+The value `false` can be used if this middleware is mounted at a path that
+is designed to be strictly a single file system directory, which allows for
+short-circuiting 404s for less overhead. This middleware will also reply to
+all methods.
+
+The default value is `true`.
+
+##### immutable
+
+Enable or disable the `immutable` directive in the `Cache-Control` response
+header, defaults to `false`. If set to `true`, the `maxAge` option should
+also be specified to enable caching. The `immutable` directive will prevent
+supported clients from making conditional requests during the life of the
+`maxAge` option to check if the file has changed.
+
+##### index
+
+By default this module will send "index.html" files in response to a request
+on a directory. To disable this set `false` or to supply a new index pass a
+string or an array in preferred order.
+
+##### lastModified
+
+Enable or disable `Last-Modified` header, defaults to true. Uses the file
+system's last modified value.
+
+##### maxAge
+
+Provide a max-age in milliseconds for http caching, defaults to 0. This
+can also be a string accepted by the [ms](https://www.npmjs.org/package/ms#readme)
+module.
+
+##### redirect
+
+Redirect to trailing "/" when the pathname is a dir. Defaults to `true`.
+
+##### setHeaders
+
+Function to set custom headers on response. Alterations to the headers need to
+occur synchronously. The function is called as `fn(res, path, stat)`, where
+the arguments are:
+
+- `res` the response object
+- `path` the file path that is being sent
+- `stat` the stat object of the file that is being sent
+
+## Examples
+
+### Serve files with vanilla node.js http server
+
+```js
+const finalhandler = require('finalhandler');
+const http = require('http');
+const serveStatic = require('serve-static');
+
+// Serve up public/ftp folder
+const serve = serveStatic('public/ftp', { index: ['index.html', 'index.htm'] });
+
+// Create server
+const server = http.createServer((req, res) => {
+ serve(req, res, finalhandler(req, res));
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve all files as downloads
+
+```js
+const contentDisposition = require('content-disposition');
+const finalhandler = require('finalhandler');
+const http = require('http');
+const serveStatic = require('serve-static');
+
+// Serve up public/ftp folder
+const serve = serveStatic('public/ftp', {
+ index: false,
+ setHeaders: setHeaders,
+});
+
+// Set header to force download
+function setHeaders(res, path) {
+ res.setHeader('Content-Disposition', contentDisposition(path));
+}
+
+// Create server
+const server = http.createServer((req, res) => {
+ serve(req, res, finalhandler(req, res));
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serving using express
+
+#### Simple
+
+This is a simple example of using Express.
+
+```js
+const express = require('express');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(serveStatic('public/ftp', { index: ['default.html', 'default.htm'] }));
+app.listen(3000);
+```
+
+#### Multiple roots
+
+This example shows a simple way to search through multiple directories.
+Files are searched for in `public-optimized/` first, then `public/` second
+as a fallback.
+
+```js
+const express = require('express');
+const path = require('path');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(serveStatic(path.join(__dirname, 'public-optimized')));
+app.use(serveStatic(path.join(__dirname, 'public')));
+app.listen(3000);
+```
+
+#### Different settings for paths
+
+This example shows how to set a different max age depending on the served
+file. In this example, HTML files are not cached, while everything else
+is for 1 day.
+
+```js
+const express = require('express');
+const path = require('path');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(
+ serveStatic(path.join(__dirname, 'public'), {
+ maxAge: '1d',
+ setHeaders: setCustomCacheControl,
+ })
+);
+
+app.listen(3000);
+
+function setCustomCacheControl(res, file) {
+ if (path.extname(file) === '.html') {
+ // Custom Cache-Control for HTML files
+ res.setHeader('Cache-Control', 'public, max-age=0');
+ }
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/serve-static/master
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-static?branch=master
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/serve-static/master?label=linux
+[github-actions-ci-url]: https://github.com/expressjs/serve-static/actions/workflows/ci.yml
+[node-image]: https://badgen.net/npm/node/serve-static
+[node-url]: https://nodejs.org/en/download/
+[npm-downloads-image]: https://badgen.net/npm/dm/serve-static
+[npm-url]: https://npmjs.org/package/serve-static
+[npm-version-image]: https://badgen.net/npm/v/serve-static
diff --git a/astro/src/content/resources/fr/middleware/session.md b/astro/src/content/resources/fr/middleware/session.md
new file mode 100644
index 0000000000..90f3837a42
--- /dev/null
+++ b/astro/src/content/resources/fr/middleware/session.md
@@ -0,0 +1,1046 @@
+---
+title: Express session middleware
+module: session
+---
+
+# express-session
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][node-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install express-session
+```
+
+## API
+
+```js
+var session = require('express-session');
+```
+
+### session(options)
+
+Create a session middleware with the given `options`.
+
+**Note** Session data is _not_ saved in the cookie itself, just the session ID.
+Session data is stored server-side.
+
+**Note** Since version 1.5.0, the [`cookie-parser` middleware](https://www.npmjs.com/package/cookie-parser)
+no longer needs to be used for this module to work. This module now directly reads
+and writes cookies on `req`/`res`. Using `cookie-parser` may result in issues
+if the `secret` is not the same between this module and `cookie-parser`.
+
+**Warning** The default server-side session storage, `MemoryStore`, is _purposely_
+not designed for a production environment. It will leak memory under most
+conditions, does not scale past a single process, and is meant for debugging and
+developing.
+
+For a list of stores, see [compatible session stores](#compatible-session-stores).
+
+#### Options
+
+`express-session` accepts these properties in the options object.
+
+##### cookie
+
+Settings object for the session ID cookie. The default value is
+`{ path: '/', httpOnly: true, secure: false, maxAge: null }`.
+
+The following are options that can be set in this object.
+
+##### cookie.domain
+
+Specifies the value for the `Domain` `Set-Cookie` attribute. By default, no domain
+is set, and most clients will consider the cookie to apply to only the current
+domain.
+
+##### cookie.expires
+
+Specifies the `Date` object to be the value for the `Expires` `Set-Cookie` attribute.
+By default, no expiration is set, and most clients will consider this a
+"non-persistent cookie" and will delete it on a condition like exiting a web browser
+application.
+
+**Note** If both `expires` and `maxAge` are set in the options, then the last one
+defined in the object is what is used.
+
+**Note** The `expires` option should not be set directly; instead only use the `maxAge`
+option.
+
+##### cookie.httpOnly
+
+Specifies the `boolean` value for the `HttpOnly` `Set-Cookie` attribute. When truthy,
+the `HttpOnly` attribute is set, otherwise it is not. By default, the `HttpOnly`
+attribute is set.
+
+**Note** be careful when setting this to `true`, as compliant clients will not allow
+client-side JavaScript to see the cookie in `document.cookie`.
+
+##### cookie.maxAge
+
+Specifies the `number` (in milliseconds) to use when calculating the `Expires`
+`Set-Cookie` attribute. This is done by taking the current server time and adding
+`maxAge` milliseconds to the value to calculate an `Expires` datetime. By default,
+no maximum age is set.
+
+**Note** If both `expires` and `maxAge` are set in the options, then the last one
+defined in the object is what is used.
+
+##### cookie.partitioned
+
+Specifies the `boolean` value for the [`Partitioned` `Set-Cookie`](rfc-cutler-httpbis-partitioned-cookies)
+attribute. When truthy, the `Partitioned` attribute is set, otherwise it is not.
+By default, the `Partitioned` attribute is not set.
+
+**Note** This is an attribute that has not yet been fully standardized, and may
+change in the future. This also means many clients may ignore this attribute until
+they understand it.
+
+More information about can be found in [the proposal](https://github.com/privacycg/CHIPS).
+
+##### cookie.path
+
+Specifies the value for the `Path` `Set-Cookie`. By default, this is set to `'/'`, which
+is the root path of the domain.
+
+##### cookie.priority
+
+Specifies the `string` to be the value for the [`Priority` `Set-Cookie` attribute][rfc-west-cookie-priority-00-4.1].
+
+- `'low'` will set the `Priority` attribute to `Low`.
+- `'medium'` will set the `Priority` attribute to `Medium`, the default priority when not set.
+- `'high'` will set the `Priority` attribute to `High`.
+
+More information about the different priority levels can be found in
+[the specification][rfc-west-cookie-priority-00-4.1].
+
+**Note** This is an attribute that has not yet been fully standardized, and may change in the future.
+This also means many clients may ignore this attribute until they understand it.
+
+##### cookie.sameSite
+
+Specifies the `boolean` or `string` to be the value for the `SameSite` `Set-Cookie` attribute.
+By default, this is `false`.
+
+- `true` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
+- `false` will not set the `SameSite` attribute.
+- `'lax'` will set the `SameSite` attribute to `Lax` for lax same site enforcement.
+- `'none'` will set the `SameSite` attribute to `None` for an explicit cross-site cookie.
+- `'strict'` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
+
+More information about the different enforcement levels can be found in
+[the specification][rfc-6265bis-03-4.1.2.7].
+
+**Note** This is an attribute that has not yet been fully standardized, and may change in
+the future. This also means many clients may ignore this attribute until they understand it.
+
+**Note** There is a [draft spec](https://tools.ietf.org/html/draft-west-cookie-incrementalism-01)
+that requires that the `Secure` attribute be set to `true` when the `SameSite` attribute has been
+set to `'none'`. Some web browsers or other clients may be adopting this specification.
+
+##### cookie.secure
+
+Specifies the `boolean` value for the `Secure` `Set-Cookie` attribute. When truthy,
+the `Secure` attribute is set, otherwise it is not. By default, the `Secure`
+attribute is not set.
+
+**Note** be careful when setting this to `true`, as compliant clients will not send
+the cookie back to the server in the future if the browser does not have an HTTPS
+connection.
+
+Please note that `secure: true` is a **recommended** option. However, it requires
+an https-enabled website, i.e., HTTPS is necessary for secure cookies. If `secure`
+is set, and you access your site over HTTP, the cookie will not be set. If you
+have your node.js behind a proxy and are using `secure: true`, you need to set
+"trust proxy" in express:
+
+```js
+var app = express();
+app.set('trust proxy', 1); // trust first proxy
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ cookie: { secure: true },
+ })
+);
+```
+
+For using secure cookies in production, but allowing for testing in development,
+the following is an example of enabling this setup based on `NODE_ENV` in express:
+
+```js
+var app = express();
+var sess = {
+ secret: 'keyboard cat',
+ cookie: {},
+};
+
+if (app.get('env') === 'production') {
+ app.set('trust proxy', 1); // trust first proxy
+ sess.cookie.secure = true; // serve secure cookies
+}
+
+app.use(session(sess));
+```
+
+The `cookie.secure` option can also be set to the special value `'auto'` to have
+this setting automatically match the determined security of the connection. Be
+careful when using this setting if the site is available both as HTTP and HTTPS,
+as once the cookie is set on HTTPS, it will no longer be visible over HTTP. This
+is useful when the Express `"trust proxy"` setting is properly setup to simplify
+development vs production configuration.
+
+##### genid
+
+Function to call to generate a new session ID. Provide a function that returns
+a string that will be used as a session ID. The function is given `req` as the
+first argument if you want to use some value attached to `req` when generating
+the ID.
+
+The default value is a function which uses the `uid-safe` library to generate IDs.
+
+**NOTE** be careful to generate unique IDs so your sessions do not conflict.
+
+```js
+app.use(
+ session({
+ genid: function (req) {
+ return genuuid(); // use UUIDs for session IDs
+ },
+ secret: 'keyboard cat',
+ })
+);
+```
+
+##### name
+
+The name of the session ID cookie to set in the response (and read from in the
+request).
+
+The default value is `'connect.sid'`.
+
+**Note** if you have multiple apps running on the same hostname (this is just
+the name, i.e. `localhost` or `127.0.0.1`; different schemes and ports do not
+name a different hostname), then you need to separate the session cookies from
+each other. The simplest method is to simply set different `name`s per app.
+
+##### proxy
+
+Trust the reverse proxy when setting secure cookies (via the "X-Forwarded-Proto"
+header).
+
+The default value is `undefined`.
+
+- `true` The "X-Forwarded-Proto" header will be used.
+- `false` All headers are ignored and the connection is considered secure only
+ if there is a direct TLS/SSL connection.
+- `undefined` Uses the "trust proxy" setting from express
+
+##### resave
+
+Forces the session to be saved back to the session store, even if the session
+was never modified during the request. Depending on your store this may be
+necessary, but it can also create race conditions where a client makes two
+parallel requests to your server and changes made to the session in one
+request may get overwritten when the other request ends, even if it made no
+changes (this behavior also depends on what store you're using).
+
+The default value is `true`, but using the default has been deprecated,
+as the default will change in the future. Please research into this setting
+and choose what is appropriate to your use-case. Typically, you'll want
+`false`.
+
+How do I know if this is necessary for my store? The best way to know is to
+check with your store if it implements the `touch` method. If it does, then
+you can safely set `resave: false`. If it does not implement the `touch`
+method and your store sets an expiration date on stored sessions, then you
+likely need `resave: true`.
+
+##### rolling
+
+Force the session identifier cookie to be set on every response. The expiration
+is reset to the original [`maxAge`](#cookiemaxage), resetting the expiration
+countdown.
+
+The default value is `false`.
+
+With this enabled, the session identifier cookie will expire in
+[`maxAge`](#cookiemaxage) since the last response was sent instead of in
+[`maxAge`](#cookiemaxage) since the session was last modified by the server.
+
+This is typically used in conjunction with short, non-session-length
+[`maxAge`](#cookiemaxage) values to provide a quick timeout of the session data
+with reduced potential of it occurring during on going server interactions.
+
+**Note** When this option is set to `true` but the `saveUninitialized` option is
+set to `false`, the cookie will not be set on a response with an uninitialized
+session. This option only modifies the behavior when an existing session was
+loaded for the request.
+
+##### saveUninitialized
+
+Forces a session that is "uninitialized" to be saved to the store. A session is
+uninitialized when it is new but not modified. Choosing `false` is useful for
+implementing login sessions, reducing server storage usage, or complying with
+laws that require permission before setting a cookie. Choosing `false` will also
+help with race conditions where a client makes multiple parallel requests
+without a session.
+
+The default value is `true`, but using the default has been deprecated, as the
+default will change in the future. Please research into this setting and
+choose what is appropriate to your use-case.
+
+**Note** if you are using Session in conjunction with PassportJS, Passport
+will add an empty Passport object to the session for use after a user is
+authenticated, which will be treated as a modification to the session, causing
+it to be saved. _This has been fixed in PassportJS 0.3.0_
+
+##### secret
+
+**Required option**
+
+This is the secret used to sign the session ID cookie. The secret can be any type
+of value that is supported by Node.js `crypto.createHmac` (like a string or a
+`Buffer`). This can be either a single secret, or an array of multiple secrets. If
+an array of secrets is provided, only the first element will be used to sign the
+session ID cookie, while all the elements will be considered when verifying the
+signature in requests. The secret itself should be not easily parsed by a human and
+would best be a random set of characters. A best practice may include:
+
+- The use of environment variables to store the secret, ensuring the secret itself
+ does not exist in your repository.
+- Periodic updates of the secret, while ensuring the previous secret is in the
+ array.
+
+Using a secret that cannot be guessed will reduce the ability to hijack a session to
+only guessing the session ID (as determined by the `genid` option).
+
+Changing the secret value will invalidate all existing sessions. In order to rotate
+the secret without invalidating sessions, provide an array of secrets, with the new
+secret as first element of the array, and including previous secrets as the later
+elements.
+
+**Note** HMAC-256 is used to sign the session ID. For this reason, the secret should
+contain at least 32 bytes of entropy.
+
+##### store
+
+The session store instance, defaults to a new `MemoryStore` instance.
+
+##### unset
+
+Control the result of unsetting `req.session` (through `delete`, setting to `null`,
+etc.).
+
+The default value is `'keep'`.
+
+- `'destroy'` The session will be destroyed (deleted) when the response ends.
+- `'keep'` The session in the store will be kept, but modifications made during
+ the request are ignored and not saved.
+
+### req.session
+
+To store or access session data, simply use the request property `req.session`,
+which is (generally) serialized as JSON by the store, so nested objects
+are typically fine. For example below is a user-specific view counter:
+
+```js
+// Use the session middleware
+app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 } }));
+
+// Access the session as req.session
+app.get('/', function (req, res, next) {
+ if (req.session.views) {
+ req.session.views++;
+ res.setHeader('Content-Type', 'text/html');
+ res.write('views: ' + req.session.views + '
');
+ res.write('expires in: ' + req.session.cookie.maxAge / 1000 + 's
');
+ res.end();
+ } else {
+ req.session.views = 1;
+ res.end('welcome to the session demo. refresh!');
+ }
+});
+```
+
+#### Session.regenerate(callback)
+
+To regenerate the session simply invoke the method. Once complete,
+a new SID and `Session` instance will be initialized at `req.session`
+and the `callback` will be invoked.
+
+```js
+req.session.regenerate(function (err) {
+ // will have a new session here
+});
+```
+
+#### Session.destroy(callback)
+
+Destroys the session and will unset the `req.session` property.
+Once complete, the `callback` will be invoked.
+
+```js
+req.session.destroy(function (err) {
+ // cannot access session here
+});
+```
+
+#### Session.reload(callback)
+
+Reloads the session data from the store and re-populates the
+`req.session` object. Once complete, the `callback` will be invoked.
+
+```js
+req.session.reload(function (err) {
+ // session updated
+});
+```
+
+#### Session.save(callback)
+
+Save the session back to the store, replacing the contents on the store with the
+contents in memory (though a store may do something else--consult the store's
+documentation for exact behavior).
+
+This method is automatically called at the end of the HTTP response if the
+session data has been altered (though this behavior can be altered with various
+options in the middleware constructor). Because of this, typically this method
+does not need to be called.
+
+There are some cases where it is useful to call this method, for example,
+redirects, long-lived requests or in WebSockets.
+
+```js
+req.session.save(function (err) {
+ // session saved
+});
+```
+
+#### Session.touch()
+
+Updates the `.maxAge` property. Typically this is
+not necessary to call, as the session middleware does this for you.
+
+### req.session.id
+
+Each session has a unique ID associated with it. This property is an
+alias of [`req.sessionID`](#reqsessionid-1) and cannot be modified.
+It has been added to make the session ID accessible from the `session`
+object.
+
+### req.session.cookie
+
+Each session has a unique cookie object accompany it. This allows
+you to alter the session cookie per visitor. For example we can
+set `req.session.cookie.expires` to `false` to enable the cookie
+to remain for only the duration of the user-agent.
+
+#### Cookie.maxAge
+
+Alternatively `req.session.cookie.maxAge` will return the time
+remaining in milliseconds, which we may also re-assign a new value
+to adjust the `.expires` property appropriately. The following
+are essentially equivalent
+
+```js
+var hour = 3600000;
+req.session.cookie.expires = new Date(Date.now() + hour);
+req.session.cookie.maxAge = hour;
+```
+
+For example when `maxAge` is set to `60000` (one minute), and 30 seconds
+has elapsed it will return `30000` until the current request has completed,
+at which time `req.session.touch()` is called to reset
+`req.session.cookie.maxAge` to its original value.
+
+```js
+req.session.cookie.maxAge; // => 30000
+```
+
+#### Cookie.originalMaxAge
+
+The `req.session.cookie.originalMaxAge` property returns the original
+`maxAge` (time-to-live), in milliseconds, of the session cookie.
+
+### req.sessionID
+
+To get the ID of the loaded session, access the request property
+`req.sessionID`. This is simply a read-only value set when a session
+is loaded/created.
+
+## Session Store Implementation
+
+Every session store _must_ be an `EventEmitter` and implement specific
+methods. The following methods are the list of **required**, **recommended**,
+and **optional**.
+
+- Required methods are ones that this module will always call on the store.
+- Recommended methods are ones that this module will call on the store if
+ available.
+- Optional methods are ones this module does not call at all, but helps
+ present uniform stores to users.
+
+For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo.
+
+### store.all(callback)
+
+**Optional**
+
+This optional method is used to get all sessions in the store as an array. The
+`callback` should be called as `callback(error, sessions)`.
+
+### store.destroy(sid, callback)
+
+**Required**
+
+This required method is used to destroy/delete a session from the store given
+a session ID (`sid`). The `callback` should be called as `callback(error)` once
+the session is destroyed.
+
+### store.clear(callback)
+
+**Optional**
+
+This optional method is used to delete all sessions from the store. The
+`callback` should be called as `callback(error)` once the store is cleared.
+
+### store.length(callback)
+
+**Optional**
+
+This optional method is used to get the count of all sessions in the store.
+The `callback` should be called as `callback(error, len)`.
+
+### store.get(sid, callback)
+
+**Required**
+
+This required method is used to get a session from the store given a session
+ID (`sid`). The `callback` should be called as `callback(error, session)`.
+
+The `session` argument should be a session if found, otherwise `null` or
+`undefined` if the session was not found (and there was no error). A special
+case is made when `error.code === 'ENOENT'` to act like `callback(null, null)`.
+
+### store.set(sid, session, callback)
+
+**Required**
+
+This required method is used to upsert a session into the store given a
+session ID (`sid`) and session (`session`) object. The callback should be
+called as `callback(error)` once the session has been set in the store.
+
+### store.touch(sid, session, callback)
+
+**Recommended**
+
+This recommended method is used to "touch" a given session given a
+session ID (`sid`) and session (`session`) object. The `callback` should be
+called as `callback(error)` once the session has been touched.
+
+This is primarily used when the store will automatically delete idle sessions
+and this method is used to signal to the store the given session is active,
+potentially resetting the idle timer.
+
+## Compatible Session Stores
+
+The following modules implement a session store that is compatible with this
+module. Please make a PR to add additional modules :)
+
+[![★][aerospike-session-store-image] aerospike-session-store][aerospike-session-store-url] A session store using [Aerospike](http://www.aerospike.com/).
+
+[aerospike-session-store-url]: https://www.npmjs.com/package/aerospike-session-store
+[aerospike-session-store-image]: https://badgen.net/github/stars/aerospike/aerospike-session-store-expressjs?label=%E2%98%85
+
+[![★][better-sqlite3-session-store-image] better-sqlite3-session-store][better-sqlite3-session-store-url] A session store based on [better-sqlite3](https://github.com/JoshuaWise/better-sqlite3).
+
+[better-sqlite3-session-store-url]: https://www.npmjs.com/package/better-sqlite3-session-store
+[better-sqlite3-session-store-image]: https://badgen.net/github/stars/timdaub/better-sqlite3-session-store?label=%E2%98%85
+
+[![★][cassandra-store-image] cassandra-store][cassandra-store-url] An Apache Cassandra-based session store.
+
+[cassandra-store-url]: https://www.npmjs.com/package/cassandra-store
+[cassandra-store-image]: https://badgen.net/github/stars/webcc/cassandra-store?label=%E2%98%85
+
+[![★][cluster-store-image] cluster-store][cluster-store-url] A wrapper for using in-process / embedded
+stores - such as SQLite (via knex), leveldb, files, or memory - with node cluster (desirable for Raspberry Pi 2
+and other multi-core embedded devices).
+
+[cluster-store-url]: https://www.npmjs.com/package/cluster-store
+[cluster-store-image]: https://badgen.net/github/stars/coolaj86/cluster-store?label=%E2%98%85
+
+[![★][connect-arango-image] connect-arango][connect-arango-url] An ArangoDB-based session store.
+
+[connect-arango-url]: https://www.npmjs.com/package/connect-arango
+[connect-arango-image]: https://badgen.net/github/stars/AlexanderArvidsson/connect-arango?label=%E2%98%85
+
+[![★][connect-azuretables-image] connect-azuretables][connect-azuretables-url] An [Azure Table Storage](https://azure.microsoft.com/en-gb/services/storage/tables/)-based session store.
+
+[connect-azuretables-url]: https://www.npmjs.com/package/connect-azuretables
+[connect-azuretables-image]: https://badgen.net/github/stars/mike-goodwin/connect-azuretables?label=%E2%98%85
+
+[![★][connect-cloudant-store-image] connect-cloudant-store][connect-cloudant-store-url] An [IBM Cloudant](https://cloudant.com/)-based session store.
+
+[connect-cloudant-store-url]: https://www.npmjs.com/package/connect-cloudant-store
+[connect-cloudant-store-image]: https://badgen.net/github/stars/adriantanasa/connect-cloudant-store?label=%E2%98%85
+
+[![★][connect-cosmosdb-image] connect-cosmosdb][connect-cosmosdb-url] An Azure [Cosmos DB](https://azure.microsoft.com/en-us/products/cosmos-db/)-based session store.
+
+[connect-cosmosdb-url]: https://www.npmjs.com/package/connect-cosmosdb
+[connect-cosmosdb-image]: https://badgen.net/github/stars/thekillingspree/connect-cosmosdb?label=%E2%98%85
+
+[![★][connect-couchbase-image] connect-couchbase][connect-couchbase-url] A [couchbase](http://www.couchbase.com/)-based session store.
+
+[connect-couchbase-url]: https://www.npmjs.com/package/connect-couchbase
+[connect-couchbase-image]: https://badgen.net/github/stars/christophermina/connect-couchbase?label=%E2%98%85
+
+[![★][connect-datacache-image] connect-datacache][connect-datacache-url] An [IBM Bluemix Data Cache](http://www.ibm.com/cloud-computing/bluemix/)-based session store.
+
+[connect-datacache-url]: https://www.npmjs.com/package/connect-datacache
+[connect-datacache-image]: https://badgen.net/github/stars/adriantanasa/connect-datacache?label=%E2%98%85
+
+[![★][@google-cloud/connect-datastore-image] @google-cloud/connect-datastore][@google-cloud/connect-datastore-url] A [Google Cloud Datastore](https://cloud.google.com/datastore/docs/concepts/overview)-based session store.
+
+[@google-cloud/connect-datastore-url]: https://www.npmjs.com/package/@google-cloud/connect-datastore
+[@google-cloud/connect-datastore-image]: https://badgen.net/github/stars/GoogleCloudPlatform/cloud-datastore-session-node?label=%E2%98%85
+
+[![★][connect-db2-image] connect-db2][connect-db2-url] An IBM DB2-based session store built using [ibm_db](https://www.npmjs.com/package/ibm_db) module.
+
+[connect-db2-url]: https://www.npmjs.com/package/connect-db2
+[connect-db2-image]: https://badgen.net/github/stars/wallali/connect-db2?label=%E2%98%85
+
+[![★][connect-dynamodb-image] connect-dynamodb][connect-dynamodb-url] A DynamoDB-based session store.
+
+[connect-dynamodb-url]: https://www.npmjs.com/package/connect-dynamodb
+[connect-dynamodb-image]: https://badgen.net/github/stars/ca98am79/connect-dynamodb?label=%E2%98%85
+
+[![★][@google-cloud/connect-firestore-image] @google-cloud/connect-firestore][@google-cloud/connect-firestore-url] A [Google Cloud Firestore](https://cloud.google.com/firestore/docs/overview)-based session store.
+
+[@google-cloud/connect-firestore-url]: https://www.npmjs.com/package/@google-cloud/connect-firestore
+[@google-cloud/connect-firestore-image]: https://badgen.net/github/stars/googleapis/nodejs-firestore-session?label=%E2%98%85
+
+[![★][connect-hazelcast-image] connect-hazelcast][connect-hazelcast-url] Hazelcast session store for Connect and Express.
+
+[connect-hazelcast-url]: https://www.npmjs.com/package/connect-hazelcast
+[connect-hazelcast-image]: https://badgen.net/github/stars/huseyinbabal/connect-hazelcast?label=%E2%98%85
+
+[![★][connect-loki-image] connect-loki][connect-loki-url] A Loki.js-based session store.
+
+[connect-loki-url]: https://www.npmjs.com/package/connect-loki
+[connect-loki-image]: https://badgen.net/github/stars/Requarks/connect-loki?label=%E2%98%85
+
+[![★][connect-lowdb-image] connect-lowdb][connect-lowdb-url] A lowdb-based session store.
+
+[connect-lowdb-url]: https://www.npmjs.com/package/connect-lowdb
+[connect-lowdb-image]: https://badgen.net/github/stars/travishorn/connect-lowdb?label=%E2%98%85
+
+[![★][connect-memcached-image] connect-memcached][connect-memcached-url] A memcached-based session store.
+
+[connect-memcached-url]: https://www.npmjs.com/package/connect-memcached
+[connect-memcached-image]: https://badgen.net/github/stars/balor/connect-memcached?label=%E2%98%85
+
+[![★][connect-memjs-image] connect-memjs][connect-memjs-url] A memcached-based session store using
+[memjs](https://www.npmjs.com/package/memjs) as the memcached client.
+
+[connect-memjs-url]: https://www.npmjs.com/package/connect-memjs
+[connect-memjs-image]: https://badgen.net/github/stars/liamdon/connect-memjs?label=%E2%98%85
+
+[![★][connect-ml-image] connect-ml][connect-ml-url] A MarkLogic Server-based session store.
+
+[connect-ml-url]: https://www.npmjs.com/package/connect-ml
+[connect-ml-image]: https://badgen.net/github/stars/bluetorch/connect-ml?label=%E2%98%85
+
+[![★][connect-monetdb-image] connect-monetdb][connect-monetdb-url] A MonetDB-based session store.
+
+[connect-monetdb-url]: https://www.npmjs.com/package/connect-monetdb
+[connect-monetdb-image]: https://badgen.net/github/stars/MonetDB/npm-connect-monetdb?label=%E2%98%85
+
+[![★][connect-mongo-image] connect-mongo][connect-mongo-url] A MongoDB-based session store.
+
+[connect-mongo-url]: https://www.npmjs.com/package/connect-mongo
+[connect-mongo-image]: https://badgen.net/github/stars/kcbanner/connect-mongo?label=%E2%98%85
+
+[![★][connect-mongodb-session-image] connect-mongodb-session][connect-mongodb-session-url] Lightweight MongoDB-based session store built and maintained by MongoDB.
+
+[connect-mongodb-session-url]: https://www.npmjs.com/package/connect-mongodb-session
+[connect-mongodb-session-image]: https://badgen.net/github/stars/mongodb-js/connect-mongodb-session?label=%E2%98%85
+
+[![★][connect-mssql-v2-image] connect-mssql-v2][connect-mssql-v2-url] A Microsoft SQL Server-based session store based on [connect-mssql](https://www.npmjs.com/package/connect-mssql).
+
+[connect-mssql-v2-url]: https://www.npmjs.com/package/connect-mssql-v2
+[connect-mssql-v2-image]: https://badgen.net/github/stars/jluboff/connect-mssql-v2?label=%E2%98%85
+
+[![★][connect-neo4j-image] connect-neo4j][connect-neo4j-url] A [Neo4j](https://neo4j.com)-based session store.
+
+[connect-neo4j-url]: https://www.npmjs.com/package/connect-neo4j
+[connect-neo4j-image]: https://badgen.net/github/stars/MaxAndersson/connect-neo4j?label=%E2%98%85
+
+[![★][connect-ottoman-image] connect-ottoman][connect-ottoman-url] A [couchbase ottoman](http://www.couchbase.com/)-based session store.
+
+[connect-ottoman-url]: https://www.npmjs.com/package/connect-ottoman
+[connect-ottoman-image]: https://badgen.net/github/stars/noiissyboy/connect-ottoman?label=%E2%98%85
+
+[![★][connect-pg-simple-image] connect-pg-simple][connect-pg-simple-url] A PostgreSQL-based session store.
+
+[connect-pg-simple-url]: https://www.npmjs.com/package/connect-pg-simple
+[connect-pg-simple-image]: https://badgen.net/github/stars/voxpelli/node-connect-pg-simple?label=%E2%98%85
+
+[![★][connect-redis-image] connect-redis][connect-redis-url] A Redis-based session store.
+
+[connect-redis-url]: https://www.npmjs.com/package/connect-redis
+[connect-redis-image]: https://badgen.net/github/stars/tj/connect-redis?label=%E2%98%85
+
+[![★][connect-session-firebase-image] connect-session-firebase][connect-session-firebase-url] A session store based on the [Firebase Realtime Database](https://firebase.google.com/docs/database/)
+
+[connect-session-firebase-url]: https://www.npmjs.com/package/connect-session-firebase
+[connect-session-firebase-image]: https://badgen.net/github/stars/benweier/connect-session-firebase?label=%E2%98%85
+
+[![★][connect-session-knex-image] connect-session-knex][connect-session-knex-url] A session store using
+[Knex.js](http://knexjs.org/), which is a SQL query builder for PostgreSQL, MySQL, MariaDB, SQLite3, and Oracle.
+
+[connect-session-knex-url]: https://www.npmjs.com/package/connect-session-knex
+[connect-session-knex-image]: https://badgen.net/github/stars/llambda/connect-session-knex?label=%E2%98%85
+
+[![★][connect-session-sequelize-image] connect-session-sequelize][connect-session-sequelize-url] A session store using
+[Sequelize.js](http://sequelizejs.com/), which is a Node.js / io.js ORM for PostgreSQL, MySQL, SQLite and MSSQL.
+
+[connect-session-sequelize-url]: https://www.npmjs.com/package/connect-session-sequelize
+[connect-session-sequelize-image]: https://badgen.net/github/stars/mweibel/connect-session-sequelize?label=%E2%98%85
+
+[![★][connect-sqlite3-image] connect-sqlite3][connect-sqlite3-url] A [SQLite3](https://github.com/mapbox/node-sqlite3) session store modeled after the TJ's `connect-redis` store.
+
+[connect-sqlite3-url]: https://www.npmjs.com/package/connect-sqlite3
+[connect-sqlite3-image]: https://badgen.net/github/stars/rawberg/connect-sqlite3?label=%E2%98%85
+
+[![★][connect-typeorm-image] connect-typeorm][connect-typeorm-url] A [TypeORM](https://github.com/typeorm/typeorm)-based session store.
+
+[connect-typeorm-url]: https://www.npmjs.com/package/connect-typeorm
+[connect-typeorm-image]: https://badgen.net/github/stars/makepost/connect-typeorm?label=%E2%98%85
+
+[![★][couchdb-expression-image] couchdb-expression][couchdb-expression-url] A [CouchDB](https://couchdb.apache.org/)-based session store.
+
+[couchdb-expression-url]: https://www.npmjs.com/package/couchdb-expression
+[couchdb-expression-image]: https://badgen.net/github/stars/tkshnwesper/couchdb-expression?label=%E2%98%85
+
+[![★][dynamodb-store-image] dynamodb-store][dynamodb-store-url] A DynamoDB-based session store.
+
+[dynamodb-store-url]: https://www.npmjs.com/package/dynamodb-store
+[dynamodb-store-image]: https://badgen.net/github/stars/rafaelrpinto/dynamodb-store?label=%E2%98%85
+
+[![★][dynamodb-store-v3-image] dynamodb-store-v3][dynamodb-store-v3-url] Implementation of a session store using DynamoDB backed by the [AWS SDK for JavaScript v3](https://github.com/aws/aws-sdk-js-v3).
+
+[dynamodb-store-v3-url]: https://www.npmjs.com/package/dynamodb-store-v3
+[dynamodb-store-v3-image]: https://badgen.net/github/stars/FryDay/dynamodb-store-v3?label=%E2%98%85
+
+[![★][express-etcd-image] express-etcd][express-etcd-url] An [etcd](https://github.com/stianeikeland/node-etcd) based session store.
+
+[express-etcd-url]: https://www.npmjs.com/package/express-etcd
+[express-etcd-image]: https://badgen.net/github/stars/gildean/express-etcd?label=%E2%98%85
+
+[![★][express-mysql-session-image] express-mysql-session][express-mysql-session-url] A session store using native
+[MySQL](https://www.mysql.com/) via the [node-mysql](https://github.com/felixge/node-mysql) module.
+
+[express-mysql-session-url]: https://www.npmjs.com/package/express-mysql-session
+[express-mysql-session-image]: https://badgen.net/github/stars/chill117/express-mysql-session?label=%E2%98%85
+
+[![★][express-nedb-session-image] express-nedb-session][express-nedb-session-url] A NeDB-based session store.
+
+[express-nedb-session-url]: https://www.npmjs.com/package/express-nedb-session
+[express-nedb-session-image]: https://badgen.net/github/stars/louischatriot/express-nedb-session?label=%E2%98%85
+
+[![★][express-oracle-session-image] express-oracle-session][express-oracle-session-url] A session store using native
+[oracle](https://www.oracle.com/) via the [node-oracledb](https://www.npmjs.com/package/oracledb) module.
+
+[express-oracle-session-url]: https://www.npmjs.com/package/express-oracle-session
+[express-oracle-session-image]: https://badgen.net/github/stars/slumber86/express-oracle-session?label=%E2%98%85
+
+[![★][express-session-cache-manager-image] express-session-cache-manager][express-session-cache-manager-url]
+A store that implements [cache-manager](https://www.npmjs.com/package/cache-manager), which supports
+a [variety of storage types](https://www.npmjs.com/package/cache-manager#store-engines).
+
+[express-session-cache-manager-url]: https://www.npmjs.com/package/express-session-cache-manager
+[express-session-cache-manager-image]: https://badgen.net/github/stars/theogravity/express-session-cache-manager?label=%E2%98%85
+
+[![★][express-session-etcd3-image] express-session-etcd3][express-session-etcd3-url] An [etcd3](https://github.com/mixer/etcd3) based session store.
+
+[express-session-etcd3-url]: https://www.npmjs.com/package/express-session-etcd3
+[express-session-etcd3-image]: https://badgen.net/github/stars/willgm/express-session-etcd3?label=%E2%98%85
+
+[![★][express-session-level-image] express-session-level][express-session-level-url] A [LevelDB](https://github.com/Level/levelup) based session store.
+
+[express-session-level-url]: https://www.npmjs.com/package/express-session-level
+[express-session-level-image]: https://badgen.net/github/stars/tgohn/express-session-level?label=%E2%98%85
+
+[![★][express-session-rsdb-image] express-session-rsdb][express-session-rsdb-url] Session store based on Rocket-Store: A very simple, super fast and yet powerful, flat file database.
+
+[express-session-rsdb-url]: https://www.npmjs.com/package/express-session-rsdb
+[express-session-rsdb-image]: https://badgen.net/github/stars/paragi/express-session-rsdb?label=%E2%98%85
+
+[![★][express-sessions-image] express-sessions][express-sessions-url] A session store supporting both MongoDB and Redis.
+
+[express-sessions-url]: https://www.npmjs.com/package/express-sessions
+[express-sessions-image]: https://badgen.net/github/stars/konteck/express-sessions?label=%E2%98%85
+
+[![★][firestore-store-image] firestore-store][firestore-store-url] A [Firestore](https://github.com/hendrysadrak/firestore-store)-based session store.
+
+[firestore-store-url]: https://www.npmjs.com/package/firestore-store
+[firestore-store-image]: https://badgen.net/github/stars/hendrysadrak/firestore-store?label=%E2%98%85
+
+[![★][fortune-session-image] fortune-session][fortune-session-url] A [Fortune.js](https://github.com/fortunejs/fortune)
+based session store. Supports all backends supported by Fortune (MongoDB, Redis, Postgres, NeDB).
+
+[fortune-session-url]: https://www.npmjs.com/package/fortune-session
+[fortune-session-image]: https://badgen.net/github/stars/aliceklipper/fortune-session?label=%E2%98%85
+
+[![★][hazelcast-store-image] hazelcast-store][hazelcast-store-url] A Hazelcast-based session store built on the [Hazelcast Node Client](https://www.npmjs.com/package/hazelcast-client).
+
+[hazelcast-store-url]: https://www.npmjs.com/package/hazelcast-store
+[hazelcast-store-image]: https://badgen.net/github/stars/jackspaniel/hazelcast-store?label=%E2%98%85
+
+[![★][level-session-store-image] level-session-store][level-session-store-url] A LevelDB-based session store.
+
+[level-session-store-url]: https://www.npmjs.com/package/level-session-store
+[level-session-store-image]: https://badgen.net/github/stars/toddself/level-session-store?label=%E2%98%85
+
+[![★][lowdb-session-store-image] lowdb-session-store][lowdb-session-store-url] A [lowdb](https://www.npmjs.com/package/lowdb)-based session store.
+
+[lowdb-session-store-url]: https://www.npmjs.com/package/lowdb-session-store
+[lowdb-session-store-image]: https://badgen.net/github/stars/fhellwig/lowdb-session-store?label=%E2%98%85
+
+[![★][medea-session-store-image] medea-session-store][medea-session-store-url] A Medea-based session store.
+
+[medea-session-store-url]: https://www.npmjs.com/package/medea-session-store
+[medea-session-store-image]: https://badgen.net/github/stars/BenjaminVadant/medea-session-store?label=%E2%98%85
+
+[![★][memorystore-image] memorystore][memorystore-url] A memory session store made for production.
+
+[memorystore-url]: https://www.npmjs.com/package/memorystore
+[memorystore-image]: https://badgen.net/github/stars/roccomuso/memorystore?label=%E2%98%85
+
+[![★][mssql-session-store-image] mssql-session-store][mssql-session-store-url] A SQL Server-based session store.
+
+[mssql-session-store-url]: https://www.npmjs.com/package/mssql-session-store
+[mssql-session-store-image]: https://badgen.net/github/stars/jwathen/mssql-session-store?label=%E2%98%85
+
+[![★][nedb-session-store-image] nedb-session-store][nedb-session-store-url] An alternate NeDB-based (either in-memory or file-persisted) session store.
+
+[nedb-session-store-url]: https://www.npmjs.com/package/nedb-session-store
+[nedb-session-store-image]: https://badgen.net/github/stars/JamesMGreene/nedb-session-store?label=%E2%98%85
+
+[![★][@quixo3/prisma-session-store-image] @quixo3/prisma-session-store][@quixo3/prisma-session-store-url] A session store for the [Prisma Framework](https://www.prisma.io).
+
+[@quixo3/prisma-session-store-url]: https://www.npmjs.com/package/@quixo3/prisma-session-store
+[@quixo3/prisma-session-store-image]: https://badgen.net/github/stars/kleydon/prisma-session-store?label=%E2%98%85
+
+[![★][restsession-image] restsession][restsession-url] Store sessions utilizing a RESTful API
+
+[restsession-url]: https://www.npmjs.com/package/restsession
+[restsession-image]: https://badgen.net/github/stars/jankal/restsession?label=%E2%98%85
+
+[![★][sequelstore-connect-image] sequelstore-connect][sequelstore-connect-url] A session store using [Sequelize.js](http://sequelizejs.com/).
+
+[sequelstore-connect-url]: https://www.npmjs.com/package/sequelstore-connect
+[sequelstore-connect-image]: https://badgen.net/github/stars/MattMcFarland/sequelstore-connect?label=%E2%98%85
+
+[![★][session-file-store-image] session-file-store][session-file-store-url] A file system-based session store.
+
+[session-file-store-url]: https://www.npmjs.com/package/session-file-store
+[session-file-store-image]: https://badgen.net/github/stars/valery-barysok/session-file-store?label=%E2%98%85
+
+[![★][session-pouchdb-store-image] session-pouchdb-store][session-pouchdb-store-url] Session store for PouchDB / CouchDB. Accepts embedded, custom, or remote PouchDB instance and realtime synchronization.
+
+[session-pouchdb-store-url]: https://www.npmjs.com/package/session-pouchdb-store
+[session-pouchdb-store-image]: https://badgen.net/github/stars/solzimer/session-pouchdb-store?label=%E2%98%85
+
+[![★][@cyclic.sh/session-store-image] @cyclic.sh/session-store][@cyclic.sh/session-store-url] A DynamoDB-based session store for [Cyclic.sh](https://www.cyclic.sh/) apps.
+
+[@cyclic.sh/session-store-url]: https://www.npmjs.com/package/@cyclic.sh/session-store
+[@cyclic.sh/session-store-image]: https://badgen.net/github/stars/cyclic-software/session-store?label=%E2%98%85
+
+[![★][@databunker/session-store-image] @databunker/session-store][@databunker/session-store-url] A [Databunker](https://databunker.org/)-based encrypted session store.
+
+[@databunker/session-store-url]: https://www.npmjs.com/package/@databunker/session-store
+[@databunker/session-store-image]: https://badgen.net/github/stars/securitybunker/databunker-session-store?label=%E2%98%85
+
+[![★][sessionstore-image] sessionstore][sessionstore-url] A session store that works with various databases.
+
+[sessionstore-url]: https://www.npmjs.com/package/sessionstore
+[sessionstore-image]: https://badgen.net/github/stars/adrai/sessionstore?label=%E2%98%85
+
+[![★][tch-nedb-session-image] tch-nedb-session][tch-nedb-session-url] A file system session store based on NeDB.
+
+[tch-nedb-session-url]: https://www.npmjs.com/package/tch-nedb-session
+[tch-nedb-session-image]: https://badgen.net/github/stars/tomaschyly/NeDBSession?label=%E2%98%85
+
+## Examples
+
+### View counter
+
+A simple example using `express-session` to store page views for a user.
+
+```js
+var express = require('express');
+var parseurl = require('parseurl');
+var session = require('express-session');
+
+var app = express();
+
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ })
+);
+
+app.use(function (req, res, next) {
+ if (!req.session.views) {
+ req.session.views = {};
+ }
+
+ // get the url pathname
+ var pathname = parseurl(req).pathname;
+
+ // count the views
+ req.session.views[pathname] = (req.session.views[pathname] || 0) + 1;
+
+ next();
+});
+
+app.get('/foo', function (req, res, next) {
+ res.send('you viewed this page ' + req.session.views['/foo'] + ' times');
+});
+
+app.get('/bar', function (req, res, next) {
+ res.send('you viewed this page ' + req.session.views['/bar'] + ' times');
+});
+
+app.listen(3000);
+```
+
+### User login
+
+A simple example using `express-session` to keep a user log in session.
+
+```js
+var escapeHtml = require('escape-html');
+var express = require('express');
+var session = require('express-session');
+
+var app = express();
+
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ })
+);
+
+// middleware to test if authenticated
+function isAuthenticated(req, res, next) {
+ if (req.session.user) next();
+ else next('route');
+}
+
+app.get('/', isAuthenticated, function (req, res) {
+ // this is only called when there is an authentication user due to isAuthenticated
+ res.send('hello, ' + escapeHtml(req.session.user) + '!' + ' Logout ');
+});
+
+app.get('/', function (req, res) {
+ res.send(
+ ''
+ );
+});
+
+app.post('/login', express.urlencoded({ extended: false }), function (req, res) {
+ // login logic to validate req.body.user and req.body.pass
+ // would be implemented here. for this example any combo works
+
+ // regenerate the session, which is good practice to help
+ // guard against forms of session fixation
+ req.session.regenerate(function (err) {
+ if (err) next(err);
+
+ // store user information in session, typically a user id
+ req.session.user = req.body.user;
+
+ // save the session before redirection to ensure page
+ // load does not happen before session is saved
+ req.session.save(function (err) {
+ if (err) return next(err);
+ res.redirect('/');
+ });
+ });
+});
+
+app.get('/logout', function (req, res, next) {
+ // logout logic
+
+ // clear the user from the session object and save.
+ // this will ensure that re-using the old session id
+ // does not have a logged in user
+ req.session.user = null;
+ req.session.save(function (err) {
+ if (err) next(err);
+
+ // regenerate the session, which is good practice to help
+ // guard against forms of session fixation
+ req.session.regenerate(function (err) {
+ if (err) next(err);
+ res.redirect('/');
+ });
+ });
+});
+
+app.listen(3000);
+```
+
+## Debugging
+
+This module uses the [debug](https://www.npmjs.com/package/debug) module
+internally to log information about session operations.
+
+To see all the internal logs, set the `DEBUG` environment variable to
+`express-session` when launching your app (`npm start`, in this example):
+
+```sh
+$ DEBUG=express-session npm start
+```
+
+On Windows, use the corresponding command;
+
+```sh
+> set DEBUG=express-session & npm start
+```
+
+## License
+
+[MIT](LICENSE)
+
+[rfc-6265bis-03-4.1.2.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7
+[rfc-cutler-httpbis-partitioned-cookies]: https://tools.ietf.org/html/draft-cutler-httpbis-partitioned-cookies/
+[rfc-west-cookie-priority-00-4.1]: https://tools.ietf.org/html/draft-west-cookie-priority-00#section-4.1
+[ci-image]: https://badgen.net/github/checks/expressjs/session/master?label=ci
+[ci-url]: https://github.com/expressjs/session/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/session/master
+[coveralls-url]: https://coveralls.io/r/expressjs/session?branch=master
+[node-url]: https://nodejs.org/en/download
+[npm-downloads-image]: https://badgen.net/npm/dm/express-session
+[npm-url]: https://npmjs.org/package/express-session
+[npm-version-image]: https://badgen.net/npm/v/express-session
diff --git a/astro/src/content/resources/fr/middleware/timeout.md b/astro/src/content/resources/fr/middleware/timeout.md
new file mode 100644
index 0000000000..f6057aedfd
--- /dev/null
+++ b/astro/src/content/resources/fr/middleware/timeout.md
@@ -0,0 +1,176 @@
+---
+title: Express timeout middleware
+module: timeout
+---
+
+# connect-timeout
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][travis-image]][travis-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Times out a request in the Connect/Express application framework.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install connect-timeout
+```
+
+## API
+
+**NOTE** This module is not recommend as a "top-level" middleware (i.e.
+`app.use(timeout('5s'))`) unless you take precautions to halt your own
+middleware processing. See [as top-level middleware](#as-top-level-middleware)
+for how to use as a top-level middleware.
+
+While the library will emit a 'timeout' event when requests exceed the given
+timeout, node will continue processing the slow request until it terminates.
+Slow requests will continue to use CPU and memory, even if you are returning
+a HTTP response in the timeout callback. For better control over CPU/memory,
+you may need to find the events that are taking a long time (3rd party HTTP
+requests, disk I/O, database calls) and find a way to cancel them, and/or
+close the attached sockets.
+
+### timeout(time, [options])
+
+Returns middleware that times out in `time` milliseconds. `time` can also
+be a string accepted by the [ms](https://www.npmjs.org/package/ms#readme)
+module. On timeout, `req` will emit `"timeout"`.
+
+#### Options
+
+The `timeout` function takes an optional `options` object that may contain
+any of the following keys:
+
+##### respond
+
+Controls if this module will "respond" in the form of forwarding an error.
+If `true`, the timeout error is passed to `next()` so that you may customize
+the response behavior. This error has a `.timeout` property as well as
+`.status == 503`. This defaults to `true`.
+
+### req.clearTimeout()
+
+Clears the timeout on the request. The timeout is completely removed and
+will not fire for this request in the future.
+
+### req.timedout
+
+`true` if timeout fired; `false` otherwise.
+
+## Examples
+
+### as top-level middleware
+
+Because of the way middleware processing works, once this module
+passes the request to the next middleware (which it has to do in order
+for you to do work), it can no longer stop the flow, so you must take
+care to check if the request has timedout before you continue to act
+on the request.
+
+```javascript
+var bodyParser = require('body-parser');
+var cookieParser = require('cookie-parser');
+var express = require('express');
+var timeout = require('connect-timeout');
+
+// example of using this top-level; note the use of haltOnTimedout
+// after every middleware; it will stop the request flow on a timeout
+var app = express();
+app.use(timeout('5s'));
+app.use(bodyParser());
+app.use(haltOnTimedout);
+app.use(cookieParser());
+app.use(haltOnTimedout);
+
+// Add your routes here, etc.
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+app.listen(3000);
+```
+
+### express 3.x
+
+```javascript
+var express = require('express');
+var bodyParser = require('body-parser');
+var timeout = require('connect-timeout');
+
+var app = express();
+app.post('/save', timeout('5s'), bodyParser.json(), haltOnTimedout, function (req, res, next) {
+ savePost(req.body, function (err, id) {
+ if (err) return next(err);
+ if (req.timedout) return;
+ res.send('saved as id ' + id);
+ });
+});
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+function savePost(post, cb) {
+ setTimeout(
+ function () {
+ cb(null, (Math.random() * 40000) >>> 0);
+ },
+ (Math.random() * 7000) >>> 0
+ );
+}
+
+app.listen(3000);
+```
+
+### connect
+
+```javascript
+var bodyParser = require('body-parser');
+var connect = require('connect');
+var timeout = require('connect-timeout');
+
+var app = connect();
+app.use('/save', timeout('5s'), bodyParser.json(), haltOnTimedout, function (req, res, next) {
+ savePost(req.body, function (err, id) {
+ if (err) return next(err);
+ if (req.timedout) return;
+ res.send('saved as id ' + id);
+ });
+});
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+function savePost(post, cb) {
+ setTimeout(
+ function () {
+ cb(null, (Math.random() * 40000) >>> 0);
+ },
+ (Math.random() * 7000) >>> 0
+ );
+}
+
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/connect-timeout.svg
+[npm-url]: https://npmjs.org/package/connect-timeout
+[travis-image]: https://img.shields.io/travis/expressjs/timeout/master.svg
+[travis-url]: https://travis-ci.org/expressjs/timeout
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/timeout/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/timeout?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/connect-timeout.svg
+[downloads-url]: https://npmjs.org/package/connect-timeout
diff --git a/astro/src/content/resources/fr/middleware/vhost.md b/astro/src/content/resources/fr/middleware/vhost.md
new file mode 100644
index 0000000000..72f49d7f93
--- /dev/null
+++ b/astro/src/content/resources/fr/middleware/vhost.md
@@ -0,0 +1,174 @@
+---
+title: Express vhost middleware
+module: vhost
+---
+
+# vhost
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Install
+
+```sh
+$ npm install vhost
+```
+
+## API
+
+```js
+var vhost = require('vhost');
+```
+
+### vhost(hostname, handle)
+
+Create a new middleware function to hand off request to `handle` when the incoming
+host for the request matches `hostname`. The function is called as
+`handle(req, res, next)`, like a standard middleware.
+
+`hostname` can be a string or a RegExp object. When `hostname` is a string it can
+contain `*` to match 1 or more characters in that section of the hostname. When
+`hostname` is a RegExp, it will be forced to case-insensitive (since hostnames are)
+and will be forced to match based on the start and end of the hostname.
+
+When host is matched and the request is sent down to a vhost handler, the `req.vhost`
+property will be populated with an object. This object will have numeric properties
+corresponding to each wildcard (or capture group if RegExp object provided) and the
+`hostname` that was matched.
+
+```js
+var connect = require('connect');
+var vhost = require('vhost');
+var app = connect();
+
+app.use(
+ vhost('*.*.example.com', function handle(req, res, next) {
+ // for match of "foo.bar.example.com:8080" against "*.*.example.com":
+ console.dir(req.vhost.host); // => 'foo.bar.example.com:8080'
+ console.dir(req.vhost.hostname); // => 'foo.bar.example.com'
+ console.dir(req.vhost.length); // => 2
+ console.dir(req.vhost[0]); // => 'foo'
+ console.dir(req.vhost[1]); // => 'bar'
+ })
+);
+```
+
+## Examples
+
+### using with connect for static serving
+
+```js
+var connect = require('connect');
+var serveStatic = require('serve-static');
+var vhost = require('vhost');
+
+var mailapp = connect();
+
+// add middlewares to mailapp for mail.example.com
+
+// create app to serve static files on subdomain
+var staticapp = connect();
+staticapp.use(serveStatic('public'));
+
+// create main app
+var app = connect();
+
+// add vhost routing to main app for mail
+app.use(vhost('mail.example.com', mailapp));
+
+// route static assets for "assets-*" subdomain to get
+// around max host connections limit on browsers
+app.use(vhost('assets-*.example.com', staticapp));
+
+// add middlewares and main usage to app
+
+app.listen(3000);
+```
+
+### using with connect for user subdomains
+
+```js
+var connect = require('connect');
+var serveStatic = require('serve-static');
+var vhost = require('vhost');
+
+var mainapp = connect();
+
+// add middlewares to mainapp for the main web site
+
+// create app that will server user content from public/{username}/
+var userapp = connect();
+
+userapp.use(function (req, res, next) {
+ var username = req.vhost[0]; // username is the "*"
+
+ // pretend request was for /{username}/* for file serving
+ req.originalUrl = req.url;
+ req.url = '/' + username + req.url;
+
+ next();
+});
+userapp.use(serveStatic('public'));
+
+// create main app
+var app = connect();
+
+// add vhost routing for main app
+app.use(vhost('userpages.local', mainapp));
+app.use(vhost('www.userpages.local', mainapp));
+
+// listen on all subdomains for user pages
+app.use(vhost('*.userpages.local', userapp));
+
+app.listen(3000);
+```
+
+### using with any generic request handler
+
+```js
+var connect = require('connect');
+var http = require('http');
+var vhost = require('vhost');
+
+// create main app
+var app = connect();
+
+app.use(
+ vhost('mail.example.com', function (req, res) {
+ // handle req + res belonging to mail.example.com
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello from mail!');
+ })
+);
+
+// an external api server in any framework
+var httpServer = http.createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello from the api!');
+});
+
+app.use(
+ vhost('api.example.com', function (req, res) {
+ // handle req + res belonging to api.example.com
+ // pass the request to a standard Node.js HTTP server
+ httpServer.emit('request', req, res);
+ })
+);
+
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/vhost.svg
+[npm-url]: https://npmjs.org/package/vhost
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/vhost/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/vhost
+[downloads-image]: https://img.shields.io/npm/dm/vhost.svg
+[downloads-url]: https://npmjs.org/package/vhost
+[github-actions-ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/vhost/ci.yml?branch=master&label=ci
+[github-actions-ci-url]: https://github.com/expressjs/vhost/actions/workflows/ci.yml
diff --git a/astro/src/content/resources/fr/utils.md b/astro/src/content/resources/fr/utils.md
new file mode 100644
index 0000000000..546b2f09b4
--- /dev/null
+++ b/astro/src/content/resources/fr/utils.md
@@ -0,0 +1,22 @@
+---
+title: Express utilities
+description: Discover utility modules related to Express.js and Node.js, including tools for cookies, CSRF protection, URL parsing, routing, and more to enhance your applications.
+---
+
+## Express utility functions
+
+The [pillarjs](https://github.com/pillarjs) GitHub organization contains a number of modules
+for utility functions that may be generally useful.
+
+| Utility modules | Description |
+| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| [cookies](https://www.npmjs.com/package/cookies) | Get and set HTTP(S) cookies that can be signed to prevent tampering, using Keygrip. Can be used with the Node.js HTTP library or as Express middleware. |
+| [csrf](https://www.npmjs.com/package/csrf) | Contains the logic behind CSRF token creation and verification. Use this module to create custom CSRF middleware. |
+| [finalhandler](https://www.npmjs.com/package/finalhandler) | Function to invoke as the final step to respond to HTTP request. |
+| [parseurl](https://www.npmjs.com/package/parseurl) | Parse a URL with caching. |
+| [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) | Turn an Express-style path string such as ``/user/:name` into a regular expression. |
+| [resolve-path](https://www.npmjs.com/package/resolve-path) | Resolves a relative path against a root path with validation. |
+| [router](https://www.npmjs.com/package/router) | Simple middleware-style router. |
+| [send](https://www.npmjs.com/package/send) | Library for streaming files as a HTTP response, with support for partial responses (ranges), conditional-GET negotiation, and granular events. |
+
+For additional low-level HTTP-related modules, see [jshttp](https://github.com/jshttp).
diff --git a/astro/src/content/resources/it/community.md b/astro/src/content/resources/it/community.md
new file mode 100755
index 0000000000..2ba8985943
--- /dev/null
+++ b/astro/src/content/resources/it/community.md
@@ -0,0 +1,69 @@
+---
+title: Express community
+description: Connect with the Express.js community, learn about the technical committee, find resources, explore community-contributed modules, and get involved in discussions.
+---
+
+# Community
+
+## Technical committee
+
+The Express technical committee meets online every two weeks (as needed) to discuss development and maintenance of Express,
+and other issues relevant to the Express project. Each meeting is typically announced in an
+[expressjs/discussions issue](https://github.com/expressjs/discussions/issues) with a link to join or view the meeting, which is
+open to all observers.
+
+The meetings are recorded; for a list of the recordings, see the [Express.js YouTube channel](https://www.youtube.com/channel/UCYjxjAeH6TRik9Iwy5nXw7g).
+
+Members of the Express technical committee are:
+
+**Active:**
+
+- [@blakeembrey](https://github.com/blakeembrey) - Blake Embrey
+- [@crandmck](https://github.com/crandmck) - Rand McKinney
+- [@LinusU](https://github.com/LinusU) - Linus Unnebäck
+- [@ulisesgascon](https://github.com/ulisesGascon) - Ulises Gascón
+- [@sheplu](https://github.com/sheplu) - Jean Burellier
+- [@wesleytodd](https://github.com/wesleytodd) - Wes Todd
+- [@jonchurch](https://github.com/jonchurch) - Jon Church
+- [@ctcpip](https://github.com/ctcpip/) - Chris de Almeida
+
+**Inactive:**
+
+- [@dougwilson](https://github.com/dougwilson) - Douglas Wilson
+- [@hacksparrow](https://github.com/hacksparrow) - Hage Yaapa
+- [@jonathanong](https://github.com/jonathanong) - jongleberry
+- [@niftylettuce](https://github.com/niftylettuce) - niftylettuce
+- [@troygoode](https://github.com/troygoode) - Troy Goode
+
+## Express is made of many modules
+
+Our vibrant community has created a large variety of extensions,
+[middleware modules](/en/resources/middleware) and higher-level frameworks.
+
+Additionally, the Express community maintains modules in these two GitHub orgs:
+
+- [jshttp](https://github.com/jshttp) modules providing useful utility functions; see [Utility modules](/en/resources/utils).
+- [pillarjs](https://github.com/pillarjs): low-level modules that Express uses internally.
+
+To keep up with what is going on in the whole community, check out the [ExpressJS StatusBoard](https://expressjs.github.io/statusboard/).
+
+## Issues
+
+If you've come across what you think is a bug, or just want to make
+a feature request open a ticket in the [issue queue](https://github.com/expressjs/express/issues).
+
+## Examples
+
+View dozens of Express application [examples](https://github.com/expressjs/express/tree/master/examples)
+in the repository covering everything from API design and authentication to template engine integration.
+
+## Github Discussions
+
+The [GitHub Discussions](https://github.com/expressjs/discussions) section is an excellent space to engage in conversations about the development and maintenance of Express, as well as to share ideas and discuss topics related to its usage.
+
+# Branding of Express.js
+
+## Express.js Logo
+
+Express is a project of the OpenJS Foundation. Please review the [trademark policy](https://trademark-policy.openjsf.org/) for information about permissible use of Express.js logos and marks.
+<-- TODO: add logos -->
diff --git a/astro/src/content/resources/it/contributing.md b/astro/src/content/resources/it/contributing.md
new file mode 100644
index 0000000000..82c6b8fed7
--- /dev/null
+++ b/astro/src/content/resources/it/contributing.md
@@ -0,0 +1,482 @@
+---
+title: Contributing to Express
+description: Find out how to contribute to Express.js, including guidelines for reporting issues, submitting pull requests, becoming a collaborator, and understanding security policies.
+---
+
+# Contributing to Express
+
+### Looking to contribute to Expressjs.com? Click [here](#expressjs-website-contributing).
+
+Express and the other projects in the [expressjs organization on GitHub](https://github.com/expressjs) are projects of the [OpenJs Foundation](https://openjsf.org/).
+These projects are governed under the general policies and guidelines of the Node.js Foundation along with the additional guidelines below.
+
+- [Technical committee](#technical-committee)
+- [Community contributing guide](#community-contributing-guide)
+- [Collaborator's guide](#collaborators-guide)
+- [Security policies and procedures](#security-policies-and-procedures)
+
+## Technical committee
+
+The Express technical committee consists of active project members, and guides development and maintenance of the Express project. For more information, see [Express Community - Technical committee](/en/resources/community/#technical-committee).
+
+## Community contributing guide
+
+
+
+The goal of this document is to create a contribution process that:
+
+- Encourages new contributions.
+- Encourages contributors to remain involved.
+- Avoids unnecessary processes and bureaucracy whenever possible.
+- Creates a transparent decision making process that makes it clear how
+ contributors can be involved in decision making.
+
+### Vocabulary
+
+- A **Contributor** is any individual creating or commenting on an issue or pull request.
+- A **Committer** is a subset of contributors who have been given write access to the repository.
+- A **Project Captain** is the lead maintainer of a repository.
+- A **TC (Technical Committee)** is a group of committers representing the required technical
+ expertise to resolve rare disputes.
+- A **Triager** is a subset of contributors who have been given triage access to the repository.
+
+### Logging Issues
+
+Log an issue for any question or problem you might have. When in doubt, log an issue, and
+any additional policies about what to include will be provided in the responses. The only
+exception is security disclosures which should be sent privately.
+
+Committers may direct you to another repository, ask for additional clarifications, and
+add appropriate metadata before the issue is addressed.
+
+Please be courteous and respectful. Every participant is expected to follow the
+project's Code of Conduct.
+
+### Contributions
+
+Any change to resources in this repository must be through pull requests. This applies to all changes
+to documentation, code, binary files, etc. Even long term committers and TC members must use
+pull requests.
+
+No pull request can be merged without being reviewed.
+
+For non-trivial contributions, pull requests should sit for at least 36 hours to ensure that
+contributors in other timezones have time to review. Consideration should also be given to
+weekends and other holiday periods to ensure active committers all have reasonable time to
+become involved in the discussion and review process if they wish.
+
+The default for each contribution is that it is accepted once no committer has an objection.
+During a review, committers may also request that a specific contributor who is most versed in a
+particular area gives a "LGTM" before the PR can be merged. There is no additional "sign off"
+process for contributions to land. Once all issues brought by committers are addressed it can
+be landed by any committer.
+
+In the case of an objection being raised in a pull request by another committer, all involved
+committers should seek to arrive at a consensus by way of addressing concerns being expressed
+by discussion, compromise on the proposed change, or withdrawal of the proposed change.
+
+If a contribution is controversial and committers cannot agree about how to get it to land
+or if it should land then it should be escalated to the TC. TC members should regularly
+discuss pending contributions in order to find a resolution. It is expected that only a
+small minority of issues be brought to the TC for resolution and that discussion and
+compromise among committers be the default resolution mechanism.
+
+### Becoming a Triager
+
+Anyone can become a triager! Read more about the process of being a triager in
+[the triage process document](https://github.com/expressjs/discussions/blob/master/Triager-Guide.md).
+
+Currently, any existing [organization member](https://github.com/orgs/expressjs/people) can nominate
+a new triager. If you are interested in becoming a triager, our best advice is to actively participate
+in the community by helping triaging issues and pull requests. As well we recommend
+to engage in other community activities like attending the TC meetings, and participating in the Slack
+discussions. If you feel ready and have been helping triage some issues, reach out to an active member of the organization to ask if they'd
+be willing to support you. If they agree, they can create a pull request to formalize your nomination. In the case of an objection to the nomination, the triage team is responsible for working with the individuals involved and finding a resolution.
+
+You can also reach out to any of the [organization members](https://github.com/orgs/expressjs/people)
+if you have questions or need guidance.
+
+### Becoming a Committer
+
+All contributors who have landed significant and valuable contributions should be onboarded in a timely manner,
+and added as a committer, and be given write access to the repository.
+
+Committers are expected to follow this policy and continue to send pull requests, go through
+proper review, and have other committers merge their pull requests.
+
+### TC Process
+
+The TC uses a "consensus seeking" process for issues that are escalated to the TC.
+The group tries to find a resolution that has no open objections among TC members.
+If a consensus cannot be reached that has no objections then a majority wins vote
+is called. It is also expected that the majority of decisions made by the TC are via
+a consensus seeking process and that voting is only used as a last-resort.
+
+Resolution may involve returning the issue to project captains with suggestions on
+how to move forward towards a consensus. It is not expected that a meeting of the TC
+will resolve all issues on its agenda during that meeting and may prefer to continue
+the discussion happening among the project captains.
+
+Members can be added to the TC at any time. Any TC member can nominate another committer
+to the TC and the TC uses its standard consensus seeking process to evaluate whether or
+not to add this new member. The TC will consist of a minimum of 3 active members and a
+maximum of 10. If the TC should drop below 5 members the active TC members should nominate
+someone new. If a TC member is stepping down, they are encouraged (but not required) to
+nominate someone to take their place.
+
+TC members will be added as admin's on the Github orgs, npm orgs, and other resources as
+necessary to be effective in the role.
+
+To remain "active" a TC member should have participation within the last 12 months and miss
+no more than six consecutive TC meetings. Our goal is to increase participation, not punish
+people for any lack of participation, this guideline should be only be used as such
+(replace an inactive member with a new active one, for example). Members who do not meet this
+are expected to step down. If A TC member does not step down, an issue can be opened in the
+discussions repo to move them to inactive status. TC members who step down or are removed due
+to inactivity will be moved into inactive status.
+
+Inactive status members can become active members by self nomination if the TC is not already
+larger than the maximum of 10. They will also be given preference if, while at max size, an
+active member steps down.
+
+### Project Captains
+
+The Express TC can designate captains for individual projects/repos in the
+organizations. These captains are responsible for being the primary
+day-to-day maintainers of the repo on a technical and community front.
+Repo captains are empowered with repo ownership and package publication rights.
+When there are conflicts, especially on topics that effect the Express project
+at large, captains are responsible to raise it up to the TC and drive
+those conflicts to resolution. Captains are also responsible for making sure
+community members follow the community guidelines, maintaining the repo
+and the published package, as well as in providing user support.
+
+Like TC members, Repo captains are a subset of committers.
+
+To become a captain for a project the candidate is expected to participate in that
+project for at least 6 months as a committer prior to the request. They should have
+helped with code contributions as well as triaging issues. They are also required to
+have 2FA enabled on both their GitHub and npm accounts.
+
+Any TC member or an existing captain on the **same** repo can nominate another committer
+to the captain role. To do so, they should submit a PR to this document, updating the
+**Active Project Captains** section (while maintaining the sort order) with the project
+name, the nominee's GitHub handle, and their npm username (if different).
+
+- Repos can have as many captains as make sense for the scope of work.
+- A TC member or an existing repo captain **on the same project** can nominate a new captain.
+ Repo captains from other projects should not nominate captains for a different project.
+
+The PR will require at least 2 approvals from TC members and 2 weeks hold time to allow
+for comment and/or dissent. When the PR is merged, a TC member will add them to the
+proper GitHub/npm groups.
+
+#### Active Projects and Captains
+
+The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members)
+
+#### Current Initiative Captains
+
+The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains)
+
+### Inactivity and Emeritus Policy for Any Role
+
+To support the health and continuity of the project, all individuals holding a role within the community (such as Triager, Committer, WG member, Project Captain, or TC member) are encouraged to maintain active participation.
+
+Inactivity is defined as the absence of meaningful involvement in the project—such as contributions, code reviews, triage, meeting attendance, or discussion participation—for a continuous period of 6 months.
+
+#### Exceptions
+
+Anyone may request a temporary leave from active participation due to personal or professional reasons. In such cases, the individual should inform the relevant team or the Technical Committee (TC). During this time, the inactivity policy is paused, and the individual will not be flagged as inactive.
+
+#### Inactivity Process
+
+- If someone is deemed inactive, the individual may be transitioned to an emeritus role that reflects their past contributions. A best effort will be made to inform them that this has occurred. They may request to be reinstated when they are ready to be active again.
+- The emeritus status helps preserve a clear record of contributors who have meaningfully shaped the project over time.
+
+#### Accountability
+
+- The Technical Committee (TC) and the respective captains of each package/team are responsible for assessing activity levels and enacting this policy fairly and transparently, in coordination with other relevant teams.
+- In case of disagreement, the situation can be discussed and resolved by consensus within the TC or appropriate team.
+
+### Developer's Certificate of Origin 1.1
+
+```text
+By making a contribution to this project, I certify that:
+
+ (a) The contribution was created in whole or in part by me and I
+ have the right to submit it under the open source license
+ indicated in the file; or
+
+ (b) The contribution is based upon previous work that, to the best
+ of my knowledge, is covered under an appropriate open source
+ license and I have the right under that license to submit that
+ work with modifications, whether created in whole or in part
+ by me, under the same open source license (unless I am
+ permitted to submit under a different license), as indicated
+ in the file; or
+
+ (c) The contribution was provided directly to me by some other
+ person who certified (a), (b) or (c) and I have not modified
+ it.
+
+ (d) I understand and agree that this project and the contribution
+ are public and that a record of the contribution (including all
+ personal information I submit with it, including my sign-off) is
+ maintained indefinitely and may be redistributed consistent with
+ this project or the open source license(s) involved.
+```
+
+## Collaborator's guide
+
+
+
+### Website Issues
+
+Open issues for the expressjs.com website in https://github.com/expressjs/expressjs.com.
+
+For issues in other Express managed repos (everything in `expressjs`, `pillarjs` or `jshttp` other than `expressjs/express`), be sure to check their contributing guide and open issues and PRs in the appropriate repository.
+
+### PRs and Code contributions
+
+- Tests must pass.
+- Follow the [JavaScript Standard Style](https://standardjs.com/) and `npm run lint`.
+- If you fix a bug, add a test.
+
+### Branches
+
+Use the `master` branch for bug fixes or minor work that is intended for the
+current release stream.
+
+Use the correspondingly named branch, e.g. `6.x`, for anything intended for
+a future release of Express.
+
+### Steps for contributing
+
+1. Create an issue for the
+ bug you want to fix or the feature that you want to add.
+2. Create your own fork on GitHub, then
+ checkout your fork.
+3. Write your code in your local copy. It's good practice to create a branch for
+ each new issue you work on, although not compulsory.
+4. To run the test suite, first install the dependencies by running `npm install`,
+ then run `npm test`.
+5. Ensure your code is linted by running `npm run lint` -- fix any issue you
+ see listed.
+6. If the tests pass, you can commit your changes to your fork and then create
+ a pull request from there. Make sure to reference your issue from the pull
+ request comments by including the issue number e.g. `#123`.
+
+### Issues which are questions
+
+We will typically close any vague issues or questions that are specific to some
+app you are writing. Please double check the docs and other references before
+being trigger happy with posting a question issue.
+
+Things that will help get your question issue looked at:
+
+- Full and runnable JS code.
+- Clear description of the problem or unexpected behavior.
+- Clear description of the expected result.
+- Steps you have taken to debug it yourself.
+
+If you post a question and do not outline the above items or make it easy for
+us to understand and reproduce your issue, it will be closed.
+
+If your question meets all of the above requirements but you do not believe it needs to be looked at
+by the maintainers
+(for example, if you are just looking for community input) please open it as a discussion topic instead
+of an issue. If you
+are unsure and open an issue, we may move it to discussions if we triage them and decide they do
+not need high
+visibility or maintainer input.
+
+## Security Policies and Procedures
+
+
+
+This document outlines security procedures and general policies for the Express
+project.
+
+- [Reporting a Bug](#reporting-a-bug)
+- [Disclosure Policy](#disclosure-policy)
+- [Comments on this Policy](#comments-on-this-policy)
+
+### Reporting a Bug
+
+The Express team and community take all security bugs in Express seriously.
+Thank you for improving the security of Express. We appreciate your efforts and
+responsible disclosure and will make every effort to acknowledge your
+contributions.
+
+Report security bugs by emailing `express-security@lists.openjsf.org`.
+
+To ensure the timely response to your report, please ensure that the entirety
+of the report is contained within the email body and not solely behind a web
+link or an attachment.
+
+The lead maintainer will acknowledge your email within 48 hours, and will send a
+more detailed response within 48 hours indicating the next steps in handling
+your report. After the initial reply to your report, the security team will
+endeavor to keep you informed of the progress towards a fix and full
+announcement, and may ask for additional information or guidance.
+
+Report security bugs in third-party modules to the person or team maintaining
+the module.
+
+### Pre-release Versions
+
+Alpha and Beta releases are unstable and **not suitable for production use**.
+Vulnerabilities found in pre-releases should be reported according to the [Reporting a Bug](#reporting-a-bug) section.
+Due to the unstable nature of the branch it is not guaranteed that any fixes will be released in the next pre-release.
+
+### Disclosure Policy
+
+When the security team receives a security bug report, they will assign it to a
+primary handler. This person will coordinate the fix and release process,
+involving the following steps:
+
+- Confirm the problem and determine the affected versions.
+- Audit code to find any potential similar problems.
+- Prepare fixes for all releases still under maintenance. These fixes will be
+ released as fast as possible to npm.
+
+### The Express Threat Model
+
+We are currently working on a new version of the security model, the most updated version can be found [here](https://github.com/expressjs/security-wg/blob/main/docs/ThreatModel.md)
+
+### Comments on this Policy
+
+If you have suggestions on how this process could be improved please submit a
+pull request.
+
+---
+
+# Contributing to Expressjs.com {#expressjs-website-contributing}
+
+
+
+### The Official Documentation of the Express.js Framework
+
+This is the contribution documentation for the [expressjs.com](https://github.com/expressjs/expressjs.com) website.
+
+#### Need some ideas? These are some typical issues.
+
+1. **Website issues**: If you see anything on the site that could use a tune-up, think about how to fix it.
+ - Display or screen sizing problems
+ - Mobile responsiveness issues
+ - Missing or broken accessibility features
+ - Website outages
+ - Broken links
+ - Page structure or user interface enhancements
+
+2. **Content Issues**: Fix anything related to site content or typos.
+ - Spelling errors
+ - Incorrect/outdated Express.js documentation
+ - Missing content
+
+3. **Translation Issues**: Fix any translation errors or contribute new content.
+ - Fix spelling errors
+ - Fix incorrect/poorly translated words
+ - Check out the [Contributing translations](#contributing-translations) section below for a contributing guide.
+
+#### Want to work on a backlog issue?
+
+We often have bugs or enhancements that need work. You can find these under our repo's [Issues tab](https://github.com/expressjs/expressjs.com/issues). Check out the tags to find something that's a good match for you.
+
+#### Have an idea? Found a bug?
+
+If you've found a bug or a typo, or if you have an idea for an enhancement, you can:
+
+- Submit a [new issue](https://github.com/expressjs/expressjs.com/issues/new/choose) on our repo. Do this for larger proposals, or if you'd like to discuss or get feedback first.
+
+- Make a [GitHub pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). If you have already done work, and it's ready to go, feel free to send it our way.
+
+## Getting Started
+
+The steps below will guide you through the Expressjs.com contribution process.
+
+#### Step 1: (OPTIONAL) Open a New Issue
+
+So you've found a problem that you want to fix, or have a site enhancement you want to make.
+
+1. If you want to get feedback or discuss, open a discussion [issue](https://github.com/expressjs/expressjs.com/issues/new/choose) prior to starting work. This is not required, but encouraged for larger proposals.
+ - While we highly encourage this step, it is only for submissions proposing significant change. It helps us to clarify and focus the work, and ensure it aligns with overall project priorities.
+ - For submissions proposing minor improvements or corrections, this is not needed. You can skip this step.
+ - When opening an issue please give it a title and fill in the description section. The more details you provide, the more feedback we can give.
+
+2. After receiving your issue the Express.js documentation team will respond with feedback. We read every submission and always try to respond quickly with feedback.
+ - For submissions proposing significant change, we encourage you to follow the review process before starting work.
+
+#### Step 2: Get the Application Code Base
+
+Clone the repo and get the code:
+
+```sh
+git clone https://github.com/expressjs/expressjs.com.git
+```
+
+After you've got the code you're ready to start making your changes!
+
+But just in case you need a little extra explanation, this section below outlines the main sections of the code base, where most changes are likely to be made.
+
+**Markdown Page Files**:
+
+- These files render to html and make up the individual pages of the site. Most of the site's documentation text content is written in `md` files.
+- Change these to make changes to individual pages' content/text or markup.
+- Each language has its own complete set of pages, located under their respective language directories - all the Spanish markdown content is found in the `es` directory, for example.
+
+**Includes Partials and Layout Templates**
+
+- `_includes` are partials that are imported and reused across multiple pages.
+ - These are used to import text content for reuse across pages, such as the API documentation, e.g., `_includes > api > en > 5x`, which is included in every language.
+ - These are used to include the page components that make up site-wide user interface and periphery structure, e.g., Header, Footer, etc.
+- `_layouts` are the templates used to wrap the site's individual pages.
+ - These are used to display the structure of the site's periphery, such as the header and footer, and for injecting and displaying individual markdown pages inside the `content` tag.
+
+**Blog Markdown Files**
+
+- These files make up the individual blog posts. If you want to contribute a blog post please
+ follow the specific instructions for [How to write a blog post.](https://expressjs.com/en/blog/write-post)
+- Located under the `_posts` directory.
+
+**CSS or Javascript**
+
+- All css and js files are kept in `css` and `js` folders on the project root.
+
+The Express.js website is built using [Jekyll](https://jekyllrb.com/) and is hosted on [GitHub Pages](https://pages.github.com/).
+
+#### Step 3: Running the Application
+
+Now you'll need a way to see your changes, which means you'll need a running version of the application. You have two options.
+
+1. **Run Locally**: This gets the local version of the application up and running on your machine. Follow our [Local Setup Guide](https://github.com/expressjs/expressjs.com?tab=readme-ov-file#build-the-website-locally) to use this option.
+ - This is the recommended option for moderate to complex work.
+
+2. **Run using Deploy Preview**: Use this option if you don't want to bother with a local installation. Part of our continuous integration pipeline includes [Netlify Deploy Preview](https://docs.netlify.com/deploy/deploy-types/deploy-previews/).
+ 1. To use this you'll need to get your changes online - after you've made your first commit on your feature branch, make a _draft_ pull request.
+ 2. After the build steps are complete, you'll have access to a **Deploy Preview** tab that will run your changes on the web, rebuilding after each commit is pushed.
+ 3. After you are completely done your work, and it's ready for review, remove the draft status on your pull request and submit your work.
+
+## Contributing translations
+
+We use Crowdin to manage our translations in multiple languages and achieve automatic translation with artificial intelligence. Since these translations can be inefficient in some cases, we need help from the community to provide accurate and helpful translations.
+
+The documentation is translated into these languages:
+
+- Chinese Simplified (`zh-cn`)
+- Chinese Traditional (`zh-tw`)
+- English (`en`)
+- French (`fr`)
+- German (`de`)
+- Italian (`it`)
+- Japanese (`ja`)
+- Korean (`ko`)
+- Brazilian Portuguese (`pt-br`)
+- Spanish (`es`)
+
+### How to translate
+
+1. Request to join the Express.js Website project on [Crowdin](https://express.crowdin.com/website)
+2. [Select the language you want to translate](https://support.crowdin.com/for-translators/#starting-translation)
+3. [Start translating](https://support.crowdin.com/online-editor/)
diff --git a/astro/src/content/resources/it/glossary.md b/astro/src/content/resources/it/glossary.md
new file mode 100755
index 0000000000..8b45bf01eb
--- /dev/null
+++ b/astro/src/content/resources/it/glossary.md
@@ -0,0 +1,62 @@
+---
+title: Express glossary
+description: A comprehensive glossary of terms related to Express.js, Node.js, middleware, routing, and other key concepts to help you understand and use Express effectively.
+---
+
+# Glossary
+
+### application
+
+In general, one or more programs that are designed to carry out operations for a specific purpose. In the context of Express, a program that uses the Express API running on the Node.js platform. Might also refer to an [app object](/en/api#express).
+
+### API
+
+Application programming interface. Spell out the abbreviation when it is first used.
+
+### Express
+
+A fast, un-opinionated, minimalist web framework for Node.js applications. In general, "Express" is preferred to "Express.js," though the latter is acceptable.
+
+### libuv
+
+A multi-platform support library which focuses on asynchronous I/O, primarily developed for use by Node.js.
+
+### middleware
+
+A function that is invoked by the Express routing layer before the final request handler, and thus sits in the middle between a raw request and the final intended route. A few fine points of terminology around middleware:
+
+- `var foo = require('middleware')` is called _requiring_ or _using_ a Node.js module. Then the statement `var mw = foo()` typically returns the middleware.
+- `app.use(mw)` is called _adding the middleware to the global processing stack_.
+- `app.get('/foo', mw, function (req, res) { ... })` is called _adding the middleware to the "GET /foo" processing stack_.
+
+### Node.js
+
+A software platform that is used to build scalable network applications. Node.js uses JavaScript as its scripting language, and achieves high throughput via non-blocking I/O and a single-threaded event loop. See [nodejs.org](https://nodejs.org/en/). **Usage note**: Initially, "Node.js," thereafter "Node".
+
+### open-source, open source
+
+When used as an adjective, hyphenate; for example: "This is open-source software." See [Open-source software on Wikipedia](http://en.wikipedia.org/wiki/Open-source_software).
+
+{% capture english-rules %}
+
+Although it is common not to hyphenate this term, we are using the standard English rules for hyphenating a compound adjective.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=english-rules %}
+
+### request
+
+An HTTP request. A client submits an HTTP request message to a server, which returns a response. The request must use one of several [request methods](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods) such as GET, POST, and so on.
+
+### response
+
+An HTTP response. A server returns an HTTP response message to the client. The response contains completion status information about the request and might also contain requested content in its message body.
+
+### route
+
+Part of a URL that identifies a resource. For example, in `http://foo.com/products/id`, "/products/id" is the route.
+
+### router
+
+See [router](/en/api#router) in the API reference.
diff --git a/astro/src/content/resources/it/middleware/body-parser.md b/astro/src/content/resources/it/middleware/body-parser.md
new file mode 100644
index 0000000000..e82649a95c
--- /dev/null
+++ b/astro/src/content/resources/it/middleware/body-parser.md
@@ -0,0 +1,498 @@
+---
+title: Express body-parser middleware
+module: body-parser
+---
+
+# body-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+
+Node.js body parsing middleware.
+
+Parse incoming request bodies in a middleware before your handlers, available
+under the `req.body` property.
+
+**Note** As `req.body`'s shape is based on user-controlled input, all
+properties and values in this object are untrusted and should be validated
+before trusting. For example, `req.body.foo.toString()` may fail in multiple
+ways, for example the `foo` property may not be there or may not be a string,
+and `toString` may not be a function and instead a string or other user input.
+
+[Learn about the anatomy of an HTTP transaction in Node.js](https://nodejs.org/en/learn/http/anatomy-of-an-http-transaction).
+
+_This does not handle multipart bodies_, due to their complex and typically
+large nature. For multipart bodies, you may be interested in the following
+modules:
+
+- [busboy](https://www.npmjs.com/package/busboy#readme) and
+ [connect-busboy](https://www.npmjs.com/package/connect-busboy#readme)
+- [multiparty](https://www.npmjs.com/package/multiparty#readme) and
+ [connect-multiparty](https://www.npmjs.com/package/connect-multiparty#readme)
+- [formidable](https://www.npmjs.com/package/formidable#readme)
+- [multer](https://www.npmjs.com/package/multer#readme)
+
+This module provides the following parsers:
+
+- [JSON body parser](#bodyparserjsonoptions)
+- [Raw body parser](#bodyparserrawoptions)
+- [Text body parser](#bodyparsertextoptions)
+- [URL-encoded form body parser](#bodyparserurlencodedoptions)
+
+Other body parsers you might be interested in:
+
+- [body](https://www.npmjs.com/package/body#readme)
+- [co-body](https://www.npmjs.com/package/co-body#readme)
+
+## Installation
+
+```sh
+$ npm install body-parser
+```
+
+## API
+
+```js
+const bodyParser = require('body-parser');
+```
+
+The `bodyParser` object exposes various factories to create middlewares. All
+middlewares will populate the `req.body` property with the parsed body when
+the `Content-Type` request header matches the `type` option.
+
+The various errors returned by this module are described in the
+[errors section](#errors).
+
+### bodyParser.json([options])
+
+Returns middleware that only parses `json` and only looks at requests where
+the `Content-Type` header matches the `type` option. This parser accepts any
+Unicode encoding of the body and supports automatic inflation of `gzip`,
+`br` (brotli) and `deflate` encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`).
+
+#### Options
+
+The `json` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### defaultCharset
+
+Specify the default character set for the json content if the charset is not
+specified in the `Content-Type` header of the request. Defaults to `utf-8`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### reviver
+
+The `reviver` option is passed directly to `JSON.parse` as the second
+argument. You can find more information on this argument
+[in the MDN documentation about JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Example.3A_Using_the_reviver_parameter).
+
+##### strict
+
+When set to `true`, will only accept arrays and objects; when `false` will
+accept anything `JSON.parse` accepts. Defaults to `true`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not a
+function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `json`), a mime type (like `application/json`), or
+a mime type with a wildcard (like `*/*` or `*/json`). If a function, the `type`
+option is called as `fn(req)` and the request is parsed if it returns a truthy
+value. Defaults to `application/json`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.raw([options])
+
+Returns middleware that parses all bodies as a `Buffer` and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser supports automatic inflation of `gzip`, `br` (brotli) and `deflate`
+encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This will be a `Buffer` object
+of the body.
+
+#### Options
+
+The `raw` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function.
+If not a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this
+can be an extension name (like `bin`), a mime type (like
+`application/octet-stream`), or a mime type with a wildcard (like `*/*` or
+`application/*`). If a function, the `type` option is called as `fn(req)`
+and the request is parsed if it returns a truthy value. Defaults to
+`application/octet-stream`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.text([options])
+
+Returns middleware that parses all bodies as a string and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser supports automatic inflation of `gzip`, `br` (brotli) and `deflate`
+encodings.
+
+A new `body` string containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This will be a string of the
+body.
+
+#### Options
+
+The `text` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### defaultCharset
+
+Specify the default character set for the text content if the charset is not
+specified in the `Content-Type` header of the request. Defaults to `utf-8`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not
+a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `txt`), a mime type (like `text/plain`), or a mime
+type with a wildcard (like `*/*` or `text/*`). If a function, the `type`
+option is called as `fn(req)` and the request is parsed if it returns a
+truthy value. Defaults to `text/plain`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.urlencoded([options])
+
+Returns middleware that only parses `urlencoded` bodies and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser accepts only UTF-8 encoding of the body and supports automatic
+inflation of `gzip`, `br` (brotli) and `deflate` encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This object will contain
+key-value pairs, where the value can be a string or array (when `extended` is
+`false`), or any type (when `extended` is `true`).
+
+#### Options
+
+The `urlencoded` function takes an optional `options` object that may contain
+any of the following keys:
+
+##### extended
+
+The "extended" syntax allows for rich objects and arrays to be encoded into the
+URL-encoded format, allowing for a JSON-like experience with URL-encoded. For
+more information, please [see the qs
+library](https://www.npmjs.com/package/qs#readme).
+
+Defaults to `false`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### parameterLimit
+
+The `parameterLimit` option controls the maximum number of parameters that
+are allowed in the URL-encoded data. If a request contains more parameters
+than this value, a 413 will be returned to the client. Defaults to `1000`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not
+a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `urlencoded`), a mime type (like
+`application/x-www-form-urlencoded`), or a mime type with a wildcard (like
+`*/x-www-form-urlencoded`). If a function, the `type` option is called as
+`fn(req)` and the request is parsed if it returns a truthy value. Defaults
+to `application/x-www-form-urlencoded`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+##### defaultCharset
+
+The default charset to parse as, if not specified in content-type. Must be
+either `utf-8` or `iso-8859-1`. Defaults to `utf-8`.
+
+##### charsetSentinel
+
+Whether to let the value of the `utf8` parameter take precedence as the charset
+selector. It requires the form to contain a parameter named `utf8` with a value
+of `✓`. Defaults to `false`.
+
+##### interpretNumericEntities
+
+Whether to decode numeric entities such as `☺` when parsing an iso-8859-1
+form. Defaults to `false`.
+
+##### depth
+
+The `depth` option is used to configure the maximum depth of the `qs` library when `extended` is `true`. This allows you to limit the amount of keys that are parsed and can be useful to prevent certain types of abuse. Defaults to `32`. It is recommended to keep this value as low as possible.
+
+## Errors
+
+The middlewares provided by this module create errors using the
+[`http-errors` module](https://www.npmjs.com/package/http-errors). The errors
+will typically have a `status`/`statusCode` property that contains the suggested
+HTTP response code, an `expose` property to determine if the `message` property
+should be displayed to the client, a `type` property to determine the type of
+error without matching against the `message`, and a `body` property containing
+the read body, if available.
+
+The following are the common errors created, though any error can come through
+for various reasons.
+
+### content encoding unsupported
+
+This error will occur when the request had a `Content-Encoding` header that
+contained an encoding but the "inflation" option was set to `false`. The
+`status` property is set to `415`, the `type` property is set to
+`'encoding.unsupported'`, and the `charset` property will be set to the
+encoding that is unsupported.
+
+### entity parse failed
+
+This error will occur when the request contained an entity that could not be
+parsed by the middleware. The `status` property is set to `400`, the `type`
+property is set to `'entity.parse.failed'`, and the `body` property is set to
+the entity value that failed parsing.
+
+### entity verify failed
+
+This error will occur when the request contained an entity that could not be
+failed verification by the defined `verify` option. The `status` property is
+set to `403`, the `type` property is set to `'entity.verify.failed'`, and the
+`body` property is set to the entity value that failed verification.
+
+### request aborted
+
+This error will occur when the request is aborted by the client before reading
+the body has finished. The `received` property will be set to the number of
+bytes received before the request was aborted and the `expected` property is
+set to the number of expected bytes. The `status` property is set to `400`
+and `type` property is set to `'request.aborted'`.
+
+### request entity too large
+
+This error will occur when the request body's size is larger than the "limit"
+option. The `limit` property will be set to the byte limit and the `length`
+property will be set to the request body's length. The `status` property is
+set to `413` and the `type` property is set to `'entity.too.large'`.
+
+### request size did not match content length
+
+This error will occur when the request's length did not match the length from
+the `Content-Length` header. This typically occurs when the request is malformed,
+typically when the `Content-Length` header was calculated based on characters
+instead of bytes. The `status` property is set to `400` and the `type` property
+is set to `'request.size.invalid'`.
+
+### stream encoding should not be set
+
+This error will occur when something called the `req.setEncoding` method prior
+to this middleware. This module operates directly on bytes only and you cannot
+call `req.setEncoding` when using this module. The `status` property is set to
+`500` and the `type` property is set to `'stream.encoding.set'`.
+
+### stream is not readable
+
+This error will occur when the request is no longer readable when this middleware
+attempts to read it. This typically means something other than a middleware from
+this module read the request body already and the middleware was also configured to
+read the same request. The `status` property is set to `500` and the `type`
+property is set to `'stream.not.readable'`.
+
+### too many parameters
+
+This error will occur when the content of the request exceeds the configured
+`parameterLimit` for the `urlencoded` parser. The `status` property is set to
+`413` and the `type` property is set to `'parameters.too.many'`.
+
+### unsupported charset "BOGUS"
+
+This error will occur when the request had a charset parameter in the
+`Content-Type` header, but the `iconv-lite` module does not support it OR the
+parser does not support it. The charset is contained in the message as well
+as in the `charset` property. The `status` property is set to `415`, the
+`type` property is set to `'charset.unsupported'`, and the `charset` property
+is set to the charset that is unsupported.
+
+### unsupported content encoding "bogus"
+
+This error will occur when the request had a `Content-Encoding` header that
+contained an unsupported encoding. The encoding is contained in the message
+as well as in the `encoding` property. The `status` property is set to `415`,
+the `type` property is set to `'encoding.unsupported'`, and the `encoding`
+property is set to the encoding that is unsupported.
+
+### The input exceeded the depth
+
+This error occurs when using `bodyParser.urlencoded` with the `extended` property set to `true` and the input exceeds the configured `depth` option. The `status` property is set to `400`. It is recommended to review the `depth` option and evaluate if it requires a higher value. When the `depth` option is set to `32` (default value), the error will not be thrown.
+
+## Examples
+
+### Express/Connect top-level generic
+
+This example demonstrates adding a generic JSON and URL-encoded parser as a
+top-level middleware, which will parse the bodies of all incoming requests.
+This is the simplest setup.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// parse application/x-www-form-urlencoded
+app.use(bodyParser.urlencoded());
+
+// parse application/json
+app.use(bodyParser.json());
+
+app.use(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.write('you posted:\n');
+ res.end(String(JSON.stringify(req.body, null, 2)));
+});
+```
+
+### Express route-specific
+
+This example demonstrates adding body parsers specifically to the routes that
+need them. In general, this is the most recommended way to use body-parser with
+Express.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// create application/json parser
+const jsonParser = bodyParser.json();
+
+// create application/x-www-form-urlencoded parser
+const urlencodedParser = bodyParser.urlencoded();
+
+// POST /login gets urlencoded bodies
+app.post('/login', urlencodedParser, function (req, res) {
+ if (!req.body || !req.body.username) res.sendStatus(400);
+ res.send('welcome, ' + req.body.username);
+});
+
+// POST /api/users gets JSON bodies
+app.post('/api/users', jsonParser, function (req, res) {
+ if (!req.body) res.sendStatus(400);
+ // create user in req.body
+});
+```
+
+### Change accepted type for parsers
+
+All the parsers accept a `type` option which allows you to change the
+`Content-Type` that the middleware will parse.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// parse various different custom JSON types as JSON
+app.use(bodyParser.json({ type: 'application/*+json' }));
+
+// parse some custom thing into a Buffer
+app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }));
+
+// parse an HTML body into a string
+app.use(bodyParser.text({ type: 'text/html' }));
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/body-parser/ci.yml?branch=master&label=ci
+[ci-url]: https://github.com/expressjs/body-parser/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coverallsCoverage/github/expressjs/body-parser?branch=master
+[coveralls-url]: https://coveralls.io/r/expressjs/body-parser?branch=master
+[npm-downloads-image]: https://img.shields.io/npm/dm/body-parser
+[npm-url]: https://npmjs.com/package/body-parser
+[npm-version-image]: https://img.shields.io/npm/v/body-parser
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/body-parser/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/body-parser
diff --git a/astro/src/content/resources/it/middleware/compression.md b/astro/src/content/resources/it/middleware/compression.md
new file mode 100644
index 0000000000..6ac63fcb7a
--- /dev/null
+++ b/astro/src/content/resources/it/middleware/compression.md
@@ -0,0 +1,314 @@
+---
+title: Express compression middleware
+module: compression
+---
+
+# compression
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+[![Funding][funding-image]][funding-url]
+
+Node.js compression middleware.
+
+The following compression codings are supported:
+
+- deflate
+- gzip
+- br (brotli)
+
+**Note** Brotli is supported only since Node.js versions v11.7.0 and v10.16.0.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```bash
+$ npm install compression
+```
+
+## API
+
+```js
+var compression = require('compression');
+```
+
+### compression([options])
+
+Returns the compression middleware using the given `options`. The middleware
+will attempt to compress response bodies for all requests that traverse through
+the middleware, based on the given `options`.
+
+This middleware will never compress responses that include a `Cache-Control`
+header with the [`no-transform` directive](https://tools.ietf.org/html/rfc7234#section-5.2.2.4),
+as compressing will transform the body.
+
+#### Options
+
+`compression()` accepts these properties in the options object. In addition to
+those listed below, [zlib](https://nodejs.org/api/zlib.html) options may be
+passed in to the options object or
+[brotli](https://nodejs.org/api/zlib.html#zlib_class_brotlioptions) options.
+
+##### chunkSize
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_CHUNK`, or `16384`.
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### filter
+
+Type: `Function`
+
+A function to decide if the response should be considered for compression.
+This function is called as `filter(req, res)` and is expected to return
+`true` to consider the response for compression, or `false` to not compress
+the response.
+
+The default filter function uses the [compressible](https://www.npmjs.com/package/compressible)
+module to determine if `res.getHeader('Content-Type')` is compressible.
+
+##### level
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_COMPRESSION`, or `-1`
+
+The level of zlib compression to apply to responses. A higher level will result
+in better compression, but will take longer to complete. A lower level will
+result in less compression, but will be much faster.
+
+This is an integer in the range of `0` (no compression) to `9` (maximum
+compression). The special value `-1` can be used to mean the "default
+compression level", which is a default compromise between speed and
+compression (currently equivalent to level 6).
+
+- `-1` Default compression level (also `zlib.constants.Z_DEFAULT_COMPRESSION`).
+- `0` No compression (also `zlib.constants.Z_NO_COMPRESSION`).
+- `1` Fastest compression (also `zlib.constants.Z_BEST_SPEED`).
+- `2`
+- `3`
+- `4`
+- `5`
+- `6` (currently what `zlib.constants.Z_DEFAULT_COMPRESSION` points to).
+- `7`
+- `8`
+- `9` Best compression (also `zlib.constants.Z_BEST_COMPRESSION`).
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### memLevel
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_MEMLEVEL`, or `8`
+
+This specifies how much memory should be allocated for the internal compression
+state and is an integer in the range of `1` (minimum level) and `9` (maximum
+level).
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### brotli
+
+Type: `Object`
+
+This specifies the options for configuring Brotli. See [Node.js documentation](https://nodejs.org/api/zlib.html#class-brotlioptions) for a complete list of available options.
+
+##### strategy
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_STRATEGY`
+
+This is used to tune the compression algorithm. This value only affects the
+compression ratio, not the correctness of the compressed output, even if it
+is not set appropriately.
+
+- `zlib.constants.Z_DEFAULT_STRATEGY` Use for normal data.
+- `zlib.constants.Z_FILTERED` Use for data produced by a filter (or predictor).
+ Filtered data consists mostly of small values with a somewhat random
+ distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect is to force more Huffman coding and less
+ string matching; it is somewhat intermediate between `zlib.constants.Z_DEFAULT_STRATEGY`
+ and `zlib.constants.Z_HUFFMAN_ONLY`.
+- `zlib.constants.Z_FIXED` Use to prevent the use of dynamic Huffman codes, allowing
+ for a simpler decoder for special applications.
+- `zlib.constants.Z_HUFFMAN_ONLY` Use to force Huffman encoding only (no string match).
+- `zlib.constants.Z_RLE` Use to limit match distances to one (run-length encoding).
+ This is designed to be almost as fast as `zlib.constants.Z_HUFFMAN_ONLY`, but give
+ better compression for PNG image data.
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### threshold
+
+Type: `Number` or `String`
+Default: `1kb`
+
+The byte threshold for the response body size before compression is considered
+for the response. This is a number of bytes or any string
+accepted by the [bytes](https://www.npmjs.com/package/bytes) module.
+
+**Note** this is only an advisory setting; if the response size cannot be determined
+at the time the response headers are written, then it is assumed the response is
+_over_ the threshold. To guarantee the response size can be determined, be sure
+set a `Content-Length` response header.
+
+##### windowBits
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_WINDOWBITS`, or `15`
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### enforceEncoding
+
+Type: `String`
+Default: `identity`
+
+This is the default encoding to use when the client does not specify an encoding in the request's [Accept-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) header.
+
+#### .filter
+
+The default `filter` function. This is used to construct a custom filter
+function that is an extension of the default function.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+app.use(compression({ filter: shouldCompress }));
+
+function shouldCompress(req, res) {
+ if (req.headers['x-no-compression']) {
+ // don't compress responses with this request header
+ return false;
+ }
+
+ // fallback to standard filter function
+ return compression.filter(req, res);
+}
+```
+
+### res.flush
+
+This module adds a `res.flush()` method to force the partially-compressed
+response to be flushed to the client.
+
+## Examples
+
+### express
+
+When using this module with express, simply `app.use` the module as
+high as you like. Requests that pass through the middleware will be compressed.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress all responses
+app.use(compression());
+
+// add all routes
+```
+
+### Node.js HTTP server
+
+```js
+var compression = require('compression')({ threshold: 0 });
+var http = require('http');
+
+function createServer(fn) {
+ return http.createServer(function (req, res) {
+ compression(req, res, function (err) {
+ if (err) {
+ res.statusCode = err.status || 500;
+ res.end(err.message);
+ return;
+ }
+
+ fn(req, res);
+ });
+ });
+}
+
+var server = createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello world!');
+});
+
+server.listen(3000, () => {
+ console.log('> Listening at http://localhost:3000');
+});
+```
+
+### Server-Sent Events
+
+Because of the nature of compression this module does not work out of the box
+with server-sent events. To compress content, a window of the output needs to
+be buffered up in order to get good compression. Typically when using server-sent
+events, there are certain block of data that need to reach the client.
+
+You can achieve this by calling `res.flush()` when you need the data written to
+actually make it to the client.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress responses
+app.use(compression());
+
+// server-sent event stream
+app.get('/events', function (req, res) {
+ res.setHeader('Content-Type', 'text/event-stream');
+ res.setHeader('Cache-Control', 'no-cache');
+
+ // send a ping approx every 2 seconds
+ var timer = setInterval(function () {
+ res.write('data: ping\n\n');
+
+ // !!! this is the important part
+ res.flush();
+ }, 2000);
+
+ res.on('close', function () {
+ clearInterval(timer);
+ });
+});
+```
+
+## Contributing
+
+The Express.js project welcomes all constructive contributions. Contributions take many forms,
+from code for bug fixes and enhancements, to additions and fixes to documentation, additional
+tests, triaging incoming pull requests and issues, and more!
+
+See the [Contributing Guide](https://github.com/expressjs/express/blob/master/Contributing.md) for more technical details on contributing.
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://badgen.net/npm/v/compression
+[npm-url]: https://npmjs.org/package/compression
+[downloads-image]: https://badgen.net/npm/dm/compression
+[downloads-url]: https://npmcharts.com/compare/compression?minimal=true
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/compression/master?label=CI
+[github-actions-ci-url]: https://github.com/expressjs/compression/actions?query=workflow%3Aci
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/compression/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/compression
+[funding-url]: https://opencollective.com/express
+[funding-image]: https://badgen.net/badge/icon/sponsor/pink?icon=github&label=Open%20Collective
diff --git a/astro/src/content/resources/it/middleware/cookie-parser.md b/astro/src/content/resources/it/middleware/cookie-parser.md
new file mode 100644
index 0000000000..2a59496387
--- /dev/null
+++ b/astro/src/content/resources/it/middleware/cookie-parser.md
@@ -0,0 +1,124 @@
+---
+title: Express cookie-parser middleware
+module: cookie-parser
+---
+
+# cookie-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Parse `Cookie` header and populate `req.cookies` with an object keyed by the
+cookie names. Optionally you may enable signed cookie support by passing a
+`secret` string, which assigns `req.secret` so it may be used by other
+middleware.
+
+## Installation
+
+```sh
+$ npm install cookie-parser
+```
+
+## API
+
+```js
+var cookieParser = require('cookie-parser');
+```
+
+### cookieParser(secret, options)
+
+Create a new cookie parser middleware function using the given `secret` and
+`options`.
+
+- `secret` a string or array used for signing cookies. This is optional and if
+ not specified, will not parse signed cookies. If a string is provided, this
+ is used as the secret. If an array is provided, an attempt will be made to
+ unsign the cookie with each secret in order.
+- `options` an object that is passed to `cookie.parse` as the second option. See
+ [cookie](https://www.npmjs.org/package/cookie) for more information.
+ - `decode` a function to decode the value of the cookie
+
+The middleware will parse the `Cookie` header on the request and expose the
+cookie data as the property `req.cookies` and, if a `secret` was provided, as
+the property `req.signedCookies`. These properties are name value pairs of the
+cookie name to cookie value.
+
+When `secret` is provided, this module will unsign and validate any signed cookie
+values and move those name value pairs from `req.cookies` into `req.signedCookies`.
+A signed cookie is a cookie that has a value prefixed with `s:`. Signed cookies
+that fail signature validation will have the value `false` instead of the tampered
+value.
+
+In addition, this module supports special "JSON cookies". These are cookie where
+the value is prefixed with `j:`. When these values are encountered, the value will
+be exposed as the result of `JSON.parse`. If parsing fails, the original value will
+remain.
+
+### cookieParser.JSONCookie(str)
+
+Parse a cookie value as a JSON cookie. This will return the parsed JSON value
+if it was a JSON cookie, otherwise, it will return the passed value.
+
+### cookieParser.JSONCookies(cookies)
+
+Given an object, this will iterate over the keys and call `JSONCookie` on each
+value, replacing the original value with the parsed value. This returns the
+same object that was passed in.
+
+### cookieParser.signedCookie(str, secret)
+
+Parse a cookie value as a signed cookie. This will return the parsed unsigned
+value if it was a signed cookie and the signature was valid. If the value was
+not signed, the original value is returned. If the value was signed but the
+signature could not be validated, `false` is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+### cookieParser.signedCookies(cookies, secret)
+
+Given an object, this will iterate over the keys and check if any value is a
+signed cookie. If it is a signed cookie and the signature is valid, the key
+will be deleted from the object and added to the new object that is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+## Example
+
+```js
+var express = require('express');
+var cookieParser = require('cookie-parser');
+
+var app = express();
+app.use(cookieParser());
+
+app.get('/', function (req, res) {
+ // Cookies that have not been signed
+ console.log('Cookies: ', req.cookies);
+
+ // Cookies that have been signed
+ console.log('Signed Cookies: ', req.signedCookies);
+});
+
+app.listen(8080);
+
+// curl command that sends an HTTP request with two cookies
+// curl http://127.0.0.1:8080 --cookie "Cho=Kim;Greet=Hello"
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/cookie-parser/master?label=ci
+[ci-url]: https://github.com/expressjs/cookie-parser/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/cookie-parser/master
+[coveralls-url]: https://coveralls.io/r/expressjs/cookie-parser?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/cookie-parser
+[npm-url]: https://npmjs.org/package/cookie-parser
+[npm-version-image]: https://badgen.net/npm/v/cookie-parser
diff --git a/astro/src/content/resources/it/middleware/cookie-session.md b/astro/src/content/resources/it/middleware/cookie-session.md
new file mode 100644
index 0000000000..2d6d1f885b
--- /dev/null
+++ b/astro/src/content/resources/it/middleware/cookie-session.md
@@ -0,0 +1,124 @@
+---
+title: Express cookie-session middleware
+module: cookie-session
+---
+
+# cookie-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Parse `Cookie` header and populate `req.cookies` with an object keyed by the
+cookie names. Optionally you may enable signed cookie support by passing a
+`secret` string, which assigns `req.secret` so it may be used by other
+middleware.
+
+## Installation
+
+```sh
+$ npm install cookie-parser
+```
+
+## API
+
+```js
+var cookieParser = require('cookie-parser');
+```
+
+### cookieParser(secret, options)
+
+Create a new cookie parser middleware function using the given `secret` and
+`options`.
+
+- `secret` a string or array used for signing cookies. This is optional and if
+ not specified, will not parse signed cookies. If a string is provided, this
+ is used as the secret. If an array is provided, an attempt will be made to
+ unsign the cookie with each secret in order.
+- `options` an object that is passed to `cookie.parse` as the second option. See
+ [cookie](https://www.npmjs.org/package/cookie) for more information.
+ - `decode` a function to decode the value of the cookie
+
+The middleware will parse the `Cookie` header on the request and expose the
+cookie data as the property `req.cookies` and, if a `secret` was provided, as
+the property `req.signedCookies`. These properties are name value pairs of the
+cookie name to cookie value.
+
+When `secret` is provided, this module will unsign and validate any signed cookie
+values and move those name value pairs from `req.cookies` into `req.signedCookies`.
+A signed cookie is a cookie that has a value prefixed with `s:`. Signed cookies
+that fail signature validation will have the value `false` instead of the tampered
+value.
+
+In addition, this module supports special "JSON cookies". These are cookie where
+the value is prefixed with `j:`. When these values are encountered, the value will
+be exposed as the result of `JSON.parse`. If parsing fails, the original value will
+remain.
+
+### cookieParser.JSONCookie(str)
+
+Parse a cookie value as a JSON cookie. This will return the parsed JSON value
+if it was a JSON cookie, otherwise, it will return the passed value.
+
+### cookieParser.JSONCookies(cookies)
+
+Given an object, this will iterate over the keys and call `JSONCookie` on each
+value, replacing the original value with the parsed value. This returns the
+same object that was passed in.
+
+### cookieParser.signedCookie(str, secret)
+
+Parse a cookie value as a signed cookie. This will return the parsed unsigned
+value if it was a signed cookie and the signature was valid. If the value was
+not signed, the original value is returned. If the value was signed but the
+signature could not be validated, `false` is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+### cookieParser.signedCookies(cookies, secret)
+
+Given an object, this will iterate over the keys and check if any value is a
+signed cookie. If it is a signed cookie and the signature is valid, the key
+will be deleted from the object and added to the new object that is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+## Example
+
+```js
+var express = require('express');
+var cookieParser = require('cookie-parser');
+
+var app = express();
+app.use(cookieParser());
+
+app.get('/', function (req, res) {
+ // Cookies that have not been signed
+ console.log('Cookies: ', req.cookies);
+
+ // Cookies that have been signed
+ console.log('Signed Cookies: ', req.signedCookies);
+});
+
+app.listen(8080);
+
+// curl command that sends an HTTP request with two cookies
+// curl http://127.0.0.1:8080 --cookie "Cho=Kim;Greet=Hello"
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/cookie-parser/master?label=ci
+[ci-url]: https://github.com/expressjs/cookie-parser/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/cookie-parser/master
+[coveralls-url]: https://coveralls.io/r/expressjs/cookie-parser?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/cookie-parser
+[npm-url]: https://npmjs.org/package/cookie-parser
+[npm-version-image]: https://badgen.net/npm/v/cookie-parser
diff --git a/astro/src/content/resources/it/middleware/cors.md b/astro/src/content/resources/it/middleware/cors.md
new file mode 100644
index 0000000000..55d70922cb
--- /dev/null
+++ b/astro/src/content/resources/it/middleware/cors.md
@@ -0,0 +1,261 @@
+---
+title: Express cors middleware
+module: cors
+---
+
+# cors
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+CORS is a [Node.js](https://nodejs.org/en/) package for providing a [Connect](https://github.com/senchalabs/connect)/[Express](https://expressjs.com/) middleware that can be used to enable [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS) with various options.
+
+- [Installation](#installation)
+- [Usage](#usage)
+ - [Simple Usage](#simple-usage-enable-all-cors-requests)
+ - [Enable CORS for a Single Route](#enable-cors-for-a-single-route)
+ - [Configuring CORS](#configuring-cors)
+ - [Configuring CORS w/ Dynamic Origin](#configuring-cors-w-dynamic-origin)
+ - [Enabling CORS Pre-Flight](#enabling-cors-pre-flight)
+ - [Customizing CORS Settings Dynamically per Request](#customizing-cors-settings-dynamically-per-request)
+- [Configuration Options](#configuration-options)
+- [License](#license)
+- [Original Author](#original-author)
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/downloading-and-installing-packages-locally):
+
+```sh
+$ npm install cors
+```
+
+## Usage
+
+### Simple Usage (Enable _All_ CORS Requests)
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.use(cors());
+
+app.get('/products/:id', function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for all origins!' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Enable CORS for a Single Route
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.get('/products/:id', cors(), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for a Single Route' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Configuring CORS
+
+See the [configuration options](#configuration-options) for details.
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+var corsOptions = {
+ origin: 'http://example.com',
+ optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
+};
+
+app.get('/products/:id', cors(corsOptions), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for only example.com.' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Configuring CORS w/ Dynamic Origin
+
+This module supports validating the origin dynamically using a function provided
+to the `origin` option. This function will be passed a string that is the origin
+(or `undefined` if the request has no origin), and a `callback` with the signature
+`callback(error, origin)`.
+
+The `origin` argument to the callback can be any value allowed for the `origin`
+option of the middleware, except a function. See the
+[configuration options](#configuration-options) section for more information on all
+the possible value types.
+
+This function is designed to allow the dynamic loading of allowed origin(s) from
+a backing datasource, like a database.
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+var corsOptions = {
+ origin: function (origin, callback) {
+ // db.loadOrigins is an example call to load
+ // a list of origins from a backing database
+ db.loadOrigins(function (error, origins) {
+ callback(error, origins);
+ });
+ },
+};
+
+app.get('/products/:id', cors(corsOptions), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for an allowed domain.' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Enabling CORS Pre-Flight
+
+Certain CORS requests are considered 'complex' and require an initial
+`OPTIONS` request (called the "pre-flight request"). An example of a
+'complex' CORS request is one that uses an HTTP verb other than
+GET/HEAD/POST (such as DELETE) or that uses custom headers. To enable
+pre-flighting, you must add a new OPTIONS handler for the route you want
+to support:
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.options('/products/:id', cors()); // enable pre-flight request for DELETE request
+app.del('/products/:id', cors(), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for all origins!' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+You can also enable pre-flight across-the-board like so:
+
+```javascript
+app.options('*', cors()); // include before other routes
+```
+
+NOTE: When using this middleware as an application level middleware (for
+example, `app.use(cors())`), pre-flight requests are already handled for all
+routes.
+
+### Customizing CORS Settings Dynamically per Request
+
+For APIs that require different CORS configurations for specific routes or requests, you can dynamically generate CORS options based on the incoming request. The `cors` middleware allows you to achieve this by passing a function instead of static options. This function is called for each incoming request and must use the callback pattern to return the appropriate CORS options.
+
+The function accepts:
+
+1. **`req`**:
+ - The incoming request object.
+
+2. **`callback(error, corsOptions)`**:
+ - A function used to return the computed CORS options.
+ - **Arguments**:
+ - **`error`**: Pass `null` if there’s no error, or an error object to indicate a failure.
+ - **`corsOptions`**: An object specifying the CORS policy for the current request.
+
+Here’s an example that handles both public routes and restricted, credential-sensitive routes:
+
+```javascript
+var dynamicCorsOptions = function (req, callback) {
+ var corsOptions;
+ if (req.path.startsWith('/auth/connect/')) {
+ corsOptions = {
+ origin: 'http://mydomain.com', // Allow only a specific origin
+ credentials: true, // Enable cookies and credentials
+ };
+ } else {
+ corsOptions = { origin: '*' }; // Allow all origins for other routes
+ }
+ callback(null, corsOptions);
+};
+
+app.use(cors(dynamicCorsOptions));
+
+app.get('/auth/connect/twitter', function (req, res) {
+ res.send('CORS dynamically applied for Twitter authentication.');
+});
+
+app.get('/public', function (req, res) {
+ res.send('Public data with open CORS.');
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+## Configuration Options
+
+- `origin`: Configures the **Access-Control-Allow-Origin** CORS header. Possible values:
+ - `Boolean` - set `origin` to `true` to reflect the [request origin](https://datatracker.ietf.org/doc/html/draft-abarth-origin-09), as defined by `req.header('Origin')`, or set it to `false` to disable CORS.
+ - `String` - set `origin` to a specific origin. For example, if you set it to
+ - `"http://example.com"` only requests from "http://example.com" will be allowed.
+ - `"*"` for all domains to be allowed.
+ - `RegExp` - set `origin` to a regular expression pattern which will be used to test the request origin. If it's a match, the request origin will be reflected. For example the pattern `/example\.com$/` will reflect any request that is coming from an origin ending with "example.com".
+ - `Array` - set `origin` to an array of valid origins. Each origin can be a `String` or a `RegExp`. For example `["http://example1.com", /\.example2\.com$/]` will accept any request from "http://example1.com" or from a subdomain of "example2.com".
+ - `Function` - set `origin` to a function implementing some custom logic. The function takes the request origin as the first parameter and a callback (called as `callback(err, origin)`, where `origin` is a non-function value of the `origin` option) as the second.
+- `methods`: Configures the **Access-Control-Allow-Methods** CORS header. Expects a comma-delimited string (ex: 'GET,PUT,POST') or an array (ex: `['GET', 'PUT', 'POST']`).
+- `allowedHeaders`: Configures the **Access-Control-Allow-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Type,Authorization') or an array (ex: `['Content-Type', 'Authorization']`). If not specified, defaults to reflecting the headers specified in the request's **Access-Control-Request-Headers** header.
+- `exposedHeaders`: Configures the **Access-Control-Expose-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Range,X-Content-Range') or an array (ex: `['Content-Range', 'X-Content-Range']`). If not specified, no custom headers are exposed.
+- `credentials`: Configures the **Access-Control-Allow-Credentials** CORS header. Set to `true` to pass the header, otherwise it is omitted.
+- `maxAge`: Configures the **Access-Control-Max-Age** CORS header. Set to an integer to pass the header, otherwise it is omitted.
+- `preflightContinue`: Pass the CORS preflight response to the next handler.
+- `optionsSuccessStatus`: Provides a status code to use for successful `OPTIONS` requests, since some legacy browsers (IE11, various SmartTVs) choke on `204`.
+
+The default configuration is the equivalent of:
+
+```json
+{
+ "origin": "*",
+ "methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
+ "preflightContinue": false,
+ "optionsSuccessStatus": 204
+}
+```
+
+For details on the effect of each CORS header, read [this](https://web.dev/articles/cross-origin-resource-sharing) article.
+
+## License
+
+[MIT License](http://www.opensource.org/licenses/mit-license.php)
+
+## Original Author
+
+[Troy Goode](https://github.com/TroyGoode) ([troygoode@gmail.com](mailto:troygoode@gmail.com))
+
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/cors/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/cors?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/cors.svg
+[downloads-url]: https://npmjs.com/package/cors
+[github-actions-ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/cors/ci.yml?branch=master&label=ci
+[github-actions-ci-url]: https://github.com/expressjs/cors?query=workflow%3Aci
+[npm-image]: https://img.shields.io/npm/v/cors.svg
+[npm-url]: https://npmjs.com/package/cors
diff --git a/astro/src/content/resources/it/middleware/errorhandler.md b/astro/src/content/resources/it/middleware/errorhandler.md
new file mode 100644
index 0000000000..20df618320
--- /dev/null
+++ b/astro/src/content/resources/it/middleware/errorhandler.md
@@ -0,0 +1,133 @@
+---
+title: Express errorhandler middleware
+module: errorhandler
+---
+
+# errorhandler
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Development-only error handler middleware.
+
+This middleware is only intended to be used in a development environment, as
+the _full error stack traces and internal details of any object passed to this
+module_ will be sent back to the client when an error occurs.
+
+When an object is provided to Express as an error, this module will display
+as much about this object as possible, and will do so by using content negotiation
+for the response between HTML, JSON, and plain text.
+
+- When the object is a standard `Error` object, the string provided by the
+ `stack` property will be returned in HTML/text responses.
+- When the object is a non-`Error` object, the result of
+ [util.inspect](https://nodejs.org/api/util.html#util_util_inspect_object_options)
+ will be returned in HTML/text responses.
+- For JSON responses, the result will be an object with all enumerable properties
+ from the object in the response.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install errorhandler
+```
+
+## API
+
+
+
+```js
+var errorhandler = require('errorhandler');
+```
+
+### errorhandler(options)
+
+Create new middleware to handle errors and respond with content negotiation.
+
+#### Options
+
+Error handler accepts these properties in the options object.
+
+##### log
+
+Provide a function to be called with the error and a string representation of
+the error. Can be used to write the error to any desired location, or set to
+`false` to only send the error back in the response. Called as
+`log(err, str, req, res)` where `err` is the `Error` object, `str` is a string
+representation of the error, `req` is the request object and `res` is the
+response object (note, this function is invoked _after_ the response has been
+written).
+
+The default value for this option is `true` unless `process.env.NODE_ENV === 'test'`.
+
+Possible values:
+
+- `true`: Log errors using `console.error(str)`.
+- `false`: Only send the error back in the response.
+- A function: pass the error to a function for handling.
+
+## Examples
+
+### Simple example
+
+Basic example of adding this middleware as the error handler only in development
+with `connect` (`express` also can be used in this example).
+
+```js
+var connect = require('connect');
+var errorhandler = require('errorhandler');
+
+var app = connect();
+
+// assumes NODE_ENV is set by the user
+if (process.env.NODE_ENV === 'development') {
+ // only use in development
+ app.use(errorhandler());
+}
+```
+
+### Custom output location
+
+Sometimes you may want to output the errors to a different location than STDERR
+during development, like a system notification, for example.
+
+
+
+```js
+var connect = require('connect');
+var errorhandler = require('errorhandler');
+var notifier = require('node-notifier');
+
+var app = connect();
+
+// assumes NODE_ENV is set by the user
+if (process.env.NODE_ENV === 'development') {
+ // only use in development
+ app.use(errorhandler({ log: errorNotification }));
+}
+
+function errorNotification(err, str, req) {
+ var title = 'Error in ' + req.method + ' ' + req.url;
+
+ notifier.notify({
+ title: title,
+ message: str,
+ });
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/errorhandler/master
+[coveralls-url]: https://coveralls.io/r/expressjs/errorhandler?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/errorhandler
+[npm-url]: https://npmjs.org/package/errorhandler
+[npm-version-image]: https://badgen.net/npm/v/errorhandler
diff --git a/astro/src/content/resources/it/middleware/method-override.md b/astro/src/content/resources/it/middleware/method-override.md
new file mode 100644
index 0000000000..7b97ab855e
--- /dev/null
+++ b/astro/src/content/resources/it/middleware/method-override.md
@@ -0,0 +1,187 @@
+---
+title: Express method-override middleware
+module: method-override
+---
+
+# method-override
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][travis-image]][travis-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Lets you use HTTP verbs such as PUT or DELETE in places where the client doesn't support it.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install method-override
+```
+
+## API
+
+**NOTE** It is very important that this module is used **before** any module that
+needs to know the method of the request (for example, it _must_ be used prior to
+the `csurf` module).
+
+### methodOverride(getter, options)
+
+Create a new middleware function to override the `req.method` property with a new
+value. This value will be pulled from the provided `getter`.
+
+- `getter` - The getter to use to look up the overridden request method for the request. (default: `X-HTTP-Method-Override`)
+- `options.methods` - The allowed methods the original request must be in to check for a method override value. (default: `['POST']`)
+
+If the found method is supported by node.js core, then `req.method` will be set to
+this value, as if it has originally been that value. The previous `req.method`
+value will be stored in `req.originalMethod`.
+
+#### getter
+
+This is the method of getting the override value from the request. If a function is provided,
+the `req` is passed as the first argument, the `res` as the second argument and the method is
+expected to be returned. If a string is provided, the string is used to look up the method
+with the following rules:
+
+- If the string starts with `X-`, then it is treated as the name of a header and that header
+ is used for the method override. If the request contains the same header multiple times, the
+ first occurrence is used.
+- All other strings are treated as a key in the URL query string.
+
+#### options.methods
+
+This allows the specification of what methods(s) the request _MUST_ be in in order to check for
+the method override value. This defaults to only `POST` methods, which is the only method the
+override should arrive in. More methods may be specified here, but it may introduce security
+issues and cause weird behavior when requests travel through caches. This value is an array
+of methods in upper-case. `null` can be specified to allow all methods.
+
+## Examples
+
+### override using a header
+
+To use a header to override the method, specify the header name
+as a string argument to the `methodOverride` function. To then make
+the call, send a `POST` request to a URL with the overridden method
+as the value of that header. This method of using a header would
+typically be used in conjunction with `XMLHttpRequest` on implementations
+that do not support the method you are trying to use.
+
+```js
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// override with the X-HTTP-Method-Override header in the request
+app.use(methodOverride('X-HTTP-Method-Override'));
+```
+
+Example call with header override using `XMLHttpRequest`:
+
+
+
+```js
+const xhr = new XMLHttpRequest();
+xhr.onload = onload;
+xhr.open('post', '/resource', true);
+xhr.setRequestHeader('X-HTTP-Method-Override', 'DELETE');
+xhr.send();
+
+function onload() {
+ alert('got response: ' + this.responseText);
+}
+```
+
+### override using a query value
+
+To use a query string value to override the method, specify the query
+string key as a string argument to the `methodOverride` function. To
+then make the call, send a `POST` request to a URL with the overridden
+method as the value of that query string key. This method of using a
+query value would typically be used in conjunction with plain HTML
+`
+```
+
+### multiple format support
+
+```js
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// override with different headers; last one takes precedence
+app.use(methodOverride('X-HTTP-Method')); // Microsoft
+app.use(methodOverride('X-HTTP-Method-Override')); // Google/GData
+app.use(methodOverride('X-Method-Override')); // IBM
+```
+
+### custom logic
+
+You can implement any kind of custom logic with a function for the `getter`. The following
+implements the logic for looking in `req.body` that was in `method-override@1`:
+
+```js
+const bodyParser = require('body-parser');
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// NOTE: when using req.body, you must fully parse the request body
+// before you call methodOverride() in your middleware stack,
+// otherwise req.body will not be populated.
+app.use(bodyParser.urlencoded());
+app.use(
+ methodOverride(function (req, res) {
+ if (req.body && typeof req.body === 'object' && '_method' in req.body) {
+ // look in urlencoded POST bodies and delete it
+ const method = req.body._method;
+ delete req.body._method;
+ return method;
+ }
+ })
+);
+```
+
+Example call with query override using HTML `
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/method-override.svg
+[npm-url]: https://npmjs.org/package/method-override
+[travis-image]: https://img.shields.io/travis/expressjs/method-override/master.svg
+[travis-url]: https://travis-ci.org/expressjs/method-override
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/method-override/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/method-override?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/method-override.svg
+[downloads-url]: https://npmjs.org/package/method-override
diff --git a/astro/src/content/resources/it/middleware/morgan.md b/astro/src/content/resources/it/middleware/morgan.md
new file mode 100644
index 0000000000..5319d93d57
--- /dev/null
+++ b/astro/src/content/resources/it/middleware/morgan.md
@@ -0,0 +1,458 @@
+---
+title: Express morgan middleware
+module: morgan
+---
+
+# morgan
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+HTTP request logger middleware for node.js
+
+> Named after [Dexter](http://en.wikipedia.org/wiki/Dexter_Morgan), a show you should not watch until completion.
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install morgan
+```
+
+## API
+
+
+
+```js
+var morgan = require('morgan');
+```
+
+### morgan(format, options)
+
+Create a new morgan logger middleware function using the given `format` and `options`.
+The `format` argument may be a string of a predefined name (see below for the names),
+a string of a format string, or a function that will produce a log entry.
+
+The `format` function will be called with three arguments `tokens`, `req`, and `res`,
+where `tokens` is an object with all defined tokens, `req` is the HTTP request and `res`
+is the HTTP response. The function is expected to return a string that will be the log
+line, or `undefined` / `null` to skip logging.
+
+#### Using a predefined format string
+
+
+
+```js
+morgan('tiny');
+```
+
+#### Using format string of predefined tokens
+
+
+
+```js
+morgan(':method :url :status :res[content-length] - :response-time ms');
+```
+
+#### Using a custom format function
+
+
+
+```js
+morgan(function (tokens, req, res) {
+ return [
+ tokens.method(req, res),
+ tokens.url(req, res),
+ tokens.status(req, res),
+ tokens.res(req, res, 'content-length'),
+ '-',
+ tokens['response-time'](req, res),
+ 'ms',
+ ].join(' ');
+});
+```
+
+#### Options
+
+Morgan accepts these properties in the options object.
+
+##### immediate
+
+Write log line on request instead of response. This means that a requests will
+be logged even if the server crashes, _but data from the response (like the
+response code, content length, etc.) cannot be logged_.
+
+##### skip
+
+Function to determine if logging is skipped, defaults to `false`. This function
+will be called as `skip(req, res)`.
+
+
+
+```js
+// EXAMPLE: only log error responses
+morgan('combined', {
+ skip: function (req, res) {
+ return res.statusCode < 400;
+ },
+});
+```
+
+##### stream
+
+Output stream for writing log lines, defaults to `process.stdout`.
+
+#### Predefined Formats
+
+There are various pre-defined formats provided:
+
+##### combined
+
+Standard Apache combined log output.
+
+```
+:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"
+# will output
+::1 - - [27/Nov/2024:06:21:42 +0000] "GET /combined HTTP/1.1" 200 2 "-" "curl/8.7.1"
+```
+
+##### common
+
+Standard Apache common log output.
+
+```
+:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length]
+# will output
+::1 - - [27/Nov/2024:06:21:46 +0000] "GET /common HTTP/1.1" 200 2
+```
+
+##### dev
+
+Concise output colored by response status for development use. The `:status`
+token will be colored green for success codes, red for server error codes,
+yellow for client error codes, cyan for redirection codes, and uncolored
+for information codes.
+
+```
+:method :url :status :response-time ms - :res[content-length]
+# will output
+GET /dev 200 0.224 ms - 2
+```
+
+##### short
+
+Shorter than default, also including response time.
+
+```
+:remote-addr :remote-user :method :url HTTP/:http-version :status :res[content-length] - :response-time ms
+# will output
+::1 - GET /short HTTP/1.1 200 2 - 0.283 ms
+```
+
+##### tiny
+
+The minimal output.
+
+```
+:method :url :status :res[content-length] - :response-time ms
+# will output
+GET /tiny 200 2 - 0.188 ms
+```
+
+#### Tokens
+
+##### Creating new tokens
+
+To define a token, simply invoke `morgan.token()` with the name and a callback function.
+This callback function is expected to return a string value. The value returned is then
+available as ":type" in this case:
+
+
+
+```js
+morgan.token('type', function (req, res) {
+ return req.headers['content-type'];
+});
+```
+
+Calling `morgan.token()` using the same name as an existing token will overwrite that
+token definition.
+
+The token function is expected to be called with the arguments `req` and `res`, representing
+the HTTP request and HTTP response. Additionally, the token can accept further arguments of
+it's choosing to customize behavior.
+
+##### :date[format]
+
+The current date and time in UTC. The available formats are:
+
+- `clf` for the common log format (`"10/Oct/2000:13:55:36 +0000"`)
+- `iso` for the common ISO 8601 date time format (`2000-10-10T13:55:36.000Z`)
+- `web` for the common RFC 1123 date time format (`Tue, 10 Oct 2000 13:55:36 GMT`)
+
+If no format is given, then the default is `web`.
+
+##### :http-version
+
+The HTTP version of the request.
+
+##### :method
+
+The HTTP method of the request.
+
+##### :pid
+
+The process ID of the Node.js process handling the request.
+
+##### :referrer
+
+The Referrer header of the request. This will use the standard mis-spelled Referer header if exists, otherwise Referrer.
+
+##### :remote-addr
+
+The remote address of the request. This will use `req.ip`, otherwise the standard `req.connection.remoteAddress` value (socket address).
+
+##### :remote-user
+
+The user authenticated as part of Basic auth for the request.
+
+##### :req[header]
+
+The given `header` of the request. If the header is not present, the
+value will be displayed as `"-"` in the log.
+
+##### :res[header]
+
+The given `header` of the response. If the header is not present, the
+value will be displayed as `"-"` in the log.
+
+##### :response-time[digits]
+
+The time between the request coming into `morgan` and when the response
+headers are written, in milliseconds.
+
+The `digits` argument is a number that specifies the number of digits to
+include on the number, defaulting to `3`, which provides microsecond precision.
+
+##### :status
+
+The status code of the response.
+
+If the request/response cycle completes before a response was sent to the
+client (for example, the TCP socket closed prematurely by a client aborting
+the request), then the status will be empty (displayed as `"-"` in the log).
+
+##### :total-time[digits]
+
+The time between the request coming into `morgan` and when the response
+has finished being written out to the connection, in milliseconds.
+
+The `digits` argument is a number that specifies the number of digits to
+include on the number, defaulting to `3`, which provides microsecond precision.
+
+##### :url
+
+The URL of the request. This will use `req.originalUrl` if exists, otherwise `req.url`.
+
+##### :user-agent
+
+The contents of the User-Agent header of the request.
+
+### morgan.compile(format)
+
+Compile a format string into a `format` function for use by `morgan`. A format string
+is a string that represents a single log line and can utilize token syntax.
+Tokens are references by `:token-name`. If tokens accept arguments, they can
+be passed using `[]`, for example: `:token-name[pretty]` would pass the string
+`'pretty'` as an argument to the token `token-name`.
+
+The function returned from `morgan.compile` takes three arguments `tokens`, `req`, and
+`res`, where `tokens` is object with all defined tokens, `req` is the HTTP request and
+`res` is the HTTP response. The function will return a string that will be the log line,
+or `undefined` / `null` to skip logging.
+
+Normally formats are defined using `morgan.format(name, format)`, but for certain
+advanced uses, this compile function is directly available.
+
+## Examples
+
+### express/connect
+
+Sample app that will log all request in the Apache combined format to STDOUT
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+
+var app = express();
+
+app.use(morgan('combined'));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### vanilla http server
+
+Sample app that will log all request in the Apache combined format to STDOUT
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var morgan = require('morgan');
+
+// create "middleware"
+var logger = morgan('combined');
+
+http.createServer(function (req, res) {
+ var done = finalhandler(req, res);
+ logger(req, res, function (err) {
+ if (err) return done(err);
+
+ // respond to request
+ res.setHeader('content-type', 'text/plain');
+ res.end('hello, world!');
+ });
+});
+```
+
+### write logs to a file
+
+#### single file
+
+Sample app that will log all requests in the Apache combined format to the file
+`access.log`.
+
+```js
+var express = require('express');
+var fs = require('fs');
+var morgan = require('morgan');
+var path = require('path');
+
+var app = express();
+
+// create a write stream (in append mode)
+var accessLogStream = fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' });
+
+// setup the logger
+app.use(morgan('combined', { stream: accessLogStream }));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+#### log file rotation
+
+Sample app that will log all requests in the Apache combined format to one log
+file per day in the `log/` directory using the
+[rotating-file-stream module](https://www.npmjs.com/package/rotating-file-stream).
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+var path = require('path');
+var rfs = require('rotating-file-stream'); // version 2.x
+
+var app = express();
+
+// create a rotating write stream
+var accessLogStream = rfs.createStream('access.log', {
+ interval: '1d', // rotate daily
+ path: path.join(__dirname, 'log'),
+});
+
+// setup the logger
+app.use(morgan('combined', { stream: accessLogStream }));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### split / dual logging
+
+The `morgan` middleware can be used as many times as needed, enabling
+combinations like:
+
+- Log entry on request and one on response
+- Log all requests to file, but errors to console
+- ... and more!
+
+Sample app that will log all requests to a file using Apache format, but
+error responses are logged to the console:
+
+```js
+var express = require('express');
+var fs = require('fs');
+var morgan = require('morgan');
+var path = require('path');
+
+var app = express();
+
+// log only 4xx and 5xx responses to console
+app.use(
+ morgan('dev', {
+ skip: function (req, res) {
+ return res.statusCode < 400;
+ },
+ })
+);
+
+// log all requests to access.log
+app.use(
+ morgan('common', {
+ stream: fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' }),
+ })
+);
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### use custom token formats
+
+Sample app that will use custom token formats. This adds an ID to all requests and displays it using the `:id` token.
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+var uuid = require('node-uuid');
+
+morgan.token('id', function getId(req) {
+ return req.id;
+});
+
+var app = express();
+
+app.use(assignId);
+app.use(morgan(':id :method :url :response-time'));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+
+function assignId(req, res, next) {
+ req.id = uuid.v4();
+ next();
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/morgan/master?label=ci
+[ci-url]: https://github.com/expressjs/morgan/actions/workflows/ci.yml
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/morgan/master
+[coveralls-url]: https://coveralls.io/r/expressjs/morgan?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/morgan
+[npm-url]: https://npmjs.org/package/morgan
+[npm-version-image]: https://badgen.net/npm/v/morgan
diff --git a/astro/src/content/resources/it/middleware/multer.md b/astro/src/content/resources/it/middleware/multer.md
new file mode 100644
index 0000000000..326786ab3d
--- /dev/null
+++ b/astro/src/content/resources/it/middleware/multer.md
@@ -0,0 +1,352 @@
+---
+title: Express multer middleware
+module: multer
+---
+
+# Multer [![NPM Version][npm-version-image]][npm-url] [![NPM Downloads][npm-downloads-image]][npm-url] [![Build Status][ci-image]][ci-url] [![Test Coverage][test-image]][test-url] [![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+
+Multer is a node.js middleware for handling `multipart/form-data`, which is primarily used for uploading files. It is written
+on top of [busboy](https://github.com/mscdex/busboy) for maximum efficiency.
+
+**NOTE**: Multer will not process any form which is not multipart (`multipart/form-data`).
+
+## Translations
+
+This README is also available in other languages:
+
+| | |
+| ------------------------------------------------------------------------------ | --------------- |
+| [العربية](https://github.com/expressjs/multer/blob/main/doc/README-ar.md) | Arabic |
+| [简体中文](https://github.com/expressjs/multer/blob/main/doc/README-zh-cn.md) | Chinese |
+| [Français](https://github.com/expressjs/multer/blob/main/doc/README-fr.md) | French |
+| [한국어](https://github.com/expressjs/multer/blob/main/doc/README-ko.md) | Korean |
+| [Português](https://github.com/expressjs/multer/blob/main/doc/README-pt-br.md) | Portuguese (BR) |
+| [Русский язык](https://github.com/expressjs/multer/blob/main/doc/README-ru.md) | Russian |
+| [Español](https://github.com/expressjs/multer/blob/main/doc/README-es.md) | Spanish |
+| [O'zbek tili](https://github.com/expressjs/multer/blob/main/doc/README-uz.md) | Uzbek |
+| [Việt Nam](https://github.com/expressjs/multer/blob/main/doc/README-vi.md) | Vietnamese |
+
+## Installation
+
+```sh
+$ npm install multer
+```
+
+## Usage
+
+Multer adds a `body` object and a `file` or `files` object to the `request` object. The `body` object contains the values of the text fields of the form, the `file` or `files` object contains the files uploaded via the form.
+
+Basic usage example:
+
+Don't forget the `enctype="multipart/form-data"` in your form.
+
+```html
+
+```
+
+```javascript
+const express = require('express');
+const multer = require('multer');
+const upload = multer({ dest: 'uploads/' });
+
+const app = express();
+
+app.post('/profile', upload.single('avatar'), function (req, res, next) {
+ // req.file is the `avatar` file
+ // req.body will hold the text fields, if there were any
+});
+
+app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
+ // req.files is array of `photos` files
+ // req.body will contain the text fields, if there were any
+});
+
+const uploadMiddleware = upload.fields([
+ { name: 'avatar', maxCount: 1 },
+ { name: 'gallery', maxCount: 8 },
+]);
+app.post('/cool-profile', uploadMiddleware, function (req, res, next) {
+ // req.files is an object (String -> Array) where fieldname is the key, and the value is array of files
+ //
+ // e.g.
+ // req.files['avatar'][0] -> File
+ // req.files['gallery'] -> Array
+ //
+ // req.body will contain the text fields, if there were any
+});
+```
+
+In case you need to handle a text-only multipart form, you should use the `.none()` method:
+
+```javascript
+const express = require('express');
+const app = express();
+const multer = require('multer');
+const upload = multer();
+
+app.post('/profile', upload.none(), function (req, res, next) {
+ // req.body contains the text fields
+});
+```
+
+Here's an example on how multer is used in a HTML form. Take special note of the `enctype="multipart/form-data"` and `name="uploaded_file"` fields:
+
+```html
+
+```
+
+Then in your javascript file you would add these lines to access both the file and the body. It is important that you use the `name` field value from the form in your upload function. This tells multer which field on the request it should look for the files in. If these fields aren't the same in the HTML form and on your server, your upload will fail:
+
+```javascript
+const multer = require('multer');
+const upload = multer({ dest: './public/data/uploads/' });
+app.post('/stats', upload.single('uploaded_file'), function (req, res) {
+ // req.file is the name of your file in the form above, here 'uploaded_file'
+ // req.body will hold the text fields, if there were any
+ console.log(req.file, req.body);
+});
+```
+
+## API
+
+### File information
+
+Each file contains the following information:
+
+| Key | Description | Note |
+| -------------- | --------------------------------------------- | --------------- |
+| `fieldname` | Field name specified in the form |
+| `originalname` | Name of the file on the user's computer |
+| `encoding` | Encoding type of the file |
+| `mimetype` | Mime type of the file |
+| `size` | Size of the file in bytes |
+| `destination` | The folder to which the file has been saved | `DiskStorage` |
+| `filename` | The name of the file within the `destination` | `DiskStorage` |
+| `path` | The full path to the uploaded file | `DiskStorage` |
+| `buffer` | A `Buffer` of the entire file | `MemoryStorage` |
+
+### `multer(opts)`
+
+Multer accepts an options object, the most basic of which is the `dest`
+property, which tells Multer where to upload the files. In case you omit the
+options object, the files will be kept in memory and never written to disk.
+
+By default, Multer will rename the files so as to avoid naming conflicts. The
+renaming function can be customized according to your needs.
+
+The following are the options that can be passed to Multer.
+
+| Key | Description |
+| ------------------- | --------------------------------------------------------- |
+| `dest` or `storage` | Where to store the files |
+| `fileFilter` | Function to control which files are accepted |
+| `limits` | Limits of the uploaded data |
+| `preservePath` | Keep the full path of files instead of just the base name |
+
+In an average web app, only `dest` might be required, and configured as shown in
+the following example.
+
+```javascript
+const upload = multer({ dest: 'uploads/' });
+```
+
+If you want more control over your uploads, you'll want to use the `storage`
+option instead of `dest`. Multer ships with storage engines `DiskStorage`
+and `MemoryStorage`; More engines are available from third parties.
+
+#### `.single(fieldname)`
+
+Accept a single file with the name `fieldname`. The single file will be stored
+in `req.file`.
+
+#### `.array(fieldname[, maxCount])`
+
+Accept an array of files, all with the name `fieldname`. Optionally error out if
+more than `maxCount` files are uploaded. The array of files will be stored in
+`req.files`.
+
+#### `.fields(fields)`
+
+Accept a mix of files, specified by `fields`. An object with arrays of files
+will be stored in `req.files`.
+
+`fields` should be an array of objects with `name` and optionally a `maxCount`.
+Example:
+
+```javascript
+[
+ { name: 'avatar', maxCount: 1 },
+ { name: 'gallery', maxCount: 8 },
+];
+```
+
+#### `.none()`
+
+Accept only text fields. If any file upload is made, error with code
+"LIMIT_UNEXPECTED_FILE" will be issued.
+
+#### `.any()`
+
+Accepts all files that comes over the wire. An array of files will be stored in
+`req.files`.
+
+**WARNING:** Make sure that you always handle the files that a user uploads.
+Never add multer as a global middleware since a malicious user could upload
+files to a route that you didn't anticipate. Only use this function on routes
+where you are handling the uploaded files.
+
+### `storage`
+
+#### `DiskStorage`
+
+The disk storage engine gives you full control on storing files to disk.
+
+```javascript
+const storage = multer.diskStorage({
+ destination: function (req, file, cb) {
+ cb(null, '/tmp/my-uploads');
+ },
+ filename: function (req, file, cb) {
+ const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
+ cb(null, file.fieldname + '-' + uniqueSuffix);
+ },
+});
+
+const upload = multer({ storage: storage });
+```
+
+There are two options available, `destination` and `filename`. They are both
+functions that determine where the file should be stored.
+
+`destination` is used to determine within which folder the uploaded files should
+be stored. This can also be given as a `string` (e.g. `'/tmp/uploads'`). If no
+`destination` is given, the operating system's default directory for temporary
+files is used.
+
+**Note:** You are responsible for creating the directory when providing
+`destination` as a function. When passing a string, multer will make sure that
+the directory is created for you.
+
+`filename` is used to determine what the file should be named inside the folder.
+If no `filename` is given, each file will be given a random name that doesn't
+include any file extension.
+
+**Note:** Multer will not append any file extension for you, your function
+should return a filename complete with a file extension.
+
+Each function gets passed both the request (`req`) and some information about
+the file (`file`) to aid with the decision.
+
+Note that `req.body` might not have been fully populated yet. It depends on the
+order that the client transmits fields and files to the server.
+
+For understanding the calling convention used in the callback (needing to pass
+null as the first param), refer to
+[Node.js error handling](https://web.archive.org/web/20220417042018/https://www.joyent.com/node-js/production/design/errors)
+
+#### `MemoryStorage`
+
+The memory storage engine stores the files in memory as `Buffer` objects. It
+doesn't have any options.
+
+```javascript
+const storage = multer.memoryStorage();
+const upload = multer({ storage: storage });
+```
+
+When using memory storage, the file info will contain a field called
+`buffer` that contains the entire file.
+
+**WARNING**: Uploading very large files, or relatively small files in large
+numbers very quickly, can cause your application to run out of memory when
+memory storage is used.
+
+### `limits`
+
+An object specifying the size limits of the following optional properties. Multer passes this object into busboy directly, and the details of the properties can be found on [busboy's page](https://github.com/mscdex/busboy#busboy-methods).
+
+The following integer values are available:
+
+| Key | Description | Default |
+| --------------- | ----------------------------------------------------------------------- | --------- |
+| `fieldNameSize` | Max field name size | 100 bytes |
+| `fieldSize` | Max field value size (in bytes) | 1MB |
+| `fields` | Max number of non-file fields | Infinity |
+| `fileSize` | For multipart forms, the max file size (in bytes) | Infinity |
+| `files` | For multipart forms, the max number of file fields | Infinity |
+| `parts` | For multipart forms, the max number of parts (fields + files) | Infinity |
+| `headerPairs` | For multipart forms, the max number of header key=>value pairs to parse | 2000 |
+
+Specifying the limits can help protect your site against denial of service (DoS) attacks.
+
+### `fileFilter`
+
+Set this to a function to control which files should be uploaded and which
+should be skipped. The function should look like this:
+
+```javascript
+function fileFilter(req, file, cb) {
+ // The function should call `cb` with a boolean
+ // to indicate if the file should be accepted
+
+ // To reject this file pass `false`, like so:
+ cb(null, false);
+
+ // To accept the file pass `true`, like so:
+ cb(null, true);
+
+ // You can always pass an error if something goes wrong:
+ cb(new Error("I don't have a clue!"));
+}
+```
+
+## Error handling
+
+When encountering an error, Multer will delegate the error to Express. You can
+display a nice error page using [the standard express way](http://expressjs.com/guide/error-handling.html).
+
+If you want to catch errors specifically from Multer, you can call the
+middleware function by yourself. Also, if you want to catch only [the Multer errors](https://github.com/expressjs/multer/blob/main/lib/multer-error.js), you can use the `MulterError` class that is attached to the `multer` object itself (e.g. `err instanceof multer.MulterError`).
+
+```javascript
+const multer = require('multer');
+const upload = multer().single('avatar');
+
+app.post('/profile', function (req, res) {
+ upload(req, res, function (err) {
+ if (err instanceof multer.MulterError) {
+ // A Multer error occurred when uploading.
+ } else if (err) {
+ // An unknown error occurred when uploading.
+ }
+
+ // Everything went fine.
+ });
+});
+```
+
+## Custom storage engine
+
+For information on how to build your own storage engine, see [Multer Storage Engine](https://github.com/expressjs/multer/blob/main/StorageEngine.md).
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://github.com/expressjs/multer/actions/workflows/ci.yml/badge.svg
+[ci-url]: https://github.com/expressjs/multer/actions/workflows/ci.yml
+[test-url]: https://coveralls.io/r/expressjs/multer?branch=main
+[test-image]: https://badgen.net/coveralls/c/github/expressjs/multer/main
+[npm-downloads-image]: https://badgen.net/npm/dm/multer
+[npm-url]: https://npmjs.org/package/multer
+[npm-version-image]: https://badgen.net/npm/v/multer
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/multer/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer
diff --git a/astro/src/content/resources/it/middleware/overview.md b/astro/src/content/resources/it/middleware/overview.md
new file mode 100755
index 0000000000..46217759e7
--- /dev/null
+++ b/astro/src/content/resources/it/middleware/overview.md
@@ -0,0 +1,40 @@
+---
+title: Express middleware
+description: Explore a list of Express.js middleware modules maintained by the Express team and the community, including built-in middleware and popular third-party modules.
+module: mw-home
+---
+
+## Express middleware
+
+The Express middleware modules listed here are maintained by the
+[Expressjs team](https://github.com/orgs/expressjs/people).
+
+| Middleware module | Description |
+| ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
+| [body-parser](/en/resources/middleware/body-parser) | Parse HTTP request body. |
+| [compression](/en/resources/middleware/compression) | Compress HTTP responses. |
+| [cookie-parser](/en/resources/middleware/cookie-parser) | Parse cookie header and populate `req.cookies`. See also [cookies](https://github.com/jed/cookies). |
+| [cookie-session](/en/resources/middleware/cookie-session) | Establish cookie-based sessions. |
+| [cors](/en/resources/middleware/cors) | Enable cross-origin resource sharing (CORS) with various options. |
+| [errorhandler](/en/resources/middleware/errorhandler) | Development error-handling/debugging. |
+| [method-override](/en/resources/middleware/method-override) | Override HTTP methods using header. |
+| [morgan](/en/resources/middleware/morgan) | HTTP request logger. |
+| [multer](/en/resources/middleware/multer) | Handle multi-part form data. |
+| [response-time](/en/resources/middleware/response-time) | Record HTTP response time. |
+| [serve-favicon](/en/resources/middleware/serve-favicon) | Serve a favicon. |
+| [serve-index](/en/resources/middleware/serve-index) | Serve directory listing for a given path. |
+| [serve-static](/en/resources/middleware/serve-static) | Serve static files. |
+| [session](/en/resources/middleware/session) | Establish server-based sessions (development only). |
+| [timeout](/en/resources/middleware/timeout) | Set a timeout perioHTTP request processing. |
+| [vhost](/en/resources/middleware/vhost) | Create virtual domains. |
+
+## Additional middleware modules
+
+These are some additional popular middleware modules.
+
+{% include community-caveat.html %}
+
+| Middleware module | Description |
+| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
+| [helmet](https://github.com/helmetjs/helmet) | Helps secure your apps by setting various HTTP headers. |
+| [passport](https://github.com/jaredhanson/passport) | Authentication using "strategies" such as OAuth, OpenID and many others. See [passportjs.org](https://passportjs.org/) for more information. |
diff --git a/astro/src/content/resources/it/middleware/response-time.md b/astro/src/content/resources/it/middleware/response-time.md
new file mode 100644
index 0000000000..f911f480f5
--- /dev/null
+++ b/astro/src/content/resources/it/middleware/response-time.md
@@ -0,0 +1,314 @@
+---
+title: Express response-time middleware
+module: response-time
+---
+
+# compression
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+[![Funding][funding-image]][funding-url]
+
+Node.js compression middleware.
+
+The following compression codings are supported:
+
+- deflate
+- gzip
+- br (brotli)
+
+**Note** Brotli is supported only since Node.js versions v11.7.0 and v10.16.0.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```bash
+$ npm install compression
+```
+
+## API
+
+```js
+var compression = require('compression');
+```
+
+### compression([options])
+
+Returns the compression middleware using the given `options`. The middleware
+will attempt to compress response bodies for all requests that traverse through
+the middleware, based on the given `options`.
+
+This middleware will never compress responses that include a `Cache-Control`
+header with the [`no-transform` directive](https://tools.ietf.org/html/rfc7234#section-5.2.2.4),
+as compressing will transform the body.
+
+#### Options
+
+`compression()` accepts these properties in the options object. In addition to
+those listed below, [zlib](https://nodejs.org/api/zlib.html) options may be
+passed in to the options object or
+[brotli](https://nodejs.org/api/zlib.html#zlib_class_brotlioptions) options.
+
+##### chunkSize
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_CHUNK`, or `16384`.
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### filter
+
+Type: `Function`
+
+A function to decide if the response should be considered for compression.
+This function is called as `filter(req, res)` and is expected to return
+`true` to consider the response for compression, or `false` to not compress
+the response.
+
+The default filter function uses the [compressible](https://www.npmjs.com/package/compressible)
+module to determine if `res.getHeader('Content-Type')` is compressible.
+
+##### level
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_COMPRESSION`, or `-1`
+
+The level of zlib compression to apply to responses. A higher level will result
+in better compression, but will take longer to complete. A lower level will
+result in less compression, but will be much faster.
+
+This is an integer in the range of `0` (no compression) to `9` (maximum
+compression). The special value `-1` can be used to mean the "default
+compression level", which is a default compromise between speed and
+compression (currently equivalent to level 6).
+
+- `-1` Default compression level (also `zlib.constants.Z_DEFAULT_COMPRESSION`).
+- `0` No compression (also `zlib.constants.Z_NO_COMPRESSION`).
+- `1` Fastest compression (also `zlib.constants.Z_BEST_SPEED`).
+- `2`
+- `3`
+- `4`
+- `5`
+- `6` (currently what `zlib.constants.Z_DEFAULT_COMPRESSION` points to).
+- `7`
+- `8`
+- `9` Best compression (also `zlib.constants.Z_BEST_COMPRESSION`).
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### memLevel
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_MEMLEVEL`, or `8`
+
+This specifies how much memory should be allocated for the internal compression
+state and is an integer in the range of `1` (minimum level) and `9` (maximum
+level).
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### brotli
+
+Type: `Object`
+
+This specifies the options for configuring Brotli. See [Node.js documentation](https://nodejs.org/api/zlib.html#class-brotlioptions) for a complete list of available options.
+
+##### strategy
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_STRATEGY`
+
+This is used to tune the compression algorithm. This value only affects the
+compression ratio, not the correctness of the compressed output, even if it
+is not set appropriately.
+
+- `zlib.constants.Z_DEFAULT_STRATEGY` Use for normal data.
+- `zlib.constants.Z_FILTERED` Use for data produced by a filter (or predictor).
+ Filtered data consists mostly of small values with a somewhat random
+ distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect is to force more Huffman coding and less
+ string matching; it is somewhat intermediate between `zlib.constants.Z_DEFAULT_STRATEGY`
+ and `zlib.constants.Z_HUFFMAN_ONLY`.
+- `zlib.constants.Z_FIXED` Use to prevent the use of dynamic Huffman codes, allowing
+ for a simpler decoder for special applications.
+- `zlib.constants.Z_HUFFMAN_ONLY` Use to force Huffman encoding only (no string match).
+- `zlib.constants.Z_RLE` Use to limit match distances to one (run-length encoding).
+ This is designed to be almost as fast as `zlib.constants.Z_HUFFMAN_ONLY`, but give
+ better compression for PNG image data.
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### threshold
+
+Type: `Number` or `String`
+Default: `1kb`
+
+The byte threshold for the response body size before compression is considered
+for the response. This is a number of bytes or any string
+accepted by the [bytes](https://www.npmjs.com/package/bytes) module.
+
+**Note** this is only an advisory setting; if the response size cannot be determined
+at the time the response headers are written, then it is assumed the response is
+_over_ the threshold. To guarantee the response size can be determined, be sure
+set a `Content-Length` response header.
+
+##### windowBits
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_WINDOWBITS`, or `15`
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### enforceEncoding
+
+Type: `String`
+Default: `identity`
+
+This is the default encoding to use when the client does not specify an encoding in the request's [Accept-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) header.
+
+#### .filter
+
+The default `filter` function. This is used to construct a custom filter
+function that is an extension of the default function.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+app.use(compression({ filter: shouldCompress }));
+
+function shouldCompress(req, res) {
+ if (req.headers['x-no-compression']) {
+ // don't compress responses with this request header
+ return false;
+ }
+
+ // fallback to standard filter function
+ return compression.filter(req, res);
+}
+```
+
+### res.flush
+
+This module adds a `res.flush()` method to force the partially-compressed
+response to be flushed to the client.
+
+## Examples
+
+### express
+
+When using this module with express, simply `app.use` the module as
+high as you like. Requests that pass through the middleware will be compressed.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress all responses
+app.use(compression());
+
+// add all routes
+```
+
+### Node.js HTTP server
+
+```js
+var compression = require('compression')({ threshold: 0 });
+var http = require('http');
+
+function createServer(fn) {
+ return http.createServer(function (req, res) {
+ compression(req, res, function (err) {
+ if (err) {
+ res.statusCode = err.status || 500;
+ res.end(err.message);
+ return;
+ }
+
+ fn(req, res);
+ });
+ });
+}
+
+var server = createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello world!');
+});
+
+server.listen(3000, () => {
+ console.log('> Listening at http://localhost:3000');
+});
+```
+
+### Server-Sent Events
+
+Because of the nature of compression this module does not work out of the box
+with server-sent events. To compress content, a window of the output needs to
+be buffered up in order to get good compression. Typically when using server-sent
+events, there are certain block of data that need to reach the client.
+
+You can achieve this by calling `res.flush()` when you need the data written to
+actually make it to the client.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress responses
+app.use(compression());
+
+// server-sent event stream
+app.get('/events', function (req, res) {
+ res.setHeader('Content-Type', 'text/event-stream');
+ res.setHeader('Cache-Control', 'no-cache');
+
+ // send a ping approx every 2 seconds
+ var timer = setInterval(function () {
+ res.write('data: ping\n\n');
+
+ // !!! this is the important part
+ res.flush();
+ }, 2000);
+
+ res.on('close', function () {
+ clearInterval(timer);
+ });
+});
+```
+
+## Contributing
+
+The Express.js project welcomes all constructive contributions. Contributions take many forms,
+from code for bug fixes and enhancements, to additions and fixes to documentation, additional
+tests, triaging incoming pull requests and issues, and more!
+
+See the [Contributing Guide](https://github.com/expressjs/express/blob/master/Contributing.md) for more technical details on contributing.
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://badgen.net/npm/v/compression
+[npm-url]: https://npmjs.org/package/compression
+[downloads-image]: https://badgen.net/npm/dm/compression
+[downloads-url]: https://npmcharts.com/compare/compression?minimal=true
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/compression/master?label=CI
+[github-actions-ci-url]: https://github.com/expressjs/compression/actions?query=workflow%3Aci
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/compression/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/compression
+[funding-url]: https://opencollective.com/express
+[funding-image]: https://badgen.net/badge/icon/sponsor/pink?icon=github&label=Open%20Collective
diff --git a/astro/src/content/resources/it/middleware/serve-favicon.md b/astro/src/content/resources/it/middleware/serve-favicon.md
new file mode 100644
index 0000000000..7a77865c6b
--- /dev/null
+++ b/astro/src/content/resources/it/middleware/serve-favicon.md
@@ -0,0 +1,156 @@
+---
+title: Express serve-favicon middleware
+module: serve-favicon
+---
+
+# serve-index
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Linux Build Status][ci-image]][ci-url]
+[![Windows Build][appveyor-image]][appveyor-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+Serves pages that contain directory listings for a given path.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-index
+```
+
+## API
+
+```js
+var serveIndex = require('serve-index');
+```
+
+### serveIndex(path, options)
+
+Returns middlware that serves an index of the directory in the given `path`.
+
+The `path` is based off the `req.url` value, so a `req.url` of `'/some/dir`
+with a `path` of `'public'` will look at `'public/some/dir'`. If you are using
+something like `express`, you can change the URL "base" with `app.use` (see
+the express example).
+
+#### Options
+
+Serve index accepts these properties in the options object.
+
+##### filter
+
+Apply this filter function to files. Defaults to `false`. The `filter` function
+is called for each file, with the signature `filter(filename, index, files, dir)`
+where `filename` is the name of the file, `index` is the array index, `files` is
+the array of files and `dir` is the absolute path the file is located (and thus,
+the directory the listing is for).
+
+##### hidden
+
+Display hidden (dot) files. Defaults to `false`.
+
+##### icons
+
+Display icons. Defaults to `false`.
+
+##### stylesheet
+
+Optional path to a CSS stylesheet. Defaults to a built-in stylesheet.
+
+##### template
+
+Optional path to an HTML template or a function that will render a HTML
+string. Defaults to a built-in template.
+
+When given a string, the string is used as a file path to load and then the
+following tokens are replaced in templates:
+
+- `{directory}` with the name of the directory.
+- `{files}` with the HTML of an unordered list of file links.
+- `{linked-path}` with the HTML of a link to the directory.
+- `{style}` with the specified stylesheet and embedded images.
+
+When given as a function, the function is called as `template(locals, callback)`
+and it needs to invoke `callback(error, htmlString)`. The following are the
+provided locals:
+
+- `directory` is the directory being displayed (where `/` is the root).
+- `displayIcons` is a Boolean for if icons should be rendered or not.
+- `fileList` is a sorted array of files in the directory. The array contains
+ objects with the following properties:
+ - `name` is the relative name for the file.
+ - `stat` is a `fs.Stats` object for the file.
+- `path` is the full filesystem path to `directory`.
+- `style` is the default stylesheet or the contents of the `stylesheet` option.
+- `viewName` is the view name provided by the `view` option.
+
+##### view
+
+Display mode. `tiles` and `details` are available. Defaults to `tiles`.
+
+## Examples
+
+### Serve directory indexes with vanilla node.js http server
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var serveIndex = require('serve-index');
+var serveStatic = require('serve-static');
+
+// Serve directory indexes for public/ftp folder (with icons)
+var index = serveIndex('public/ftp', { icons: true });
+
+// Serve up public/ftp folder files
+var serve = serveStatic('public/ftp');
+
+// Create server
+var server = http.createServer(function onRequest(req, res) {
+ var done = finalhandler(req, res);
+ serve(req, res, function onNext(err) {
+ if (err) return done(err);
+ index(req, res, done);
+ });
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve directory indexes with express
+
+```js
+var express = require('express');
+var serveIndex = require('serve-index');
+
+var app = express();
+
+// Serve URLs like /ftp/thing as public/ftp/thing
+// The express.static serves the file contents
+// The serveIndex is this module serving the directory
+app.use('/ftp', express.static('public/ftp'), serveIndex('public/ftp', { icons: true }));
+
+// Listen
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE). The [Silk](http://www.famfamfam.com/lab/icons/silk/) icons
+are created by/copyright of [FAMFAMFAM](http://www.famfamfam.com/).
+
+[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/serve-index/master.svg?label=windows
+[appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index
+[ci-image]: https://badgen.net/github/checks/expressjs/serve-index/master?label=ci
+[ci-url]: https://github.com/expressjs/serve-index/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/serve-index/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-index?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/serve-index.svg
+[downloads-url]: https://npmjs.org/package/serve-index
+[npm-image]: https://img.shields.io/npm/v/serve-index.svg
+[npm-url]: https://npmjs.org/package/serve-index
diff --git a/astro/src/content/resources/it/middleware/serve-index.md b/astro/src/content/resources/it/middleware/serve-index.md
new file mode 100644
index 0000000000..da03cf94b2
--- /dev/null
+++ b/astro/src/content/resources/it/middleware/serve-index.md
@@ -0,0 +1,156 @@
+---
+title: Express serve-index middleware
+module: serve-index
+---
+
+# serve-index
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Linux Build Status][ci-image]][ci-url]
+[![Windows Build][appveyor-image]][appveyor-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+Serves pages that contain directory listings for a given path.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-index
+```
+
+## API
+
+```js
+var serveIndex = require('serve-index');
+```
+
+### serveIndex(path, options)
+
+Returns middlware that serves an index of the directory in the given `path`.
+
+The `path` is based off the `req.url` value, so a `req.url` of `'/some/dir`
+with a `path` of `'public'` will look at `'public/some/dir'`. If you are using
+something like `express`, you can change the URL "base" with `app.use` (see
+the express example).
+
+#### Options
+
+Serve index accepts these properties in the options object.
+
+##### filter
+
+Apply this filter function to files. Defaults to `false`. The `filter` function
+is called for each file, with the signature `filter(filename, index, files, dir)`
+where `filename` is the name of the file, `index` is the array index, `files` is
+the array of files and `dir` is the absolute path the file is located (and thus,
+the directory the listing is for).
+
+##### hidden
+
+Display hidden (dot) files. Defaults to `false`.
+
+##### icons
+
+Display icons. Defaults to `false`.
+
+##### stylesheet
+
+Optional path to a CSS stylesheet. Defaults to a built-in stylesheet.
+
+##### template
+
+Optional path to an HTML template or a function that will render a HTML
+string. Defaults to a built-in template.
+
+When given a string, the string is used as a file path to load and then the
+following tokens are replaced in templates:
+
+- `{directory}` with the name of the directory.
+- `{files}` with the HTML of an unordered list of file links.
+- `{linked-path}` with the HTML of a link to the directory.
+- `{style}` with the specified stylesheet and embedded images.
+
+When given as a function, the function is called as `template(locals, callback)`
+and it needs to invoke `callback(error, htmlString)`. The following are the
+provided locals:
+
+- `directory` is the directory being displayed (where `/` is the root).
+- `displayIcons` is a Boolean for if icons should be rendered or not.
+- `fileList` is a sorted array of files in the directory. The array contains
+ objects with the following properties:
+ - `name` is the relative name for the file.
+ - `stat` is a `fs.Stats` object for the file.
+- `path` is the full filesystem path to `directory`.
+- `style` is the default stylesheet or the contents of the `stylesheet` option.
+- `viewName` is the view name provided by the `view` option.
+
+##### view
+
+Display mode. `tiles` and `details` are available. Defaults to `tiles`.
+
+## Examples
+
+### Serve directory indexes with vanilla node.js http server
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var serveIndex = require('serve-index');
+var serveStatic = require('serve-static');
+
+// Serve directory indexes for public/ftp folder (with icons)
+var index = serveIndex('public/ftp', { icons: true });
+
+// Serve up public/ftp folder files
+var serve = serveStatic('public/ftp');
+
+// Create server
+var server = http.createServer(function onRequest(req, res) {
+ var done = finalhandler(req, res);
+ serve(req, res, function onNext(err) {
+ if (err) return done(err);
+ index(req, res, done);
+ });
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve directory indexes with express
+
+```js
+var express = require('express');
+var serveIndex = require('serve-index');
+
+var app = express();
+
+// Serve URLs like /ftp/thing as public/ftp/thing
+// The express.static serves the file contents
+// The serveIndex is this module serving the directory
+app.use('/ftp', express.static('public/ftp'), serveIndex('public/ftp', { icons: true }));
+
+// Listen
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE). The [Silk](http://www.famfamfam.com/lab/icons/silk/) icons
+are created by/copyright of [FAMFAMFAM](http://www.famfamfam.com/).
+
+[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/serve-index/master.svg?label=windows
+[appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index
+[ci-image]: https://badgen.net/github/checks/expressjs/serve-index/master?label=ci
+[ci-url]: https://github.com/expressjs/serve-index/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/serve-index/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-index?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/serve-index.svg
+[downloads-url]: https://npmjs.org/package/serve-index
+[npm-image]: https://img.shields.io/npm/v/serve-index.svg
+[npm-url]: https://npmjs.org/package/serve-index
diff --git a/astro/src/content/resources/it/middleware/serve-static.md b/astro/src/content/resources/it/middleware/serve-static.md
new file mode 100644
index 0000000000..b048165d7b
--- /dev/null
+++ b/astro/src/content/resources/it/middleware/serve-static.md
@@ -0,0 +1,260 @@
+---
+title: Express serve-static middleware
+module: serve-static
+---
+
+# serve-static
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![CI][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-static
+```
+
+## API
+
+```js
+const serveStatic = require('serve-static');
+```
+
+### serveStatic(root, options)
+
+Create a new middleware function to serve files from within a given root
+directory. The file to serve will be determined by combining `req.url`
+with the provided root directory. When a file is not found, instead of
+sending a 404 response, this module will instead call `next()` to move on
+to the next middleware, allowing for stacking and fall-backs.
+
+#### Options
+
+##### acceptRanges
+
+Enable or disable accepting ranged requests, defaults to true.
+Disabling this will not send `Accept-Ranges` and ignore the contents
+of the `Range` request header.
+
+##### cacheControl
+
+Enable or disable setting `Cache-Control` response header, defaults to
+true. Disabling this will ignore the `immutable` and `maxAge` options.
+
+##### dotfiles
+
+Set how "dotfiles" are treated when encountered. A dotfile is a file
+or directory that begins with a dot ("."). Note this check is done on
+the path itself without checking if the path actually exists on the
+disk. If `root` is specified, only the dotfiles above the root are
+checked (i.e. the root itself can be within a dotfile when set
+to "deny").
+
+- `'allow'` No special treatment for dotfiles.
+- `'deny'` Deny a request for a dotfile and 403/`next()`.
+- `'ignore'` Pretend like the dotfile does not exist and 404/`next()`.
+
+The default value is `'ignore'`.
+
+##### etag
+
+Enable or disable etag generation, defaults to true.
+
+##### extensions
+
+Set file extension fallbacks. When set, if a file is not found, the given
+extensions will be added to the file name and search for. The first that
+exists will be served. Example: `['html', 'htm']`.
+
+The default value is `false`.
+
+##### fallthrough
+
+Set the middleware to have client errors fall-through as just unhandled
+requests, otherwise forward a client error. The difference is that client
+errors like a bad request or a request to a non-existent file will cause
+this middleware to simply `next()` to your next middleware when this value
+is `true`. When this value is `false`, these errors (even 404s), will invoke
+`next(err)`.
+
+Typically `true` is desired such that multiple physical directories can be
+mapped to the same web address or for routes to fill in non-existent files.
+
+The value `false` can be used if this middleware is mounted at a path that
+is designed to be strictly a single file system directory, which allows for
+short-circuiting 404s for less overhead. This middleware will also reply to
+all methods.
+
+The default value is `true`.
+
+##### immutable
+
+Enable or disable the `immutable` directive in the `Cache-Control` response
+header, defaults to `false`. If set to `true`, the `maxAge` option should
+also be specified to enable caching. The `immutable` directive will prevent
+supported clients from making conditional requests during the life of the
+`maxAge` option to check if the file has changed.
+
+##### index
+
+By default this module will send "index.html" files in response to a request
+on a directory. To disable this set `false` or to supply a new index pass a
+string or an array in preferred order.
+
+##### lastModified
+
+Enable or disable `Last-Modified` header, defaults to true. Uses the file
+system's last modified value.
+
+##### maxAge
+
+Provide a max-age in milliseconds for http caching, defaults to 0. This
+can also be a string accepted by the [ms](https://www.npmjs.org/package/ms#readme)
+module.
+
+##### redirect
+
+Redirect to trailing "/" when the pathname is a dir. Defaults to `true`.
+
+##### setHeaders
+
+Function to set custom headers on response. Alterations to the headers need to
+occur synchronously. The function is called as `fn(res, path, stat)`, where
+the arguments are:
+
+- `res` the response object
+- `path` the file path that is being sent
+- `stat` the stat object of the file that is being sent
+
+## Examples
+
+### Serve files with vanilla node.js http server
+
+```js
+const finalhandler = require('finalhandler');
+const http = require('http');
+const serveStatic = require('serve-static');
+
+// Serve up public/ftp folder
+const serve = serveStatic('public/ftp', { index: ['index.html', 'index.htm'] });
+
+// Create server
+const server = http.createServer((req, res) => {
+ serve(req, res, finalhandler(req, res));
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve all files as downloads
+
+```js
+const contentDisposition = require('content-disposition');
+const finalhandler = require('finalhandler');
+const http = require('http');
+const serveStatic = require('serve-static');
+
+// Serve up public/ftp folder
+const serve = serveStatic('public/ftp', {
+ index: false,
+ setHeaders: setHeaders,
+});
+
+// Set header to force download
+function setHeaders(res, path) {
+ res.setHeader('Content-Disposition', contentDisposition(path));
+}
+
+// Create server
+const server = http.createServer((req, res) => {
+ serve(req, res, finalhandler(req, res));
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serving using express
+
+#### Simple
+
+This is a simple example of using Express.
+
+```js
+const express = require('express');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(serveStatic('public/ftp', { index: ['default.html', 'default.htm'] }));
+app.listen(3000);
+```
+
+#### Multiple roots
+
+This example shows a simple way to search through multiple directories.
+Files are searched for in `public-optimized/` first, then `public/` second
+as a fallback.
+
+```js
+const express = require('express');
+const path = require('path');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(serveStatic(path.join(__dirname, 'public-optimized')));
+app.use(serveStatic(path.join(__dirname, 'public')));
+app.listen(3000);
+```
+
+#### Different settings for paths
+
+This example shows how to set a different max age depending on the served
+file. In this example, HTML files are not cached, while everything else
+is for 1 day.
+
+```js
+const express = require('express');
+const path = require('path');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(
+ serveStatic(path.join(__dirname, 'public'), {
+ maxAge: '1d',
+ setHeaders: setCustomCacheControl,
+ })
+);
+
+app.listen(3000);
+
+function setCustomCacheControl(res, file) {
+ if (path.extname(file) === '.html') {
+ // Custom Cache-Control for HTML files
+ res.setHeader('Cache-Control', 'public, max-age=0');
+ }
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/serve-static/master
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-static?branch=master
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/serve-static/master?label=linux
+[github-actions-ci-url]: https://github.com/expressjs/serve-static/actions/workflows/ci.yml
+[node-image]: https://badgen.net/npm/node/serve-static
+[node-url]: https://nodejs.org/en/download/
+[npm-downloads-image]: https://badgen.net/npm/dm/serve-static
+[npm-url]: https://npmjs.org/package/serve-static
+[npm-version-image]: https://badgen.net/npm/v/serve-static
diff --git a/astro/src/content/resources/it/middleware/session.md b/astro/src/content/resources/it/middleware/session.md
new file mode 100644
index 0000000000..90f3837a42
--- /dev/null
+++ b/astro/src/content/resources/it/middleware/session.md
@@ -0,0 +1,1046 @@
+---
+title: Express session middleware
+module: session
+---
+
+# express-session
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][node-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install express-session
+```
+
+## API
+
+```js
+var session = require('express-session');
+```
+
+### session(options)
+
+Create a session middleware with the given `options`.
+
+**Note** Session data is _not_ saved in the cookie itself, just the session ID.
+Session data is stored server-side.
+
+**Note** Since version 1.5.0, the [`cookie-parser` middleware](https://www.npmjs.com/package/cookie-parser)
+no longer needs to be used for this module to work. This module now directly reads
+and writes cookies on `req`/`res`. Using `cookie-parser` may result in issues
+if the `secret` is not the same between this module and `cookie-parser`.
+
+**Warning** The default server-side session storage, `MemoryStore`, is _purposely_
+not designed for a production environment. It will leak memory under most
+conditions, does not scale past a single process, and is meant for debugging and
+developing.
+
+For a list of stores, see [compatible session stores](#compatible-session-stores).
+
+#### Options
+
+`express-session` accepts these properties in the options object.
+
+##### cookie
+
+Settings object for the session ID cookie. The default value is
+`{ path: '/', httpOnly: true, secure: false, maxAge: null }`.
+
+The following are options that can be set in this object.
+
+##### cookie.domain
+
+Specifies the value for the `Domain` `Set-Cookie` attribute. By default, no domain
+is set, and most clients will consider the cookie to apply to only the current
+domain.
+
+##### cookie.expires
+
+Specifies the `Date` object to be the value for the `Expires` `Set-Cookie` attribute.
+By default, no expiration is set, and most clients will consider this a
+"non-persistent cookie" and will delete it on a condition like exiting a web browser
+application.
+
+**Note** If both `expires` and `maxAge` are set in the options, then the last one
+defined in the object is what is used.
+
+**Note** The `expires` option should not be set directly; instead only use the `maxAge`
+option.
+
+##### cookie.httpOnly
+
+Specifies the `boolean` value for the `HttpOnly` `Set-Cookie` attribute. When truthy,
+the `HttpOnly` attribute is set, otherwise it is not. By default, the `HttpOnly`
+attribute is set.
+
+**Note** be careful when setting this to `true`, as compliant clients will not allow
+client-side JavaScript to see the cookie in `document.cookie`.
+
+##### cookie.maxAge
+
+Specifies the `number` (in milliseconds) to use when calculating the `Expires`
+`Set-Cookie` attribute. This is done by taking the current server time and adding
+`maxAge` milliseconds to the value to calculate an `Expires` datetime. By default,
+no maximum age is set.
+
+**Note** If both `expires` and `maxAge` are set in the options, then the last one
+defined in the object is what is used.
+
+##### cookie.partitioned
+
+Specifies the `boolean` value for the [`Partitioned` `Set-Cookie`](rfc-cutler-httpbis-partitioned-cookies)
+attribute. When truthy, the `Partitioned` attribute is set, otherwise it is not.
+By default, the `Partitioned` attribute is not set.
+
+**Note** This is an attribute that has not yet been fully standardized, and may
+change in the future. This also means many clients may ignore this attribute until
+they understand it.
+
+More information about can be found in [the proposal](https://github.com/privacycg/CHIPS).
+
+##### cookie.path
+
+Specifies the value for the `Path` `Set-Cookie`. By default, this is set to `'/'`, which
+is the root path of the domain.
+
+##### cookie.priority
+
+Specifies the `string` to be the value for the [`Priority` `Set-Cookie` attribute][rfc-west-cookie-priority-00-4.1].
+
+- `'low'` will set the `Priority` attribute to `Low`.
+- `'medium'` will set the `Priority` attribute to `Medium`, the default priority when not set.
+- `'high'` will set the `Priority` attribute to `High`.
+
+More information about the different priority levels can be found in
+[the specification][rfc-west-cookie-priority-00-4.1].
+
+**Note** This is an attribute that has not yet been fully standardized, and may change in the future.
+This also means many clients may ignore this attribute until they understand it.
+
+##### cookie.sameSite
+
+Specifies the `boolean` or `string` to be the value for the `SameSite` `Set-Cookie` attribute.
+By default, this is `false`.
+
+- `true` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
+- `false` will not set the `SameSite` attribute.
+- `'lax'` will set the `SameSite` attribute to `Lax` for lax same site enforcement.
+- `'none'` will set the `SameSite` attribute to `None` for an explicit cross-site cookie.
+- `'strict'` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
+
+More information about the different enforcement levels can be found in
+[the specification][rfc-6265bis-03-4.1.2.7].
+
+**Note** This is an attribute that has not yet been fully standardized, and may change in
+the future. This also means many clients may ignore this attribute until they understand it.
+
+**Note** There is a [draft spec](https://tools.ietf.org/html/draft-west-cookie-incrementalism-01)
+that requires that the `Secure` attribute be set to `true` when the `SameSite` attribute has been
+set to `'none'`. Some web browsers or other clients may be adopting this specification.
+
+##### cookie.secure
+
+Specifies the `boolean` value for the `Secure` `Set-Cookie` attribute. When truthy,
+the `Secure` attribute is set, otherwise it is not. By default, the `Secure`
+attribute is not set.
+
+**Note** be careful when setting this to `true`, as compliant clients will not send
+the cookie back to the server in the future if the browser does not have an HTTPS
+connection.
+
+Please note that `secure: true` is a **recommended** option. However, it requires
+an https-enabled website, i.e., HTTPS is necessary for secure cookies. If `secure`
+is set, and you access your site over HTTP, the cookie will not be set. If you
+have your node.js behind a proxy and are using `secure: true`, you need to set
+"trust proxy" in express:
+
+```js
+var app = express();
+app.set('trust proxy', 1); // trust first proxy
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ cookie: { secure: true },
+ })
+);
+```
+
+For using secure cookies in production, but allowing for testing in development,
+the following is an example of enabling this setup based on `NODE_ENV` in express:
+
+```js
+var app = express();
+var sess = {
+ secret: 'keyboard cat',
+ cookie: {},
+};
+
+if (app.get('env') === 'production') {
+ app.set('trust proxy', 1); // trust first proxy
+ sess.cookie.secure = true; // serve secure cookies
+}
+
+app.use(session(sess));
+```
+
+The `cookie.secure` option can also be set to the special value `'auto'` to have
+this setting automatically match the determined security of the connection. Be
+careful when using this setting if the site is available both as HTTP and HTTPS,
+as once the cookie is set on HTTPS, it will no longer be visible over HTTP. This
+is useful when the Express `"trust proxy"` setting is properly setup to simplify
+development vs production configuration.
+
+##### genid
+
+Function to call to generate a new session ID. Provide a function that returns
+a string that will be used as a session ID. The function is given `req` as the
+first argument if you want to use some value attached to `req` when generating
+the ID.
+
+The default value is a function which uses the `uid-safe` library to generate IDs.
+
+**NOTE** be careful to generate unique IDs so your sessions do not conflict.
+
+```js
+app.use(
+ session({
+ genid: function (req) {
+ return genuuid(); // use UUIDs for session IDs
+ },
+ secret: 'keyboard cat',
+ })
+);
+```
+
+##### name
+
+The name of the session ID cookie to set in the response (and read from in the
+request).
+
+The default value is `'connect.sid'`.
+
+**Note** if you have multiple apps running on the same hostname (this is just
+the name, i.e. `localhost` or `127.0.0.1`; different schemes and ports do not
+name a different hostname), then you need to separate the session cookies from
+each other. The simplest method is to simply set different `name`s per app.
+
+##### proxy
+
+Trust the reverse proxy when setting secure cookies (via the "X-Forwarded-Proto"
+header).
+
+The default value is `undefined`.
+
+- `true` The "X-Forwarded-Proto" header will be used.
+- `false` All headers are ignored and the connection is considered secure only
+ if there is a direct TLS/SSL connection.
+- `undefined` Uses the "trust proxy" setting from express
+
+##### resave
+
+Forces the session to be saved back to the session store, even if the session
+was never modified during the request. Depending on your store this may be
+necessary, but it can also create race conditions where a client makes two
+parallel requests to your server and changes made to the session in one
+request may get overwritten when the other request ends, even if it made no
+changes (this behavior also depends on what store you're using).
+
+The default value is `true`, but using the default has been deprecated,
+as the default will change in the future. Please research into this setting
+and choose what is appropriate to your use-case. Typically, you'll want
+`false`.
+
+How do I know if this is necessary for my store? The best way to know is to
+check with your store if it implements the `touch` method. If it does, then
+you can safely set `resave: false`. If it does not implement the `touch`
+method and your store sets an expiration date on stored sessions, then you
+likely need `resave: true`.
+
+##### rolling
+
+Force the session identifier cookie to be set on every response. The expiration
+is reset to the original [`maxAge`](#cookiemaxage), resetting the expiration
+countdown.
+
+The default value is `false`.
+
+With this enabled, the session identifier cookie will expire in
+[`maxAge`](#cookiemaxage) since the last response was sent instead of in
+[`maxAge`](#cookiemaxage) since the session was last modified by the server.
+
+This is typically used in conjunction with short, non-session-length
+[`maxAge`](#cookiemaxage) values to provide a quick timeout of the session data
+with reduced potential of it occurring during on going server interactions.
+
+**Note** When this option is set to `true` but the `saveUninitialized` option is
+set to `false`, the cookie will not be set on a response with an uninitialized
+session. This option only modifies the behavior when an existing session was
+loaded for the request.
+
+##### saveUninitialized
+
+Forces a session that is "uninitialized" to be saved to the store. A session is
+uninitialized when it is new but not modified. Choosing `false` is useful for
+implementing login sessions, reducing server storage usage, or complying with
+laws that require permission before setting a cookie. Choosing `false` will also
+help with race conditions where a client makes multiple parallel requests
+without a session.
+
+The default value is `true`, but using the default has been deprecated, as the
+default will change in the future. Please research into this setting and
+choose what is appropriate to your use-case.
+
+**Note** if you are using Session in conjunction with PassportJS, Passport
+will add an empty Passport object to the session for use after a user is
+authenticated, which will be treated as a modification to the session, causing
+it to be saved. _This has been fixed in PassportJS 0.3.0_
+
+##### secret
+
+**Required option**
+
+This is the secret used to sign the session ID cookie. The secret can be any type
+of value that is supported by Node.js `crypto.createHmac` (like a string or a
+`Buffer`). This can be either a single secret, or an array of multiple secrets. If
+an array of secrets is provided, only the first element will be used to sign the
+session ID cookie, while all the elements will be considered when verifying the
+signature in requests. The secret itself should be not easily parsed by a human and
+would best be a random set of characters. A best practice may include:
+
+- The use of environment variables to store the secret, ensuring the secret itself
+ does not exist in your repository.
+- Periodic updates of the secret, while ensuring the previous secret is in the
+ array.
+
+Using a secret that cannot be guessed will reduce the ability to hijack a session to
+only guessing the session ID (as determined by the `genid` option).
+
+Changing the secret value will invalidate all existing sessions. In order to rotate
+the secret without invalidating sessions, provide an array of secrets, with the new
+secret as first element of the array, and including previous secrets as the later
+elements.
+
+**Note** HMAC-256 is used to sign the session ID. For this reason, the secret should
+contain at least 32 bytes of entropy.
+
+##### store
+
+The session store instance, defaults to a new `MemoryStore` instance.
+
+##### unset
+
+Control the result of unsetting `req.session` (through `delete`, setting to `null`,
+etc.).
+
+The default value is `'keep'`.
+
+- `'destroy'` The session will be destroyed (deleted) when the response ends.
+- `'keep'` The session in the store will be kept, but modifications made during
+ the request are ignored and not saved.
+
+### req.session
+
+To store or access session data, simply use the request property `req.session`,
+which is (generally) serialized as JSON by the store, so nested objects
+are typically fine. For example below is a user-specific view counter:
+
+```js
+// Use the session middleware
+app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 } }));
+
+// Access the session as req.session
+app.get('/', function (req, res, next) {
+ if (req.session.views) {
+ req.session.views++;
+ res.setHeader('Content-Type', 'text/html');
+ res.write('views: ' + req.session.views + '
');
+ res.write('expires in: ' + req.session.cookie.maxAge / 1000 + 's
');
+ res.end();
+ } else {
+ req.session.views = 1;
+ res.end('welcome to the session demo. refresh!');
+ }
+});
+```
+
+#### Session.regenerate(callback)
+
+To regenerate the session simply invoke the method. Once complete,
+a new SID and `Session` instance will be initialized at `req.session`
+and the `callback` will be invoked.
+
+```js
+req.session.regenerate(function (err) {
+ // will have a new session here
+});
+```
+
+#### Session.destroy(callback)
+
+Destroys the session and will unset the `req.session` property.
+Once complete, the `callback` will be invoked.
+
+```js
+req.session.destroy(function (err) {
+ // cannot access session here
+});
+```
+
+#### Session.reload(callback)
+
+Reloads the session data from the store and re-populates the
+`req.session` object. Once complete, the `callback` will be invoked.
+
+```js
+req.session.reload(function (err) {
+ // session updated
+});
+```
+
+#### Session.save(callback)
+
+Save the session back to the store, replacing the contents on the store with the
+contents in memory (though a store may do something else--consult the store's
+documentation for exact behavior).
+
+This method is automatically called at the end of the HTTP response if the
+session data has been altered (though this behavior can be altered with various
+options in the middleware constructor). Because of this, typically this method
+does not need to be called.
+
+There are some cases where it is useful to call this method, for example,
+redirects, long-lived requests or in WebSockets.
+
+```js
+req.session.save(function (err) {
+ // session saved
+});
+```
+
+#### Session.touch()
+
+Updates the `.maxAge` property. Typically this is
+not necessary to call, as the session middleware does this for you.
+
+### req.session.id
+
+Each session has a unique ID associated with it. This property is an
+alias of [`req.sessionID`](#reqsessionid-1) and cannot be modified.
+It has been added to make the session ID accessible from the `session`
+object.
+
+### req.session.cookie
+
+Each session has a unique cookie object accompany it. This allows
+you to alter the session cookie per visitor. For example we can
+set `req.session.cookie.expires` to `false` to enable the cookie
+to remain for only the duration of the user-agent.
+
+#### Cookie.maxAge
+
+Alternatively `req.session.cookie.maxAge` will return the time
+remaining in milliseconds, which we may also re-assign a new value
+to adjust the `.expires` property appropriately. The following
+are essentially equivalent
+
+```js
+var hour = 3600000;
+req.session.cookie.expires = new Date(Date.now() + hour);
+req.session.cookie.maxAge = hour;
+```
+
+For example when `maxAge` is set to `60000` (one minute), and 30 seconds
+has elapsed it will return `30000` until the current request has completed,
+at which time `req.session.touch()` is called to reset
+`req.session.cookie.maxAge` to its original value.
+
+```js
+req.session.cookie.maxAge; // => 30000
+```
+
+#### Cookie.originalMaxAge
+
+The `req.session.cookie.originalMaxAge` property returns the original
+`maxAge` (time-to-live), in milliseconds, of the session cookie.
+
+### req.sessionID
+
+To get the ID of the loaded session, access the request property
+`req.sessionID`. This is simply a read-only value set when a session
+is loaded/created.
+
+## Session Store Implementation
+
+Every session store _must_ be an `EventEmitter` and implement specific
+methods. The following methods are the list of **required**, **recommended**,
+and **optional**.
+
+- Required methods are ones that this module will always call on the store.
+- Recommended methods are ones that this module will call on the store if
+ available.
+- Optional methods are ones this module does not call at all, but helps
+ present uniform stores to users.
+
+For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo.
+
+### store.all(callback)
+
+**Optional**
+
+This optional method is used to get all sessions in the store as an array. The
+`callback` should be called as `callback(error, sessions)`.
+
+### store.destroy(sid, callback)
+
+**Required**
+
+This required method is used to destroy/delete a session from the store given
+a session ID (`sid`). The `callback` should be called as `callback(error)` once
+the session is destroyed.
+
+### store.clear(callback)
+
+**Optional**
+
+This optional method is used to delete all sessions from the store. The
+`callback` should be called as `callback(error)` once the store is cleared.
+
+### store.length(callback)
+
+**Optional**
+
+This optional method is used to get the count of all sessions in the store.
+The `callback` should be called as `callback(error, len)`.
+
+### store.get(sid, callback)
+
+**Required**
+
+This required method is used to get a session from the store given a session
+ID (`sid`). The `callback` should be called as `callback(error, session)`.
+
+The `session` argument should be a session if found, otherwise `null` or
+`undefined` if the session was not found (and there was no error). A special
+case is made when `error.code === 'ENOENT'` to act like `callback(null, null)`.
+
+### store.set(sid, session, callback)
+
+**Required**
+
+This required method is used to upsert a session into the store given a
+session ID (`sid`) and session (`session`) object. The callback should be
+called as `callback(error)` once the session has been set in the store.
+
+### store.touch(sid, session, callback)
+
+**Recommended**
+
+This recommended method is used to "touch" a given session given a
+session ID (`sid`) and session (`session`) object. The `callback` should be
+called as `callback(error)` once the session has been touched.
+
+This is primarily used when the store will automatically delete idle sessions
+and this method is used to signal to the store the given session is active,
+potentially resetting the idle timer.
+
+## Compatible Session Stores
+
+The following modules implement a session store that is compatible with this
+module. Please make a PR to add additional modules :)
+
+[![★][aerospike-session-store-image] aerospike-session-store][aerospike-session-store-url] A session store using [Aerospike](http://www.aerospike.com/).
+
+[aerospike-session-store-url]: https://www.npmjs.com/package/aerospike-session-store
+[aerospike-session-store-image]: https://badgen.net/github/stars/aerospike/aerospike-session-store-expressjs?label=%E2%98%85
+
+[![★][better-sqlite3-session-store-image] better-sqlite3-session-store][better-sqlite3-session-store-url] A session store based on [better-sqlite3](https://github.com/JoshuaWise/better-sqlite3).
+
+[better-sqlite3-session-store-url]: https://www.npmjs.com/package/better-sqlite3-session-store
+[better-sqlite3-session-store-image]: https://badgen.net/github/stars/timdaub/better-sqlite3-session-store?label=%E2%98%85
+
+[![★][cassandra-store-image] cassandra-store][cassandra-store-url] An Apache Cassandra-based session store.
+
+[cassandra-store-url]: https://www.npmjs.com/package/cassandra-store
+[cassandra-store-image]: https://badgen.net/github/stars/webcc/cassandra-store?label=%E2%98%85
+
+[![★][cluster-store-image] cluster-store][cluster-store-url] A wrapper for using in-process / embedded
+stores - such as SQLite (via knex), leveldb, files, or memory - with node cluster (desirable for Raspberry Pi 2
+and other multi-core embedded devices).
+
+[cluster-store-url]: https://www.npmjs.com/package/cluster-store
+[cluster-store-image]: https://badgen.net/github/stars/coolaj86/cluster-store?label=%E2%98%85
+
+[![★][connect-arango-image] connect-arango][connect-arango-url] An ArangoDB-based session store.
+
+[connect-arango-url]: https://www.npmjs.com/package/connect-arango
+[connect-arango-image]: https://badgen.net/github/stars/AlexanderArvidsson/connect-arango?label=%E2%98%85
+
+[![★][connect-azuretables-image] connect-azuretables][connect-azuretables-url] An [Azure Table Storage](https://azure.microsoft.com/en-gb/services/storage/tables/)-based session store.
+
+[connect-azuretables-url]: https://www.npmjs.com/package/connect-azuretables
+[connect-azuretables-image]: https://badgen.net/github/stars/mike-goodwin/connect-azuretables?label=%E2%98%85
+
+[![★][connect-cloudant-store-image] connect-cloudant-store][connect-cloudant-store-url] An [IBM Cloudant](https://cloudant.com/)-based session store.
+
+[connect-cloudant-store-url]: https://www.npmjs.com/package/connect-cloudant-store
+[connect-cloudant-store-image]: https://badgen.net/github/stars/adriantanasa/connect-cloudant-store?label=%E2%98%85
+
+[![★][connect-cosmosdb-image] connect-cosmosdb][connect-cosmosdb-url] An Azure [Cosmos DB](https://azure.microsoft.com/en-us/products/cosmos-db/)-based session store.
+
+[connect-cosmosdb-url]: https://www.npmjs.com/package/connect-cosmosdb
+[connect-cosmosdb-image]: https://badgen.net/github/stars/thekillingspree/connect-cosmosdb?label=%E2%98%85
+
+[![★][connect-couchbase-image] connect-couchbase][connect-couchbase-url] A [couchbase](http://www.couchbase.com/)-based session store.
+
+[connect-couchbase-url]: https://www.npmjs.com/package/connect-couchbase
+[connect-couchbase-image]: https://badgen.net/github/stars/christophermina/connect-couchbase?label=%E2%98%85
+
+[![★][connect-datacache-image] connect-datacache][connect-datacache-url] An [IBM Bluemix Data Cache](http://www.ibm.com/cloud-computing/bluemix/)-based session store.
+
+[connect-datacache-url]: https://www.npmjs.com/package/connect-datacache
+[connect-datacache-image]: https://badgen.net/github/stars/adriantanasa/connect-datacache?label=%E2%98%85
+
+[![★][@google-cloud/connect-datastore-image] @google-cloud/connect-datastore][@google-cloud/connect-datastore-url] A [Google Cloud Datastore](https://cloud.google.com/datastore/docs/concepts/overview)-based session store.
+
+[@google-cloud/connect-datastore-url]: https://www.npmjs.com/package/@google-cloud/connect-datastore
+[@google-cloud/connect-datastore-image]: https://badgen.net/github/stars/GoogleCloudPlatform/cloud-datastore-session-node?label=%E2%98%85
+
+[![★][connect-db2-image] connect-db2][connect-db2-url] An IBM DB2-based session store built using [ibm_db](https://www.npmjs.com/package/ibm_db) module.
+
+[connect-db2-url]: https://www.npmjs.com/package/connect-db2
+[connect-db2-image]: https://badgen.net/github/stars/wallali/connect-db2?label=%E2%98%85
+
+[![★][connect-dynamodb-image] connect-dynamodb][connect-dynamodb-url] A DynamoDB-based session store.
+
+[connect-dynamodb-url]: https://www.npmjs.com/package/connect-dynamodb
+[connect-dynamodb-image]: https://badgen.net/github/stars/ca98am79/connect-dynamodb?label=%E2%98%85
+
+[![★][@google-cloud/connect-firestore-image] @google-cloud/connect-firestore][@google-cloud/connect-firestore-url] A [Google Cloud Firestore](https://cloud.google.com/firestore/docs/overview)-based session store.
+
+[@google-cloud/connect-firestore-url]: https://www.npmjs.com/package/@google-cloud/connect-firestore
+[@google-cloud/connect-firestore-image]: https://badgen.net/github/stars/googleapis/nodejs-firestore-session?label=%E2%98%85
+
+[![★][connect-hazelcast-image] connect-hazelcast][connect-hazelcast-url] Hazelcast session store for Connect and Express.
+
+[connect-hazelcast-url]: https://www.npmjs.com/package/connect-hazelcast
+[connect-hazelcast-image]: https://badgen.net/github/stars/huseyinbabal/connect-hazelcast?label=%E2%98%85
+
+[![★][connect-loki-image] connect-loki][connect-loki-url] A Loki.js-based session store.
+
+[connect-loki-url]: https://www.npmjs.com/package/connect-loki
+[connect-loki-image]: https://badgen.net/github/stars/Requarks/connect-loki?label=%E2%98%85
+
+[![★][connect-lowdb-image] connect-lowdb][connect-lowdb-url] A lowdb-based session store.
+
+[connect-lowdb-url]: https://www.npmjs.com/package/connect-lowdb
+[connect-lowdb-image]: https://badgen.net/github/stars/travishorn/connect-lowdb?label=%E2%98%85
+
+[![★][connect-memcached-image] connect-memcached][connect-memcached-url] A memcached-based session store.
+
+[connect-memcached-url]: https://www.npmjs.com/package/connect-memcached
+[connect-memcached-image]: https://badgen.net/github/stars/balor/connect-memcached?label=%E2%98%85
+
+[![★][connect-memjs-image] connect-memjs][connect-memjs-url] A memcached-based session store using
+[memjs](https://www.npmjs.com/package/memjs) as the memcached client.
+
+[connect-memjs-url]: https://www.npmjs.com/package/connect-memjs
+[connect-memjs-image]: https://badgen.net/github/stars/liamdon/connect-memjs?label=%E2%98%85
+
+[![★][connect-ml-image] connect-ml][connect-ml-url] A MarkLogic Server-based session store.
+
+[connect-ml-url]: https://www.npmjs.com/package/connect-ml
+[connect-ml-image]: https://badgen.net/github/stars/bluetorch/connect-ml?label=%E2%98%85
+
+[![★][connect-monetdb-image] connect-monetdb][connect-monetdb-url] A MonetDB-based session store.
+
+[connect-monetdb-url]: https://www.npmjs.com/package/connect-monetdb
+[connect-monetdb-image]: https://badgen.net/github/stars/MonetDB/npm-connect-monetdb?label=%E2%98%85
+
+[![★][connect-mongo-image] connect-mongo][connect-mongo-url] A MongoDB-based session store.
+
+[connect-mongo-url]: https://www.npmjs.com/package/connect-mongo
+[connect-mongo-image]: https://badgen.net/github/stars/kcbanner/connect-mongo?label=%E2%98%85
+
+[![★][connect-mongodb-session-image] connect-mongodb-session][connect-mongodb-session-url] Lightweight MongoDB-based session store built and maintained by MongoDB.
+
+[connect-mongodb-session-url]: https://www.npmjs.com/package/connect-mongodb-session
+[connect-mongodb-session-image]: https://badgen.net/github/stars/mongodb-js/connect-mongodb-session?label=%E2%98%85
+
+[![★][connect-mssql-v2-image] connect-mssql-v2][connect-mssql-v2-url] A Microsoft SQL Server-based session store based on [connect-mssql](https://www.npmjs.com/package/connect-mssql).
+
+[connect-mssql-v2-url]: https://www.npmjs.com/package/connect-mssql-v2
+[connect-mssql-v2-image]: https://badgen.net/github/stars/jluboff/connect-mssql-v2?label=%E2%98%85
+
+[![★][connect-neo4j-image] connect-neo4j][connect-neo4j-url] A [Neo4j](https://neo4j.com)-based session store.
+
+[connect-neo4j-url]: https://www.npmjs.com/package/connect-neo4j
+[connect-neo4j-image]: https://badgen.net/github/stars/MaxAndersson/connect-neo4j?label=%E2%98%85
+
+[![★][connect-ottoman-image] connect-ottoman][connect-ottoman-url] A [couchbase ottoman](http://www.couchbase.com/)-based session store.
+
+[connect-ottoman-url]: https://www.npmjs.com/package/connect-ottoman
+[connect-ottoman-image]: https://badgen.net/github/stars/noiissyboy/connect-ottoman?label=%E2%98%85
+
+[![★][connect-pg-simple-image] connect-pg-simple][connect-pg-simple-url] A PostgreSQL-based session store.
+
+[connect-pg-simple-url]: https://www.npmjs.com/package/connect-pg-simple
+[connect-pg-simple-image]: https://badgen.net/github/stars/voxpelli/node-connect-pg-simple?label=%E2%98%85
+
+[![★][connect-redis-image] connect-redis][connect-redis-url] A Redis-based session store.
+
+[connect-redis-url]: https://www.npmjs.com/package/connect-redis
+[connect-redis-image]: https://badgen.net/github/stars/tj/connect-redis?label=%E2%98%85
+
+[![★][connect-session-firebase-image] connect-session-firebase][connect-session-firebase-url] A session store based on the [Firebase Realtime Database](https://firebase.google.com/docs/database/)
+
+[connect-session-firebase-url]: https://www.npmjs.com/package/connect-session-firebase
+[connect-session-firebase-image]: https://badgen.net/github/stars/benweier/connect-session-firebase?label=%E2%98%85
+
+[![★][connect-session-knex-image] connect-session-knex][connect-session-knex-url] A session store using
+[Knex.js](http://knexjs.org/), which is a SQL query builder for PostgreSQL, MySQL, MariaDB, SQLite3, and Oracle.
+
+[connect-session-knex-url]: https://www.npmjs.com/package/connect-session-knex
+[connect-session-knex-image]: https://badgen.net/github/stars/llambda/connect-session-knex?label=%E2%98%85
+
+[![★][connect-session-sequelize-image] connect-session-sequelize][connect-session-sequelize-url] A session store using
+[Sequelize.js](http://sequelizejs.com/), which is a Node.js / io.js ORM for PostgreSQL, MySQL, SQLite and MSSQL.
+
+[connect-session-sequelize-url]: https://www.npmjs.com/package/connect-session-sequelize
+[connect-session-sequelize-image]: https://badgen.net/github/stars/mweibel/connect-session-sequelize?label=%E2%98%85
+
+[![★][connect-sqlite3-image] connect-sqlite3][connect-sqlite3-url] A [SQLite3](https://github.com/mapbox/node-sqlite3) session store modeled after the TJ's `connect-redis` store.
+
+[connect-sqlite3-url]: https://www.npmjs.com/package/connect-sqlite3
+[connect-sqlite3-image]: https://badgen.net/github/stars/rawberg/connect-sqlite3?label=%E2%98%85
+
+[![★][connect-typeorm-image] connect-typeorm][connect-typeorm-url] A [TypeORM](https://github.com/typeorm/typeorm)-based session store.
+
+[connect-typeorm-url]: https://www.npmjs.com/package/connect-typeorm
+[connect-typeorm-image]: https://badgen.net/github/stars/makepost/connect-typeorm?label=%E2%98%85
+
+[![★][couchdb-expression-image] couchdb-expression][couchdb-expression-url] A [CouchDB](https://couchdb.apache.org/)-based session store.
+
+[couchdb-expression-url]: https://www.npmjs.com/package/couchdb-expression
+[couchdb-expression-image]: https://badgen.net/github/stars/tkshnwesper/couchdb-expression?label=%E2%98%85
+
+[![★][dynamodb-store-image] dynamodb-store][dynamodb-store-url] A DynamoDB-based session store.
+
+[dynamodb-store-url]: https://www.npmjs.com/package/dynamodb-store
+[dynamodb-store-image]: https://badgen.net/github/stars/rafaelrpinto/dynamodb-store?label=%E2%98%85
+
+[![★][dynamodb-store-v3-image] dynamodb-store-v3][dynamodb-store-v3-url] Implementation of a session store using DynamoDB backed by the [AWS SDK for JavaScript v3](https://github.com/aws/aws-sdk-js-v3).
+
+[dynamodb-store-v3-url]: https://www.npmjs.com/package/dynamodb-store-v3
+[dynamodb-store-v3-image]: https://badgen.net/github/stars/FryDay/dynamodb-store-v3?label=%E2%98%85
+
+[![★][express-etcd-image] express-etcd][express-etcd-url] An [etcd](https://github.com/stianeikeland/node-etcd) based session store.
+
+[express-etcd-url]: https://www.npmjs.com/package/express-etcd
+[express-etcd-image]: https://badgen.net/github/stars/gildean/express-etcd?label=%E2%98%85
+
+[![★][express-mysql-session-image] express-mysql-session][express-mysql-session-url] A session store using native
+[MySQL](https://www.mysql.com/) via the [node-mysql](https://github.com/felixge/node-mysql) module.
+
+[express-mysql-session-url]: https://www.npmjs.com/package/express-mysql-session
+[express-mysql-session-image]: https://badgen.net/github/stars/chill117/express-mysql-session?label=%E2%98%85
+
+[![★][express-nedb-session-image] express-nedb-session][express-nedb-session-url] A NeDB-based session store.
+
+[express-nedb-session-url]: https://www.npmjs.com/package/express-nedb-session
+[express-nedb-session-image]: https://badgen.net/github/stars/louischatriot/express-nedb-session?label=%E2%98%85
+
+[![★][express-oracle-session-image] express-oracle-session][express-oracle-session-url] A session store using native
+[oracle](https://www.oracle.com/) via the [node-oracledb](https://www.npmjs.com/package/oracledb) module.
+
+[express-oracle-session-url]: https://www.npmjs.com/package/express-oracle-session
+[express-oracle-session-image]: https://badgen.net/github/stars/slumber86/express-oracle-session?label=%E2%98%85
+
+[![★][express-session-cache-manager-image] express-session-cache-manager][express-session-cache-manager-url]
+A store that implements [cache-manager](https://www.npmjs.com/package/cache-manager), which supports
+a [variety of storage types](https://www.npmjs.com/package/cache-manager#store-engines).
+
+[express-session-cache-manager-url]: https://www.npmjs.com/package/express-session-cache-manager
+[express-session-cache-manager-image]: https://badgen.net/github/stars/theogravity/express-session-cache-manager?label=%E2%98%85
+
+[![★][express-session-etcd3-image] express-session-etcd3][express-session-etcd3-url] An [etcd3](https://github.com/mixer/etcd3) based session store.
+
+[express-session-etcd3-url]: https://www.npmjs.com/package/express-session-etcd3
+[express-session-etcd3-image]: https://badgen.net/github/stars/willgm/express-session-etcd3?label=%E2%98%85
+
+[![★][express-session-level-image] express-session-level][express-session-level-url] A [LevelDB](https://github.com/Level/levelup) based session store.
+
+[express-session-level-url]: https://www.npmjs.com/package/express-session-level
+[express-session-level-image]: https://badgen.net/github/stars/tgohn/express-session-level?label=%E2%98%85
+
+[![★][express-session-rsdb-image] express-session-rsdb][express-session-rsdb-url] Session store based on Rocket-Store: A very simple, super fast and yet powerful, flat file database.
+
+[express-session-rsdb-url]: https://www.npmjs.com/package/express-session-rsdb
+[express-session-rsdb-image]: https://badgen.net/github/stars/paragi/express-session-rsdb?label=%E2%98%85
+
+[![★][express-sessions-image] express-sessions][express-sessions-url] A session store supporting both MongoDB and Redis.
+
+[express-sessions-url]: https://www.npmjs.com/package/express-sessions
+[express-sessions-image]: https://badgen.net/github/stars/konteck/express-sessions?label=%E2%98%85
+
+[![★][firestore-store-image] firestore-store][firestore-store-url] A [Firestore](https://github.com/hendrysadrak/firestore-store)-based session store.
+
+[firestore-store-url]: https://www.npmjs.com/package/firestore-store
+[firestore-store-image]: https://badgen.net/github/stars/hendrysadrak/firestore-store?label=%E2%98%85
+
+[![★][fortune-session-image] fortune-session][fortune-session-url] A [Fortune.js](https://github.com/fortunejs/fortune)
+based session store. Supports all backends supported by Fortune (MongoDB, Redis, Postgres, NeDB).
+
+[fortune-session-url]: https://www.npmjs.com/package/fortune-session
+[fortune-session-image]: https://badgen.net/github/stars/aliceklipper/fortune-session?label=%E2%98%85
+
+[![★][hazelcast-store-image] hazelcast-store][hazelcast-store-url] A Hazelcast-based session store built on the [Hazelcast Node Client](https://www.npmjs.com/package/hazelcast-client).
+
+[hazelcast-store-url]: https://www.npmjs.com/package/hazelcast-store
+[hazelcast-store-image]: https://badgen.net/github/stars/jackspaniel/hazelcast-store?label=%E2%98%85
+
+[![★][level-session-store-image] level-session-store][level-session-store-url] A LevelDB-based session store.
+
+[level-session-store-url]: https://www.npmjs.com/package/level-session-store
+[level-session-store-image]: https://badgen.net/github/stars/toddself/level-session-store?label=%E2%98%85
+
+[![★][lowdb-session-store-image] lowdb-session-store][lowdb-session-store-url] A [lowdb](https://www.npmjs.com/package/lowdb)-based session store.
+
+[lowdb-session-store-url]: https://www.npmjs.com/package/lowdb-session-store
+[lowdb-session-store-image]: https://badgen.net/github/stars/fhellwig/lowdb-session-store?label=%E2%98%85
+
+[![★][medea-session-store-image] medea-session-store][medea-session-store-url] A Medea-based session store.
+
+[medea-session-store-url]: https://www.npmjs.com/package/medea-session-store
+[medea-session-store-image]: https://badgen.net/github/stars/BenjaminVadant/medea-session-store?label=%E2%98%85
+
+[![★][memorystore-image] memorystore][memorystore-url] A memory session store made for production.
+
+[memorystore-url]: https://www.npmjs.com/package/memorystore
+[memorystore-image]: https://badgen.net/github/stars/roccomuso/memorystore?label=%E2%98%85
+
+[![★][mssql-session-store-image] mssql-session-store][mssql-session-store-url] A SQL Server-based session store.
+
+[mssql-session-store-url]: https://www.npmjs.com/package/mssql-session-store
+[mssql-session-store-image]: https://badgen.net/github/stars/jwathen/mssql-session-store?label=%E2%98%85
+
+[![★][nedb-session-store-image] nedb-session-store][nedb-session-store-url] An alternate NeDB-based (either in-memory or file-persisted) session store.
+
+[nedb-session-store-url]: https://www.npmjs.com/package/nedb-session-store
+[nedb-session-store-image]: https://badgen.net/github/stars/JamesMGreene/nedb-session-store?label=%E2%98%85
+
+[![★][@quixo3/prisma-session-store-image] @quixo3/prisma-session-store][@quixo3/prisma-session-store-url] A session store for the [Prisma Framework](https://www.prisma.io).
+
+[@quixo3/prisma-session-store-url]: https://www.npmjs.com/package/@quixo3/prisma-session-store
+[@quixo3/prisma-session-store-image]: https://badgen.net/github/stars/kleydon/prisma-session-store?label=%E2%98%85
+
+[![★][restsession-image] restsession][restsession-url] Store sessions utilizing a RESTful API
+
+[restsession-url]: https://www.npmjs.com/package/restsession
+[restsession-image]: https://badgen.net/github/stars/jankal/restsession?label=%E2%98%85
+
+[![★][sequelstore-connect-image] sequelstore-connect][sequelstore-connect-url] A session store using [Sequelize.js](http://sequelizejs.com/).
+
+[sequelstore-connect-url]: https://www.npmjs.com/package/sequelstore-connect
+[sequelstore-connect-image]: https://badgen.net/github/stars/MattMcFarland/sequelstore-connect?label=%E2%98%85
+
+[![★][session-file-store-image] session-file-store][session-file-store-url] A file system-based session store.
+
+[session-file-store-url]: https://www.npmjs.com/package/session-file-store
+[session-file-store-image]: https://badgen.net/github/stars/valery-barysok/session-file-store?label=%E2%98%85
+
+[![★][session-pouchdb-store-image] session-pouchdb-store][session-pouchdb-store-url] Session store for PouchDB / CouchDB. Accepts embedded, custom, or remote PouchDB instance and realtime synchronization.
+
+[session-pouchdb-store-url]: https://www.npmjs.com/package/session-pouchdb-store
+[session-pouchdb-store-image]: https://badgen.net/github/stars/solzimer/session-pouchdb-store?label=%E2%98%85
+
+[![★][@cyclic.sh/session-store-image] @cyclic.sh/session-store][@cyclic.sh/session-store-url] A DynamoDB-based session store for [Cyclic.sh](https://www.cyclic.sh/) apps.
+
+[@cyclic.sh/session-store-url]: https://www.npmjs.com/package/@cyclic.sh/session-store
+[@cyclic.sh/session-store-image]: https://badgen.net/github/stars/cyclic-software/session-store?label=%E2%98%85
+
+[![★][@databunker/session-store-image] @databunker/session-store][@databunker/session-store-url] A [Databunker](https://databunker.org/)-based encrypted session store.
+
+[@databunker/session-store-url]: https://www.npmjs.com/package/@databunker/session-store
+[@databunker/session-store-image]: https://badgen.net/github/stars/securitybunker/databunker-session-store?label=%E2%98%85
+
+[![★][sessionstore-image] sessionstore][sessionstore-url] A session store that works with various databases.
+
+[sessionstore-url]: https://www.npmjs.com/package/sessionstore
+[sessionstore-image]: https://badgen.net/github/stars/adrai/sessionstore?label=%E2%98%85
+
+[![★][tch-nedb-session-image] tch-nedb-session][tch-nedb-session-url] A file system session store based on NeDB.
+
+[tch-nedb-session-url]: https://www.npmjs.com/package/tch-nedb-session
+[tch-nedb-session-image]: https://badgen.net/github/stars/tomaschyly/NeDBSession?label=%E2%98%85
+
+## Examples
+
+### View counter
+
+A simple example using `express-session` to store page views for a user.
+
+```js
+var express = require('express');
+var parseurl = require('parseurl');
+var session = require('express-session');
+
+var app = express();
+
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ })
+);
+
+app.use(function (req, res, next) {
+ if (!req.session.views) {
+ req.session.views = {};
+ }
+
+ // get the url pathname
+ var pathname = parseurl(req).pathname;
+
+ // count the views
+ req.session.views[pathname] = (req.session.views[pathname] || 0) + 1;
+
+ next();
+});
+
+app.get('/foo', function (req, res, next) {
+ res.send('you viewed this page ' + req.session.views['/foo'] + ' times');
+});
+
+app.get('/bar', function (req, res, next) {
+ res.send('you viewed this page ' + req.session.views['/bar'] + ' times');
+});
+
+app.listen(3000);
+```
+
+### User login
+
+A simple example using `express-session` to keep a user log in session.
+
+```js
+var escapeHtml = require('escape-html');
+var express = require('express');
+var session = require('express-session');
+
+var app = express();
+
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ })
+);
+
+// middleware to test if authenticated
+function isAuthenticated(req, res, next) {
+ if (req.session.user) next();
+ else next('route');
+}
+
+app.get('/', isAuthenticated, function (req, res) {
+ // this is only called when there is an authentication user due to isAuthenticated
+ res.send('hello, ' + escapeHtml(req.session.user) + '!' + ' Logout ');
+});
+
+app.get('/', function (req, res) {
+ res.send(
+ ''
+ );
+});
+
+app.post('/login', express.urlencoded({ extended: false }), function (req, res) {
+ // login logic to validate req.body.user and req.body.pass
+ // would be implemented here. for this example any combo works
+
+ // regenerate the session, which is good practice to help
+ // guard against forms of session fixation
+ req.session.regenerate(function (err) {
+ if (err) next(err);
+
+ // store user information in session, typically a user id
+ req.session.user = req.body.user;
+
+ // save the session before redirection to ensure page
+ // load does not happen before session is saved
+ req.session.save(function (err) {
+ if (err) return next(err);
+ res.redirect('/');
+ });
+ });
+});
+
+app.get('/logout', function (req, res, next) {
+ // logout logic
+
+ // clear the user from the session object and save.
+ // this will ensure that re-using the old session id
+ // does not have a logged in user
+ req.session.user = null;
+ req.session.save(function (err) {
+ if (err) next(err);
+
+ // regenerate the session, which is good practice to help
+ // guard against forms of session fixation
+ req.session.regenerate(function (err) {
+ if (err) next(err);
+ res.redirect('/');
+ });
+ });
+});
+
+app.listen(3000);
+```
+
+## Debugging
+
+This module uses the [debug](https://www.npmjs.com/package/debug) module
+internally to log information about session operations.
+
+To see all the internal logs, set the `DEBUG` environment variable to
+`express-session` when launching your app (`npm start`, in this example):
+
+```sh
+$ DEBUG=express-session npm start
+```
+
+On Windows, use the corresponding command;
+
+```sh
+> set DEBUG=express-session & npm start
+```
+
+## License
+
+[MIT](LICENSE)
+
+[rfc-6265bis-03-4.1.2.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7
+[rfc-cutler-httpbis-partitioned-cookies]: https://tools.ietf.org/html/draft-cutler-httpbis-partitioned-cookies/
+[rfc-west-cookie-priority-00-4.1]: https://tools.ietf.org/html/draft-west-cookie-priority-00#section-4.1
+[ci-image]: https://badgen.net/github/checks/expressjs/session/master?label=ci
+[ci-url]: https://github.com/expressjs/session/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/session/master
+[coveralls-url]: https://coveralls.io/r/expressjs/session?branch=master
+[node-url]: https://nodejs.org/en/download
+[npm-downloads-image]: https://badgen.net/npm/dm/express-session
+[npm-url]: https://npmjs.org/package/express-session
+[npm-version-image]: https://badgen.net/npm/v/express-session
diff --git a/astro/src/content/resources/it/middleware/timeout.md b/astro/src/content/resources/it/middleware/timeout.md
new file mode 100644
index 0000000000..f6057aedfd
--- /dev/null
+++ b/astro/src/content/resources/it/middleware/timeout.md
@@ -0,0 +1,176 @@
+---
+title: Express timeout middleware
+module: timeout
+---
+
+# connect-timeout
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][travis-image]][travis-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Times out a request in the Connect/Express application framework.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install connect-timeout
+```
+
+## API
+
+**NOTE** This module is not recommend as a "top-level" middleware (i.e.
+`app.use(timeout('5s'))`) unless you take precautions to halt your own
+middleware processing. See [as top-level middleware](#as-top-level-middleware)
+for how to use as a top-level middleware.
+
+While the library will emit a 'timeout' event when requests exceed the given
+timeout, node will continue processing the slow request until it terminates.
+Slow requests will continue to use CPU and memory, even if you are returning
+a HTTP response in the timeout callback. For better control over CPU/memory,
+you may need to find the events that are taking a long time (3rd party HTTP
+requests, disk I/O, database calls) and find a way to cancel them, and/or
+close the attached sockets.
+
+### timeout(time, [options])
+
+Returns middleware that times out in `time` milliseconds. `time` can also
+be a string accepted by the [ms](https://www.npmjs.org/package/ms#readme)
+module. On timeout, `req` will emit `"timeout"`.
+
+#### Options
+
+The `timeout` function takes an optional `options` object that may contain
+any of the following keys:
+
+##### respond
+
+Controls if this module will "respond" in the form of forwarding an error.
+If `true`, the timeout error is passed to `next()` so that you may customize
+the response behavior. This error has a `.timeout` property as well as
+`.status == 503`. This defaults to `true`.
+
+### req.clearTimeout()
+
+Clears the timeout on the request. The timeout is completely removed and
+will not fire for this request in the future.
+
+### req.timedout
+
+`true` if timeout fired; `false` otherwise.
+
+## Examples
+
+### as top-level middleware
+
+Because of the way middleware processing works, once this module
+passes the request to the next middleware (which it has to do in order
+for you to do work), it can no longer stop the flow, so you must take
+care to check if the request has timedout before you continue to act
+on the request.
+
+```javascript
+var bodyParser = require('body-parser');
+var cookieParser = require('cookie-parser');
+var express = require('express');
+var timeout = require('connect-timeout');
+
+// example of using this top-level; note the use of haltOnTimedout
+// after every middleware; it will stop the request flow on a timeout
+var app = express();
+app.use(timeout('5s'));
+app.use(bodyParser());
+app.use(haltOnTimedout);
+app.use(cookieParser());
+app.use(haltOnTimedout);
+
+// Add your routes here, etc.
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+app.listen(3000);
+```
+
+### express 3.x
+
+```javascript
+var express = require('express');
+var bodyParser = require('body-parser');
+var timeout = require('connect-timeout');
+
+var app = express();
+app.post('/save', timeout('5s'), bodyParser.json(), haltOnTimedout, function (req, res, next) {
+ savePost(req.body, function (err, id) {
+ if (err) return next(err);
+ if (req.timedout) return;
+ res.send('saved as id ' + id);
+ });
+});
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+function savePost(post, cb) {
+ setTimeout(
+ function () {
+ cb(null, (Math.random() * 40000) >>> 0);
+ },
+ (Math.random() * 7000) >>> 0
+ );
+}
+
+app.listen(3000);
+```
+
+### connect
+
+```javascript
+var bodyParser = require('body-parser');
+var connect = require('connect');
+var timeout = require('connect-timeout');
+
+var app = connect();
+app.use('/save', timeout('5s'), bodyParser.json(), haltOnTimedout, function (req, res, next) {
+ savePost(req.body, function (err, id) {
+ if (err) return next(err);
+ if (req.timedout) return;
+ res.send('saved as id ' + id);
+ });
+});
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+function savePost(post, cb) {
+ setTimeout(
+ function () {
+ cb(null, (Math.random() * 40000) >>> 0);
+ },
+ (Math.random() * 7000) >>> 0
+ );
+}
+
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/connect-timeout.svg
+[npm-url]: https://npmjs.org/package/connect-timeout
+[travis-image]: https://img.shields.io/travis/expressjs/timeout/master.svg
+[travis-url]: https://travis-ci.org/expressjs/timeout
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/timeout/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/timeout?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/connect-timeout.svg
+[downloads-url]: https://npmjs.org/package/connect-timeout
diff --git a/astro/src/content/resources/it/middleware/vhost.md b/astro/src/content/resources/it/middleware/vhost.md
new file mode 100644
index 0000000000..72f49d7f93
--- /dev/null
+++ b/astro/src/content/resources/it/middleware/vhost.md
@@ -0,0 +1,174 @@
+---
+title: Express vhost middleware
+module: vhost
+---
+
+# vhost
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Install
+
+```sh
+$ npm install vhost
+```
+
+## API
+
+```js
+var vhost = require('vhost');
+```
+
+### vhost(hostname, handle)
+
+Create a new middleware function to hand off request to `handle` when the incoming
+host for the request matches `hostname`. The function is called as
+`handle(req, res, next)`, like a standard middleware.
+
+`hostname` can be a string or a RegExp object. When `hostname` is a string it can
+contain `*` to match 1 or more characters in that section of the hostname. When
+`hostname` is a RegExp, it will be forced to case-insensitive (since hostnames are)
+and will be forced to match based on the start and end of the hostname.
+
+When host is matched and the request is sent down to a vhost handler, the `req.vhost`
+property will be populated with an object. This object will have numeric properties
+corresponding to each wildcard (or capture group if RegExp object provided) and the
+`hostname` that was matched.
+
+```js
+var connect = require('connect');
+var vhost = require('vhost');
+var app = connect();
+
+app.use(
+ vhost('*.*.example.com', function handle(req, res, next) {
+ // for match of "foo.bar.example.com:8080" against "*.*.example.com":
+ console.dir(req.vhost.host); // => 'foo.bar.example.com:8080'
+ console.dir(req.vhost.hostname); // => 'foo.bar.example.com'
+ console.dir(req.vhost.length); // => 2
+ console.dir(req.vhost[0]); // => 'foo'
+ console.dir(req.vhost[1]); // => 'bar'
+ })
+);
+```
+
+## Examples
+
+### using with connect for static serving
+
+```js
+var connect = require('connect');
+var serveStatic = require('serve-static');
+var vhost = require('vhost');
+
+var mailapp = connect();
+
+// add middlewares to mailapp for mail.example.com
+
+// create app to serve static files on subdomain
+var staticapp = connect();
+staticapp.use(serveStatic('public'));
+
+// create main app
+var app = connect();
+
+// add vhost routing to main app for mail
+app.use(vhost('mail.example.com', mailapp));
+
+// route static assets for "assets-*" subdomain to get
+// around max host connections limit on browsers
+app.use(vhost('assets-*.example.com', staticapp));
+
+// add middlewares and main usage to app
+
+app.listen(3000);
+```
+
+### using with connect for user subdomains
+
+```js
+var connect = require('connect');
+var serveStatic = require('serve-static');
+var vhost = require('vhost');
+
+var mainapp = connect();
+
+// add middlewares to mainapp for the main web site
+
+// create app that will server user content from public/{username}/
+var userapp = connect();
+
+userapp.use(function (req, res, next) {
+ var username = req.vhost[0]; // username is the "*"
+
+ // pretend request was for /{username}/* for file serving
+ req.originalUrl = req.url;
+ req.url = '/' + username + req.url;
+
+ next();
+});
+userapp.use(serveStatic('public'));
+
+// create main app
+var app = connect();
+
+// add vhost routing for main app
+app.use(vhost('userpages.local', mainapp));
+app.use(vhost('www.userpages.local', mainapp));
+
+// listen on all subdomains for user pages
+app.use(vhost('*.userpages.local', userapp));
+
+app.listen(3000);
+```
+
+### using with any generic request handler
+
+```js
+var connect = require('connect');
+var http = require('http');
+var vhost = require('vhost');
+
+// create main app
+var app = connect();
+
+app.use(
+ vhost('mail.example.com', function (req, res) {
+ // handle req + res belonging to mail.example.com
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello from mail!');
+ })
+);
+
+// an external api server in any framework
+var httpServer = http.createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello from the api!');
+});
+
+app.use(
+ vhost('api.example.com', function (req, res) {
+ // handle req + res belonging to api.example.com
+ // pass the request to a standard Node.js HTTP server
+ httpServer.emit('request', req, res);
+ })
+);
+
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/vhost.svg
+[npm-url]: https://npmjs.org/package/vhost
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/vhost/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/vhost
+[downloads-image]: https://img.shields.io/npm/dm/vhost.svg
+[downloads-url]: https://npmjs.org/package/vhost
+[github-actions-ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/vhost/ci.yml?branch=master&label=ci
+[github-actions-ci-url]: https://github.com/expressjs/vhost/actions/workflows/ci.yml
diff --git a/astro/src/content/resources/it/utils.md b/astro/src/content/resources/it/utils.md
new file mode 100644
index 0000000000..546b2f09b4
--- /dev/null
+++ b/astro/src/content/resources/it/utils.md
@@ -0,0 +1,22 @@
+---
+title: Express utilities
+description: Discover utility modules related to Express.js and Node.js, including tools for cookies, CSRF protection, URL parsing, routing, and more to enhance your applications.
+---
+
+## Express utility functions
+
+The [pillarjs](https://github.com/pillarjs) GitHub organization contains a number of modules
+for utility functions that may be generally useful.
+
+| Utility modules | Description |
+| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| [cookies](https://www.npmjs.com/package/cookies) | Get and set HTTP(S) cookies that can be signed to prevent tampering, using Keygrip. Can be used with the Node.js HTTP library or as Express middleware. |
+| [csrf](https://www.npmjs.com/package/csrf) | Contains the logic behind CSRF token creation and verification. Use this module to create custom CSRF middleware. |
+| [finalhandler](https://www.npmjs.com/package/finalhandler) | Function to invoke as the final step to respond to HTTP request. |
+| [parseurl](https://www.npmjs.com/package/parseurl) | Parse a URL with caching. |
+| [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) | Turn an Express-style path string such as ``/user/:name` into a regular expression. |
+| [resolve-path](https://www.npmjs.com/package/resolve-path) | Resolves a relative path against a root path with validation. |
+| [router](https://www.npmjs.com/package/router) | Simple middleware-style router. |
+| [send](https://www.npmjs.com/package/send) | Library for streaming files as a HTTP response, with support for partial responses (ranges), conditional-GET negotiation, and granular events. |
+
+For additional low-level HTTP-related modules, see [jshttp](https://github.com/jshttp).
diff --git a/astro/src/content/resources/ja/community.md b/astro/src/content/resources/ja/community.md
new file mode 100755
index 0000000000..e40d97e421
--- /dev/null
+++ b/astro/src/content/resources/ja/community.md
@@ -0,0 +1,70 @@
+---
+title: Express community
+description: Connect with the Express.js community, learn about the technical committee, find resources, explore community-contributed modules, and get involved in discussions.
+---
+
+# Community
+
+## Technical committee
+
+The Express technical committee meets online every two weeks (as needed) to discuss development and maintenance of Express,
+and other issues relevant to the Express project. Each meeting is typically announced in an
+[expressjs/discussions issue](https://github.com/expressjs/discussions/issues) with a link to join or view the meeting, which is
+open to all observers.
+
+The meetings are recorded; for a list of the recordings, see the [Express.js YouTube channel](https://www.youtube.com/channel/UCYjxjAeH6TRik9Iwy5nXw7g).
+
+Members of the Express technical committee are:
+
+**Active:**
+
+- [@blakeembrey](https://github.com/blakeembrey) - Blake Embrey
+- [@crandmck](https://github.com/crandmck) - Rand McKinney
+- [@LinusU](https://github.com/LinusU) - Linus Unnebäck
+- [@ulisesgascon](https://github.com/ulisesGascon) - Ulises Gascón
+- [@sheplu](https://github.com/sheplu) - Jean Burellier
+- [@wesleytodd](https://github.com/wesleytodd) - Wes Todd
+- [@jonchurch](https://github.com/jonchurch) - Jon Church
+- [@ctcpip](https://github.com/ctcpip/) - Chris de Almeida
+
+**Inactive:**
+
+- [@dougwilson](https://github.com/dougwilson) - Douglas Wilson
+- [@hacksparrow](https://github.com/hacksparrow) - Hage Yaapa
+- [@jonathanong](https://github.com/jonathanong) - jongleberry
+- [@niftylettuce](https://github.com/niftylettuce) - niftylettuce
+- [@troygoode](https://github.com/troygoode) - Troy Goode
+
+## Express is made of many modules
+
+Our vibrant community has created a large variety of extensions,
+[middleware modules](/en/resources/middleware) and higher-level frameworks.
+
+Additionally, the Express community maintains modules in these two GitHub orgs:
+
+- [jshttp](https://github.com/jshttp) modules providing useful utility functions; see [Utility modules](/en/resources/utils).
+- [pillarjs](https://github.com/pillarjs): low-level modules that Express uses internally.
+
+To keep up with what is going on in the whole community, check out the [ExpressJS StatusBoard](https://expressjs.github.io/statusboard/).
+
+## Issues
+
+If you've come across what you think is a bug, or just want to make
+a feature request open a ticket in the [issue queue](https://github.com/expressjs/express/issues).
+
+## Examples
+
+View dozens of Express application [examples](https://github.com/expressjs/express/tree/master/examples)
+in the repository covering everything from API design and authentication to template engine integration.
+
+## Github Discussions
+
+The [GitHub Discussions](https://github.com/expressjs/discussions) section is an excellent space to engage in conversations about the development and maintenance of Express, as well as to share ideas and discuss topics related to its usage.
+
+# Branding of Express.js
+
+## Express.js Logo
+
+Express is a project of the OpenJS Foundation. Please review the [trademark policy](https://trademark-policy.openjsf.org/) for information about permissible use of Express.js logos and marks.
+
+
diff --git a/astro/src/content/resources/ja/contributing.md b/astro/src/content/resources/ja/contributing.md
new file mode 100644
index 0000000000..82c6b8fed7
--- /dev/null
+++ b/astro/src/content/resources/ja/contributing.md
@@ -0,0 +1,482 @@
+---
+title: Contributing to Express
+description: Find out how to contribute to Express.js, including guidelines for reporting issues, submitting pull requests, becoming a collaborator, and understanding security policies.
+---
+
+# Contributing to Express
+
+### Looking to contribute to Expressjs.com? Click [here](#expressjs-website-contributing).
+
+Express and the other projects in the [expressjs organization on GitHub](https://github.com/expressjs) are projects of the [OpenJs Foundation](https://openjsf.org/).
+These projects are governed under the general policies and guidelines of the Node.js Foundation along with the additional guidelines below.
+
+- [Technical committee](#technical-committee)
+- [Community contributing guide](#community-contributing-guide)
+- [Collaborator's guide](#collaborators-guide)
+- [Security policies and procedures](#security-policies-and-procedures)
+
+## Technical committee
+
+The Express technical committee consists of active project members, and guides development and maintenance of the Express project. For more information, see [Express Community - Technical committee](/en/resources/community/#technical-committee).
+
+## Community contributing guide
+
+
+
+The goal of this document is to create a contribution process that:
+
+- Encourages new contributions.
+- Encourages contributors to remain involved.
+- Avoids unnecessary processes and bureaucracy whenever possible.
+- Creates a transparent decision making process that makes it clear how
+ contributors can be involved in decision making.
+
+### Vocabulary
+
+- A **Contributor** is any individual creating or commenting on an issue or pull request.
+- A **Committer** is a subset of contributors who have been given write access to the repository.
+- A **Project Captain** is the lead maintainer of a repository.
+- A **TC (Technical Committee)** is a group of committers representing the required technical
+ expertise to resolve rare disputes.
+- A **Triager** is a subset of contributors who have been given triage access to the repository.
+
+### Logging Issues
+
+Log an issue for any question or problem you might have. When in doubt, log an issue, and
+any additional policies about what to include will be provided in the responses. The only
+exception is security disclosures which should be sent privately.
+
+Committers may direct you to another repository, ask for additional clarifications, and
+add appropriate metadata before the issue is addressed.
+
+Please be courteous and respectful. Every participant is expected to follow the
+project's Code of Conduct.
+
+### Contributions
+
+Any change to resources in this repository must be through pull requests. This applies to all changes
+to documentation, code, binary files, etc. Even long term committers and TC members must use
+pull requests.
+
+No pull request can be merged without being reviewed.
+
+For non-trivial contributions, pull requests should sit for at least 36 hours to ensure that
+contributors in other timezones have time to review. Consideration should also be given to
+weekends and other holiday periods to ensure active committers all have reasonable time to
+become involved in the discussion and review process if they wish.
+
+The default for each contribution is that it is accepted once no committer has an objection.
+During a review, committers may also request that a specific contributor who is most versed in a
+particular area gives a "LGTM" before the PR can be merged. There is no additional "sign off"
+process for contributions to land. Once all issues brought by committers are addressed it can
+be landed by any committer.
+
+In the case of an objection being raised in a pull request by another committer, all involved
+committers should seek to arrive at a consensus by way of addressing concerns being expressed
+by discussion, compromise on the proposed change, or withdrawal of the proposed change.
+
+If a contribution is controversial and committers cannot agree about how to get it to land
+or if it should land then it should be escalated to the TC. TC members should regularly
+discuss pending contributions in order to find a resolution. It is expected that only a
+small minority of issues be brought to the TC for resolution and that discussion and
+compromise among committers be the default resolution mechanism.
+
+### Becoming a Triager
+
+Anyone can become a triager! Read more about the process of being a triager in
+[the triage process document](https://github.com/expressjs/discussions/blob/master/Triager-Guide.md).
+
+Currently, any existing [organization member](https://github.com/orgs/expressjs/people) can nominate
+a new triager. If you are interested in becoming a triager, our best advice is to actively participate
+in the community by helping triaging issues and pull requests. As well we recommend
+to engage in other community activities like attending the TC meetings, and participating in the Slack
+discussions. If you feel ready and have been helping triage some issues, reach out to an active member of the organization to ask if they'd
+be willing to support you. If they agree, they can create a pull request to formalize your nomination. In the case of an objection to the nomination, the triage team is responsible for working with the individuals involved and finding a resolution.
+
+You can also reach out to any of the [organization members](https://github.com/orgs/expressjs/people)
+if you have questions or need guidance.
+
+### Becoming a Committer
+
+All contributors who have landed significant and valuable contributions should be onboarded in a timely manner,
+and added as a committer, and be given write access to the repository.
+
+Committers are expected to follow this policy and continue to send pull requests, go through
+proper review, and have other committers merge their pull requests.
+
+### TC Process
+
+The TC uses a "consensus seeking" process for issues that are escalated to the TC.
+The group tries to find a resolution that has no open objections among TC members.
+If a consensus cannot be reached that has no objections then a majority wins vote
+is called. It is also expected that the majority of decisions made by the TC are via
+a consensus seeking process and that voting is only used as a last-resort.
+
+Resolution may involve returning the issue to project captains with suggestions on
+how to move forward towards a consensus. It is not expected that a meeting of the TC
+will resolve all issues on its agenda during that meeting and may prefer to continue
+the discussion happening among the project captains.
+
+Members can be added to the TC at any time. Any TC member can nominate another committer
+to the TC and the TC uses its standard consensus seeking process to evaluate whether or
+not to add this new member. The TC will consist of a minimum of 3 active members and a
+maximum of 10. If the TC should drop below 5 members the active TC members should nominate
+someone new. If a TC member is stepping down, they are encouraged (but not required) to
+nominate someone to take their place.
+
+TC members will be added as admin's on the Github orgs, npm orgs, and other resources as
+necessary to be effective in the role.
+
+To remain "active" a TC member should have participation within the last 12 months and miss
+no more than six consecutive TC meetings. Our goal is to increase participation, not punish
+people for any lack of participation, this guideline should be only be used as such
+(replace an inactive member with a new active one, for example). Members who do not meet this
+are expected to step down. If A TC member does not step down, an issue can be opened in the
+discussions repo to move them to inactive status. TC members who step down or are removed due
+to inactivity will be moved into inactive status.
+
+Inactive status members can become active members by self nomination if the TC is not already
+larger than the maximum of 10. They will also be given preference if, while at max size, an
+active member steps down.
+
+### Project Captains
+
+The Express TC can designate captains for individual projects/repos in the
+organizations. These captains are responsible for being the primary
+day-to-day maintainers of the repo on a technical and community front.
+Repo captains are empowered with repo ownership and package publication rights.
+When there are conflicts, especially on topics that effect the Express project
+at large, captains are responsible to raise it up to the TC and drive
+those conflicts to resolution. Captains are also responsible for making sure
+community members follow the community guidelines, maintaining the repo
+and the published package, as well as in providing user support.
+
+Like TC members, Repo captains are a subset of committers.
+
+To become a captain for a project the candidate is expected to participate in that
+project for at least 6 months as a committer prior to the request. They should have
+helped with code contributions as well as triaging issues. They are also required to
+have 2FA enabled on both their GitHub and npm accounts.
+
+Any TC member or an existing captain on the **same** repo can nominate another committer
+to the captain role. To do so, they should submit a PR to this document, updating the
+**Active Project Captains** section (while maintaining the sort order) with the project
+name, the nominee's GitHub handle, and their npm username (if different).
+
+- Repos can have as many captains as make sense for the scope of work.
+- A TC member or an existing repo captain **on the same project** can nominate a new captain.
+ Repo captains from other projects should not nominate captains for a different project.
+
+The PR will require at least 2 approvals from TC members and 2 weeks hold time to allow
+for comment and/or dissent. When the PR is merged, a TC member will add them to the
+proper GitHub/npm groups.
+
+#### Active Projects and Captains
+
+The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members)
+
+#### Current Initiative Captains
+
+The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains)
+
+### Inactivity and Emeritus Policy for Any Role
+
+To support the health and continuity of the project, all individuals holding a role within the community (such as Triager, Committer, WG member, Project Captain, or TC member) are encouraged to maintain active participation.
+
+Inactivity is defined as the absence of meaningful involvement in the project—such as contributions, code reviews, triage, meeting attendance, or discussion participation—for a continuous period of 6 months.
+
+#### Exceptions
+
+Anyone may request a temporary leave from active participation due to personal or professional reasons. In such cases, the individual should inform the relevant team or the Technical Committee (TC). During this time, the inactivity policy is paused, and the individual will not be flagged as inactive.
+
+#### Inactivity Process
+
+- If someone is deemed inactive, the individual may be transitioned to an emeritus role that reflects their past contributions. A best effort will be made to inform them that this has occurred. They may request to be reinstated when they are ready to be active again.
+- The emeritus status helps preserve a clear record of contributors who have meaningfully shaped the project over time.
+
+#### Accountability
+
+- The Technical Committee (TC) and the respective captains of each package/team are responsible for assessing activity levels and enacting this policy fairly and transparently, in coordination with other relevant teams.
+- In case of disagreement, the situation can be discussed and resolved by consensus within the TC or appropriate team.
+
+### Developer's Certificate of Origin 1.1
+
+```text
+By making a contribution to this project, I certify that:
+
+ (a) The contribution was created in whole or in part by me and I
+ have the right to submit it under the open source license
+ indicated in the file; or
+
+ (b) The contribution is based upon previous work that, to the best
+ of my knowledge, is covered under an appropriate open source
+ license and I have the right under that license to submit that
+ work with modifications, whether created in whole or in part
+ by me, under the same open source license (unless I am
+ permitted to submit under a different license), as indicated
+ in the file; or
+
+ (c) The contribution was provided directly to me by some other
+ person who certified (a), (b) or (c) and I have not modified
+ it.
+
+ (d) I understand and agree that this project and the contribution
+ are public and that a record of the contribution (including all
+ personal information I submit with it, including my sign-off) is
+ maintained indefinitely and may be redistributed consistent with
+ this project or the open source license(s) involved.
+```
+
+## Collaborator's guide
+
+
+
+### Website Issues
+
+Open issues for the expressjs.com website in https://github.com/expressjs/expressjs.com.
+
+For issues in other Express managed repos (everything in `expressjs`, `pillarjs` or `jshttp` other than `expressjs/express`), be sure to check their contributing guide and open issues and PRs in the appropriate repository.
+
+### PRs and Code contributions
+
+- Tests must pass.
+- Follow the [JavaScript Standard Style](https://standardjs.com/) and `npm run lint`.
+- If you fix a bug, add a test.
+
+### Branches
+
+Use the `master` branch for bug fixes or minor work that is intended for the
+current release stream.
+
+Use the correspondingly named branch, e.g. `6.x`, for anything intended for
+a future release of Express.
+
+### Steps for contributing
+
+1. Create an issue for the
+ bug you want to fix or the feature that you want to add.
+2. Create your own fork on GitHub, then
+ checkout your fork.
+3. Write your code in your local copy. It's good practice to create a branch for
+ each new issue you work on, although not compulsory.
+4. To run the test suite, first install the dependencies by running `npm install`,
+ then run `npm test`.
+5. Ensure your code is linted by running `npm run lint` -- fix any issue you
+ see listed.
+6. If the tests pass, you can commit your changes to your fork and then create
+ a pull request from there. Make sure to reference your issue from the pull
+ request comments by including the issue number e.g. `#123`.
+
+### Issues which are questions
+
+We will typically close any vague issues or questions that are specific to some
+app you are writing. Please double check the docs and other references before
+being trigger happy with posting a question issue.
+
+Things that will help get your question issue looked at:
+
+- Full and runnable JS code.
+- Clear description of the problem or unexpected behavior.
+- Clear description of the expected result.
+- Steps you have taken to debug it yourself.
+
+If you post a question and do not outline the above items or make it easy for
+us to understand and reproduce your issue, it will be closed.
+
+If your question meets all of the above requirements but you do not believe it needs to be looked at
+by the maintainers
+(for example, if you are just looking for community input) please open it as a discussion topic instead
+of an issue. If you
+are unsure and open an issue, we may move it to discussions if we triage them and decide they do
+not need high
+visibility or maintainer input.
+
+## Security Policies and Procedures
+
+
+
+This document outlines security procedures and general policies for the Express
+project.
+
+- [Reporting a Bug](#reporting-a-bug)
+- [Disclosure Policy](#disclosure-policy)
+- [Comments on this Policy](#comments-on-this-policy)
+
+### Reporting a Bug
+
+The Express team and community take all security bugs in Express seriously.
+Thank you for improving the security of Express. We appreciate your efforts and
+responsible disclosure and will make every effort to acknowledge your
+contributions.
+
+Report security bugs by emailing `express-security@lists.openjsf.org`.
+
+To ensure the timely response to your report, please ensure that the entirety
+of the report is contained within the email body and not solely behind a web
+link or an attachment.
+
+The lead maintainer will acknowledge your email within 48 hours, and will send a
+more detailed response within 48 hours indicating the next steps in handling
+your report. After the initial reply to your report, the security team will
+endeavor to keep you informed of the progress towards a fix and full
+announcement, and may ask for additional information or guidance.
+
+Report security bugs in third-party modules to the person or team maintaining
+the module.
+
+### Pre-release Versions
+
+Alpha and Beta releases are unstable and **not suitable for production use**.
+Vulnerabilities found in pre-releases should be reported according to the [Reporting a Bug](#reporting-a-bug) section.
+Due to the unstable nature of the branch it is not guaranteed that any fixes will be released in the next pre-release.
+
+### Disclosure Policy
+
+When the security team receives a security bug report, they will assign it to a
+primary handler. This person will coordinate the fix and release process,
+involving the following steps:
+
+- Confirm the problem and determine the affected versions.
+- Audit code to find any potential similar problems.
+- Prepare fixes for all releases still under maintenance. These fixes will be
+ released as fast as possible to npm.
+
+### The Express Threat Model
+
+We are currently working on a new version of the security model, the most updated version can be found [here](https://github.com/expressjs/security-wg/blob/main/docs/ThreatModel.md)
+
+### Comments on this Policy
+
+If you have suggestions on how this process could be improved please submit a
+pull request.
+
+---
+
+# Contributing to Expressjs.com {#expressjs-website-contributing}
+
+
+
+### The Official Documentation of the Express.js Framework
+
+This is the contribution documentation for the [expressjs.com](https://github.com/expressjs/expressjs.com) website.
+
+#### Need some ideas? These are some typical issues.
+
+1. **Website issues**: If you see anything on the site that could use a tune-up, think about how to fix it.
+ - Display or screen sizing problems
+ - Mobile responsiveness issues
+ - Missing or broken accessibility features
+ - Website outages
+ - Broken links
+ - Page structure or user interface enhancements
+
+2. **Content Issues**: Fix anything related to site content or typos.
+ - Spelling errors
+ - Incorrect/outdated Express.js documentation
+ - Missing content
+
+3. **Translation Issues**: Fix any translation errors or contribute new content.
+ - Fix spelling errors
+ - Fix incorrect/poorly translated words
+ - Check out the [Contributing translations](#contributing-translations) section below for a contributing guide.
+
+#### Want to work on a backlog issue?
+
+We often have bugs or enhancements that need work. You can find these under our repo's [Issues tab](https://github.com/expressjs/expressjs.com/issues). Check out the tags to find something that's a good match for you.
+
+#### Have an idea? Found a bug?
+
+If you've found a bug or a typo, or if you have an idea for an enhancement, you can:
+
+- Submit a [new issue](https://github.com/expressjs/expressjs.com/issues/new/choose) on our repo. Do this for larger proposals, or if you'd like to discuss or get feedback first.
+
+- Make a [GitHub pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). If you have already done work, and it's ready to go, feel free to send it our way.
+
+## Getting Started
+
+The steps below will guide you through the Expressjs.com contribution process.
+
+#### Step 1: (OPTIONAL) Open a New Issue
+
+So you've found a problem that you want to fix, or have a site enhancement you want to make.
+
+1. If you want to get feedback or discuss, open a discussion [issue](https://github.com/expressjs/expressjs.com/issues/new/choose) prior to starting work. This is not required, but encouraged for larger proposals.
+ - While we highly encourage this step, it is only for submissions proposing significant change. It helps us to clarify and focus the work, and ensure it aligns with overall project priorities.
+ - For submissions proposing minor improvements or corrections, this is not needed. You can skip this step.
+ - When opening an issue please give it a title and fill in the description section. The more details you provide, the more feedback we can give.
+
+2. After receiving your issue the Express.js documentation team will respond with feedback. We read every submission and always try to respond quickly with feedback.
+ - For submissions proposing significant change, we encourage you to follow the review process before starting work.
+
+#### Step 2: Get the Application Code Base
+
+Clone the repo and get the code:
+
+```sh
+git clone https://github.com/expressjs/expressjs.com.git
+```
+
+After you've got the code you're ready to start making your changes!
+
+But just in case you need a little extra explanation, this section below outlines the main sections of the code base, where most changes are likely to be made.
+
+**Markdown Page Files**:
+
+- These files render to html and make up the individual pages of the site. Most of the site's documentation text content is written in `md` files.
+- Change these to make changes to individual pages' content/text or markup.
+- Each language has its own complete set of pages, located under their respective language directories - all the Spanish markdown content is found in the `es` directory, for example.
+
+**Includes Partials and Layout Templates**
+
+- `_includes` are partials that are imported and reused across multiple pages.
+ - These are used to import text content for reuse across pages, such as the API documentation, e.g., `_includes > api > en > 5x`, which is included in every language.
+ - These are used to include the page components that make up site-wide user interface and periphery structure, e.g., Header, Footer, etc.
+- `_layouts` are the templates used to wrap the site's individual pages.
+ - These are used to display the structure of the site's periphery, such as the header and footer, and for injecting and displaying individual markdown pages inside the `content` tag.
+
+**Blog Markdown Files**
+
+- These files make up the individual blog posts. If you want to contribute a blog post please
+ follow the specific instructions for [How to write a blog post.](https://expressjs.com/en/blog/write-post)
+- Located under the `_posts` directory.
+
+**CSS or Javascript**
+
+- All css and js files are kept in `css` and `js` folders on the project root.
+
+The Express.js website is built using [Jekyll](https://jekyllrb.com/) and is hosted on [GitHub Pages](https://pages.github.com/).
+
+#### Step 3: Running the Application
+
+Now you'll need a way to see your changes, which means you'll need a running version of the application. You have two options.
+
+1. **Run Locally**: This gets the local version of the application up and running on your machine. Follow our [Local Setup Guide](https://github.com/expressjs/expressjs.com?tab=readme-ov-file#build-the-website-locally) to use this option.
+ - This is the recommended option for moderate to complex work.
+
+2. **Run using Deploy Preview**: Use this option if you don't want to bother with a local installation. Part of our continuous integration pipeline includes [Netlify Deploy Preview](https://docs.netlify.com/deploy/deploy-types/deploy-previews/).
+ 1. To use this you'll need to get your changes online - after you've made your first commit on your feature branch, make a _draft_ pull request.
+ 2. After the build steps are complete, you'll have access to a **Deploy Preview** tab that will run your changes on the web, rebuilding after each commit is pushed.
+ 3. After you are completely done your work, and it's ready for review, remove the draft status on your pull request and submit your work.
+
+## Contributing translations
+
+We use Crowdin to manage our translations in multiple languages and achieve automatic translation with artificial intelligence. Since these translations can be inefficient in some cases, we need help from the community to provide accurate and helpful translations.
+
+The documentation is translated into these languages:
+
+- Chinese Simplified (`zh-cn`)
+- Chinese Traditional (`zh-tw`)
+- English (`en`)
+- French (`fr`)
+- German (`de`)
+- Italian (`it`)
+- Japanese (`ja`)
+- Korean (`ko`)
+- Brazilian Portuguese (`pt-br`)
+- Spanish (`es`)
+
+### How to translate
+
+1. Request to join the Express.js Website project on [Crowdin](https://express.crowdin.com/website)
+2. [Select the language you want to translate](https://support.crowdin.com/for-translators/#starting-translation)
+3. [Start translating](https://support.crowdin.com/online-editor/)
diff --git a/astro/src/content/resources/ja/glossary.md b/astro/src/content/resources/ja/glossary.md
new file mode 100755
index 0000000000..8b45bf01eb
--- /dev/null
+++ b/astro/src/content/resources/ja/glossary.md
@@ -0,0 +1,62 @@
+---
+title: Express glossary
+description: A comprehensive glossary of terms related to Express.js, Node.js, middleware, routing, and other key concepts to help you understand and use Express effectively.
+---
+
+# Glossary
+
+### application
+
+In general, one or more programs that are designed to carry out operations for a specific purpose. In the context of Express, a program that uses the Express API running on the Node.js platform. Might also refer to an [app object](/en/api#express).
+
+### API
+
+Application programming interface. Spell out the abbreviation when it is first used.
+
+### Express
+
+A fast, un-opinionated, minimalist web framework for Node.js applications. In general, "Express" is preferred to "Express.js," though the latter is acceptable.
+
+### libuv
+
+A multi-platform support library which focuses on asynchronous I/O, primarily developed for use by Node.js.
+
+### middleware
+
+A function that is invoked by the Express routing layer before the final request handler, and thus sits in the middle between a raw request and the final intended route. A few fine points of terminology around middleware:
+
+- `var foo = require('middleware')` is called _requiring_ or _using_ a Node.js module. Then the statement `var mw = foo()` typically returns the middleware.
+- `app.use(mw)` is called _adding the middleware to the global processing stack_.
+- `app.get('/foo', mw, function (req, res) { ... })` is called _adding the middleware to the "GET /foo" processing stack_.
+
+### Node.js
+
+A software platform that is used to build scalable network applications. Node.js uses JavaScript as its scripting language, and achieves high throughput via non-blocking I/O and a single-threaded event loop. See [nodejs.org](https://nodejs.org/en/). **Usage note**: Initially, "Node.js," thereafter "Node".
+
+### open-source, open source
+
+When used as an adjective, hyphenate; for example: "This is open-source software." See [Open-source software on Wikipedia](http://en.wikipedia.org/wiki/Open-source_software).
+
+{% capture english-rules %}
+
+Although it is common not to hyphenate this term, we are using the standard English rules for hyphenating a compound adjective.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=english-rules %}
+
+### request
+
+An HTTP request. A client submits an HTTP request message to a server, which returns a response. The request must use one of several [request methods](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods) such as GET, POST, and so on.
+
+### response
+
+An HTTP response. A server returns an HTTP response message to the client. The response contains completion status information about the request and might also contain requested content in its message body.
+
+### route
+
+Part of a URL that identifies a resource. For example, in `http://foo.com/products/id`, "/products/id" is the route.
+
+### router
+
+See [router](/en/api#router) in the API reference.
diff --git a/astro/src/content/resources/ja/middleware/body-parser.md b/astro/src/content/resources/ja/middleware/body-parser.md
new file mode 100644
index 0000000000..e82649a95c
--- /dev/null
+++ b/astro/src/content/resources/ja/middleware/body-parser.md
@@ -0,0 +1,498 @@
+---
+title: Express body-parser middleware
+module: body-parser
+---
+
+# body-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+
+Node.js body parsing middleware.
+
+Parse incoming request bodies in a middleware before your handlers, available
+under the `req.body` property.
+
+**Note** As `req.body`'s shape is based on user-controlled input, all
+properties and values in this object are untrusted and should be validated
+before trusting. For example, `req.body.foo.toString()` may fail in multiple
+ways, for example the `foo` property may not be there or may not be a string,
+and `toString` may not be a function and instead a string or other user input.
+
+[Learn about the anatomy of an HTTP transaction in Node.js](https://nodejs.org/en/learn/http/anatomy-of-an-http-transaction).
+
+_This does not handle multipart bodies_, due to their complex and typically
+large nature. For multipart bodies, you may be interested in the following
+modules:
+
+- [busboy](https://www.npmjs.com/package/busboy#readme) and
+ [connect-busboy](https://www.npmjs.com/package/connect-busboy#readme)
+- [multiparty](https://www.npmjs.com/package/multiparty#readme) and
+ [connect-multiparty](https://www.npmjs.com/package/connect-multiparty#readme)
+- [formidable](https://www.npmjs.com/package/formidable#readme)
+- [multer](https://www.npmjs.com/package/multer#readme)
+
+This module provides the following parsers:
+
+- [JSON body parser](#bodyparserjsonoptions)
+- [Raw body parser](#bodyparserrawoptions)
+- [Text body parser](#bodyparsertextoptions)
+- [URL-encoded form body parser](#bodyparserurlencodedoptions)
+
+Other body parsers you might be interested in:
+
+- [body](https://www.npmjs.com/package/body#readme)
+- [co-body](https://www.npmjs.com/package/co-body#readme)
+
+## Installation
+
+```sh
+$ npm install body-parser
+```
+
+## API
+
+```js
+const bodyParser = require('body-parser');
+```
+
+The `bodyParser` object exposes various factories to create middlewares. All
+middlewares will populate the `req.body` property with the parsed body when
+the `Content-Type` request header matches the `type` option.
+
+The various errors returned by this module are described in the
+[errors section](#errors).
+
+### bodyParser.json([options])
+
+Returns middleware that only parses `json` and only looks at requests where
+the `Content-Type` header matches the `type` option. This parser accepts any
+Unicode encoding of the body and supports automatic inflation of `gzip`,
+`br` (brotli) and `deflate` encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`).
+
+#### Options
+
+The `json` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### defaultCharset
+
+Specify the default character set for the json content if the charset is not
+specified in the `Content-Type` header of the request. Defaults to `utf-8`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### reviver
+
+The `reviver` option is passed directly to `JSON.parse` as the second
+argument. You can find more information on this argument
+[in the MDN documentation about JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Example.3A_Using_the_reviver_parameter).
+
+##### strict
+
+When set to `true`, will only accept arrays and objects; when `false` will
+accept anything `JSON.parse` accepts. Defaults to `true`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not a
+function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `json`), a mime type (like `application/json`), or
+a mime type with a wildcard (like `*/*` or `*/json`). If a function, the `type`
+option is called as `fn(req)` and the request is parsed if it returns a truthy
+value. Defaults to `application/json`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.raw([options])
+
+Returns middleware that parses all bodies as a `Buffer` and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser supports automatic inflation of `gzip`, `br` (brotli) and `deflate`
+encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This will be a `Buffer` object
+of the body.
+
+#### Options
+
+The `raw` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function.
+If not a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this
+can be an extension name (like `bin`), a mime type (like
+`application/octet-stream`), or a mime type with a wildcard (like `*/*` or
+`application/*`). If a function, the `type` option is called as `fn(req)`
+and the request is parsed if it returns a truthy value. Defaults to
+`application/octet-stream`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.text([options])
+
+Returns middleware that parses all bodies as a string and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser supports automatic inflation of `gzip`, `br` (brotli) and `deflate`
+encodings.
+
+A new `body` string containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This will be a string of the
+body.
+
+#### Options
+
+The `text` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### defaultCharset
+
+Specify the default character set for the text content if the charset is not
+specified in the `Content-Type` header of the request. Defaults to `utf-8`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not
+a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `txt`), a mime type (like `text/plain`), or a mime
+type with a wildcard (like `*/*` or `text/*`). If a function, the `type`
+option is called as `fn(req)` and the request is parsed if it returns a
+truthy value. Defaults to `text/plain`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.urlencoded([options])
+
+Returns middleware that only parses `urlencoded` bodies and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser accepts only UTF-8 encoding of the body and supports automatic
+inflation of `gzip`, `br` (brotli) and `deflate` encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This object will contain
+key-value pairs, where the value can be a string or array (when `extended` is
+`false`), or any type (when `extended` is `true`).
+
+#### Options
+
+The `urlencoded` function takes an optional `options` object that may contain
+any of the following keys:
+
+##### extended
+
+The "extended" syntax allows for rich objects and arrays to be encoded into the
+URL-encoded format, allowing for a JSON-like experience with URL-encoded. For
+more information, please [see the qs
+library](https://www.npmjs.com/package/qs#readme).
+
+Defaults to `false`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### parameterLimit
+
+The `parameterLimit` option controls the maximum number of parameters that
+are allowed in the URL-encoded data. If a request contains more parameters
+than this value, a 413 will be returned to the client. Defaults to `1000`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not
+a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `urlencoded`), a mime type (like
+`application/x-www-form-urlencoded`), or a mime type with a wildcard (like
+`*/x-www-form-urlencoded`). If a function, the `type` option is called as
+`fn(req)` and the request is parsed if it returns a truthy value. Defaults
+to `application/x-www-form-urlencoded`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+##### defaultCharset
+
+The default charset to parse as, if not specified in content-type. Must be
+either `utf-8` or `iso-8859-1`. Defaults to `utf-8`.
+
+##### charsetSentinel
+
+Whether to let the value of the `utf8` parameter take precedence as the charset
+selector. It requires the form to contain a parameter named `utf8` with a value
+of `✓`. Defaults to `false`.
+
+##### interpretNumericEntities
+
+Whether to decode numeric entities such as `☺` when parsing an iso-8859-1
+form. Defaults to `false`.
+
+##### depth
+
+The `depth` option is used to configure the maximum depth of the `qs` library when `extended` is `true`. This allows you to limit the amount of keys that are parsed and can be useful to prevent certain types of abuse. Defaults to `32`. It is recommended to keep this value as low as possible.
+
+## Errors
+
+The middlewares provided by this module create errors using the
+[`http-errors` module](https://www.npmjs.com/package/http-errors). The errors
+will typically have a `status`/`statusCode` property that contains the suggested
+HTTP response code, an `expose` property to determine if the `message` property
+should be displayed to the client, a `type` property to determine the type of
+error without matching against the `message`, and a `body` property containing
+the read body, if available.
+
+The following are the common errors created, though any error can come through
+for various reasons.
+
+### content encoding unsupported
+
+This error will occur when the request had a `Content-Encoding` header that
+contained an encoding but the "inflation" option was set to `false`. The
+`status` property is set to `415`, the `type` property is set to
+`'encoding.unsupported'`, and the `charset` property will be set to the
+encoding that is unsupported.
+
+### entity parse failed
+
+This error will occur when the request contained an entity that could not be
+parsed by the middleware. The `status` property is set to `400`, the `type`
+property is set to `'entity.parse.failed'`, and the `body` property is set to
+the entity value that failed parsing.
+
+### entity verify failed
+
+This error will occur when the request contained an entity that could not be
+failed verification by the defined `verify` option. The `status` property is
+set to `403`, the `type` property is set to `'entity.verify.failed'`, and the
+`body` property is set to the entity value that failed verification.
+
+### request aborted
+
+This error will occur when the request is aborted by the client before reading
+the body has finished. The `received` property will be set to the number of
+bytes received before the request was aborted and the `expected` property is
+set to the number of expected bytes. The `status` property is set to `400`
+and `type` property is set to `'request.aborted'`.
+
+### request entity too large
+
+This error will occur when the request body's size is larger than the "limit"
+option. The `limit` property will be set to the byte limit and the `length`
+property will be set to the request body's length. The `status` property is
+set to `413` and the `type` property is set to `'entity.too.large'`.
+
+### request size did not match content length
+
+This error will occur when the request's length did not match the length from
+the `Content-Length` header. This typically occurs when the request is malformed,
+typically when the `Content-Length` header was calculated based on characters
+instead of bytes. The `status` property is set to `400` and the `type` property
+is set to `'request.size.invalid'`.
+
+### stream encoding should not be set
+
+This error will occur when something called the `req.setEncoding` method prior
+to this middleware. This module operates directly on bytes only and you cannot
+call `req.setEncoding` when using this module. The `status` property is set to
+`500` and the `type` property is set to `'stream.encoding.set'`.
+
+### stream is not readable
+
+This error will occur when the request is no longer readable when this middleware
+attempts to read it. This typically means something other than a middleware from
+this module read the request body already and the middleware was also configured to
+read the same request. The `status` property is set to `500` and the `type`
+property is set to `'stream.not.readable'`.
+
+### too many parameters
+
+This error will occur when the content of the request exceeds the configured
+`parameterLimit` for the `urlencoded` parser. The `status` property is set to
+`413` and the `type` property is set to `'parameters.too.many'`.
+
+### unsupported charset "BOGUS"
+
+This error will occur when the request had a charset parameter in the
+`Content-Type` header, but the `iconv-lite` module does not support it OR the
+parser does not support it. The charset is contained in the message as well
+as in the `charset` property. The `status` property is set to `415`, the
+`type` property is set to `'charset.unsupported'`, and the `charset` property
+is set to the charset that is unsupported.
+
+### unsupported content encoding "bogus"
+
+This error will occur when the request had a `Content-Encoding` header that
+contained an unsupported encoding. The encoding is contained in the message
+as well as in the `encoding` property. The `status` property is set to `415`,
+the `type` property is set to `'encoding.unsupported'`, and the `encoding`
+property is set to the encoding that is unsupported.
+
+### The input exceeded the depth
+
+This error occurs when using `bodyParser.urlencoded` with the `extended` property set to `true` and the input exceeds the configured `depth` option. The `status` property is set to `400`. It is recommended to review the `depth` option and evaluate if it requires a higher value. When the `depth` option is set to `32` (default value), the error will not be thrown.
+
+## Examples
+
+### Express/Connect top-level generic
+
+This example demonstrates adding a generic JSON and URL-encoded parser as a
+top-level middleware, which will parse the bodies of all incoming requests.
+This is the simplest setup.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// parse application/x-www-form-urlencoded
+app.use(bodyParser.urlencoded());
+
+// parse application/json
+app.use(bodyParser.json());
+
+app.use(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.write('you posted:\n');
+ res.end(String(JSON.stringify(req.body, null, 2)));
+});
+```
+
+### Express route-specific
+
+This example demonstrates adding body parsers specifically to the routes that
+need them. In general, this is the most recommended way to use body-parser with
+Express.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// create application/json parser
+const jsonParser = bodyParser.json();
+
+// create application/x-www-form-urlencoded parser
+const urlencodedParser = bodyParser.urlencoded();
+
+// POST /login gets urlencoded bodies
+app.post('/login', urlencodedParser, function (req, res) {
+ if (!req.body || !req.body.username) res.sendStatus(400);
+ res.send('welcome, ' + req.body.username);
+});
+
+// POST /api/users gets JSON bodies
+app.post('/api/users', jsonParser, function (req, res) {
+ if (!req.body) res.sendStatus(400);
+ // create user in req.body
+});
+```
+
+### Change accepted type for parsers
+
+All the parsers accept a `type` option which allows you to change the
+`Content-Type` that the middleware will parse.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// parse various different custom JSON types as JSON
+app.use(bodyParser.json({ type: 'application/*+json' }));
+
+// parse some custom thing into a Buffer
+app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }));
+
+// parse an HTML body into a string
+app.use(bodyParser.text({ type: 'text/html' }));
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/body-parser/ci.yml?branch=master&label=ci
+[ci-url]: https://github.com/expressjs/body-parser/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coverallsCoverage/github/expressjs/body-parser?branch=master
+[coveralls-url]: https://coveralls.io/r/expressjs/body-parser?branch=master
+[npm-downloads-image]: https://img.shields.io/npm/dm/body-parser
+[npm-url]: https://npmjs.com/package/body-parser
+[npm-version-image]: https://img.shields.io/npm/v/body-parser
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/body-parser/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/body-parser
diff --git a/astro/src/content/resources/ja/middleware/compression.md b/astro/src/content/resources/ja/middleware/compression.md
new file mode 100644
index 0000000000..6ac63fcb7a
--- /dev/null
+++ b/astro/src/content/resources/ja/middleware/compression.md
@@ -0,0 +1,314 @@
+---
+title: Express compression middleware
+module: compression
+---
+
+# compression
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+[![Funding][funding-image]][funding-url]
+
+Node.js compression middleware.
+
+The following compression codings are supported:
+
+- deflate
+- gzip
+- br (brotli)
+
+**Note** Brotli is supported only since Node.js versions v11.7.0 and v10.16.0.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```bash
+$ npm install compression
+```
+
+## API
+
+```js
+var compression = require('compression');
+```
+
+### compression([options])
+
+Returns the compression middleware using the given `options`. The middleware
+will attempt to compress response bodies for all requests that traverse through
+the middleware, based on the given `options`.
+
+This middleware will never compress responses that include a `Cache-Control`
+header with the [`no-transform` directive](https://tools.ietf.org/html/rfc7234#section-5.2.2.4),
+as compressing will transform the body.
+
+#### Options
+
+`compression()` accepts these properties in the options object. In addition to
+those listed below, [zlib](https://nodejs.org/api/zlib.html) options may be
+passed in to the options object or
+[brotli](https://nodejs.org/api/zlib.html#zlib_class_brotlioptions) options.
+
+##### chunkSize
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_CHUNK`, or `16384`.
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### filter
+
+Type: `Function`
+
+A function to decide if the response should be considered for compression.
+This function is called as `filter(req, res)` and is expected to return
+`true` to consider the response for compression, or `false` to not compress
+the response.
+
+The default filter function uses the [compressible](https://www.npmjs.com/package/compressible)
+module to determine if `res.getHeader('Content-Type')` is compressible.
+
+##### level
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_COMPRESSION`, or `-1`
+
+The level of zlib compression to apply to responses. A higher level will result
+in better compression, but will take longer to complete. A lower level will
+result in less compression, but will be much faster.
+
+This is an integer in the range of `0` (no compression) to `9` (maximum
+compression). The special value `-1` can be used to mean the "default
+compression level", which is a default compromise between speed and
+compression (currently equivalent to level 6).
+
+- `-1` Default compression level (also `zlib.constants.Z_DEFAULT_COMPRESSION`).
+- `0` No compression (also `zlib.constants.Z_NO_COMPRESSION`).
+- `1` Fastest compression (also `zlib.constants.Z_BEST_SPEED`).
+- `2`
+- `3`
+- `4`
+- `5`
+- `6` (currently what `zlib.constants.Z_DEFAULT_COMPRESSION` points to).
+- `7`
+- `8`
+- `9` Best compression (also `zlib.constants.Z_BEST_COMPRESSION`).
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### memLevel
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_MEMLEVEL`, or `8`
+
+This specifies how much memory should be allocated for the internal compression
+state and is an integer in the range of `1` (minimum level) and `9` (maximum
+level).
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### brotli
+
+Type: `Object`
+
+This specifies the options for configuring Brotli. See [Node.js documentation](https://nodejs.org/api/zlib.html#class-brotlioptions) for a complete list of available options.
+
+##### strategy
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_STRATEGY`
+
+This is used to tune the compression algorithm. This value only affects the
+compression ratio, not the correctness of the compressed output, even if it
+is not set appropriately.
+
+- `zlib.constants.Z_DEFAULT_STRATEGY` Use for normal data.
+- `zlib.constants.Z_FILTERED` Use for data produced by a filter (or predictor).
+ Filtered data consists mostly of small values with a somewhat random
+ distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect is to force more Huffman coding and less
+ string matching; it is somewhat intermediate between `zlib.constants.Z_DEFAULT_STRATEGY`
+ and `zlib.constants.Z_HUFFMAN_ONLY`.
+- `zlib.constants.Z_FIXED` Use to prevent the use of dynamic Huffman codes, allowing
+ for a simpler decoder for special applications.
+- `zlib.constants.Z_HUFFMAN_ONLY` Use to force Huffman encoding only (no string match).
+- `zlib.constants.Z_RLE` Use to limit match distances to one (run-length encoding).
+ This is designed to be almost as fast as `zlib.constants.Z_HUFFMAN_ONLY`, but give
+ better compression for PNG image data.
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### threshold
+
+Type: `Number` or `String`
+Default: `1kb`
+
+The byte threshold for the response body size before compression is considered
+for the response. This is a number of bytes or any string
+accepted by the [bytes](https://www.npmjs.com/package/bytes) module.
+
+**Note** this is only an advisory setting; if the response size cannot be determined
+at the time the response headers are written, then it is assumed the response is
+_over_ the threshold. To guarantee the response size can be determined, be sure
+set a `Content-Length` response header.
+
+##### windowBits
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_WINDOWBITS`, or `15`
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### enforceEncoding
+
+Type: `String`
+Default: `identity`
+
+This is the default encoding to use when the client does not specify an encoding in the request's [Accept-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) header.
+
+#### .filter
+
+The default `filter` function. This is used to construct a custom filter
+function that is an extension of the default function.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+app.use(compression({ filter: shouldCompress }));
+
+function shouldCompress(req, res) {
+ if (req.headers['x-no-compression']) {
+ // don't compress responses with this request header
+ return false;
+ }
+
+ // fallback to standard filter function
+ return compression.filter(req, res);
+}
+```
+
+### res.flush
+
+This module adds a `res.flush()` method to force the partially-compressed
+response to be flushed to the client.
+
+## Examples
+
+### express
+
+When using this module with express, simply `app.use` the module as
+high as you like. Requests that pass through the middleware will be compressed.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress all responses
+app.use(compression());
+
+// add all routes
+```
+
+### Node.js HTTP server
+
+```js
+var compression = require('compression')({ threshold: 0 });
+var http = require('http');
+
+function createServer(fn) {
+ return http.createServer(function (req, res) {
+ compression(req, res, function (err) {
+ if (err) {
+ res.statusCode = err.status || 500;
+ res.end(err.message);
+ return;
+ }
+
+ fn(req, res);
+ });
+ });
+}
+
+var server = createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello world!');
+});
+
+server.listen(3000, () => {
+ console.log('> Listening at http://localhost:3000');
+});
+```
+
+### Server-Sent Events
+
+Because of the nature of compression this module does not work out of the box
+with server-sent events. To compress content, a window of the output needs to
+be buffered up in order to get good compression. Typically when using server-sent
+events, there are certain block of data that need to reach the client.
+
+You can achieve this by calling `res.flush()` when you need the data written to
+actually make it to the client.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress responses
+app.use(compression());
+
+// server-sent event stream
+app.get('/events', function (req, res) {
+ res.setHeader('Content-Type', 'text/event-stream');
+ res.setHeader('Cache-Control', 'no-cache');
+
+ // send a ping approx every 2 seconds
+ var timer = setInterval(function () {
+ res.write('data: ping\n\n');
+
+ // !!! this is the important part
+ res.flush();
+ }, 2000);
+
+ res.on('close', function () {
+ clearInterval(timer);
+ });
+});
+```
+
+## Contributing
+
+The Express.js project welcomes all constructive contributions. Contributions take many forms,
+from code for bug fixes and enhancements, to additions and fixes to documentation, additional
+tests, triaging incoming pull requests and issues, and more!
+
+See the [Contributing Guide](https://github.com/expressjs/express/blob/master/Contributing.md) for more technical details on contributing.
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://badgen.net/npm/v/compression
+[npm-url]: https://npmjs.org/package/compression
+[downloads-image]: https://badgen.net/npm/dm/compression
+[downloads-url]: https://npmcharts.com/compare/compression?minimal=true
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/compression/master?label=CI
+[github-actions-ci-url]: https://github.com/expressjs/compression/actions?query=workflow%3Aci
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/compression/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/compression
+[funding-url]: https://opencollective.com/express
+[funding-image]: https://badgen.net/badge/icon/sponsor/pink?icon=github&label=Open%20Collective
diff --git a/astro/src/content/resources/ja/middleware/cookie-parser.md b/astro/src/content/resources/ja/middleware/cookie-parser.md
new file mode 100644
index 0000000000..2a59496387
--- /dev/null
+++ b/astro/src/content/resources/ja/middleware/cookie-parser.md
@@ -0,0 +1,124 @@
+---
+title: Express cookie-parser middleware
+module: cookie-parser
+---
+
+# cookie-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Parse `Cookie` header and populate `req.cookies` with an object keyed by the
+cookie names. Optionally you may enable signed cookie support by passing a
+`secret` string, which assigns `req.secret` so it may be used by other
+middleware.
+
+## Installation
+
+```sh
+$ npm install cookie-parser
+```
+
+## API
+
+```js
+var cookieParser = require('cookie-parser');
+```
+
+### cookieParser(secret, options)
+
+Create a new cookie parser middleware function using the given `secret` and
+`options`.
+
+- `secret` a string or array used for signing cookies. This is optional and if
+ not specified, will not parse signed cookies. If a string is provided, this
+ is used as the secret. If an array is provided, an attempt will be made to
+ unsign the cookie with each secret in order.
+- `options` an object that is passed to `cookie.parse` as the second option. See
+ [cookie](https://www.npmjs.org/package/cookie) for more information.
+ - `decode` a function to decode the value of the cookie
+
+The middleware will parse the `Cookie` header on the request and expose the
+cookie data as the property `req.cookies` and, if a `secret` was provided, as
+the property `req.signedCookies`. These properties are name value pairs of the
+cookie name to cookie value.
+
+When `secret` is provided, this module will unsign and validate any signed cookie
+values and move those name value pairs from `req.cookies` into `req.signedCookies`.
+A signed cookie is a cookie that has a value prefixed with `s:`. Signed cookies
+that fail signature validation will have the value `false` instead of the tampered
+value.
+
+In addition, this module supports special "JSON cookies". These are cookie where
+the value is prefixed with `j:`. When these values are encountered, the value will
+be exposed as the result of `JSON.parse`. If parsing fails, the original value will
+remain.
+
+### cookieParser.JSONCookie(str)
+
+Parse a cookie value as a JSON cookie. This will return the parsed JSON value
+if it was a JSON cookie, otherwise, it will return the passed value.
+
+### cookieParser.JSONCookies(cookies)
+
+Given an object, this will iterate over the keys and call `JSONCookie` on each
+value, replacing the original value with the parsed value. This returns the
+same object that was passed in.
+
+### cookieParser.signedCookie(str, secret)
+
+Parse a cookie value as a signed cookie. This will return the parsed unsigned
+value if it was a signed cookie and the signature was valid. If the value was
+not signed, the original value is returned. If the value was signed but the
+signature could not be validated, `false` is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+### cookieParser.signedCookies(cookies, secret)
+
+Given an object, this will iterate over the keys and check if any value is a
+signed cookie. If it is a signed cookie and the signature is valid, the key
+will be deleted from the object and added to the new object that is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+## Example
+
+```js
+var express = require('express');
+var cookieParser = require('cookie-parser');
+
+var app = express();
+app.use(cookieParser());
+
+app.get('/', function (req, res) {
+ // Cookies that have not been signed
+ console.log('Cookies: ', req.cookies);
+
+ // Cookies that have been signed
+ console.log('Signed Cookies: ', req.signedCookies);
+});
+
+app.listen(8080);
+
+// curl command that sends an HTTP request with two cookies
+// curl http://127.0.0.1:8080 --cookie "Cho=Kim;Greet=Hello"
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/cookie-parser/master?label=ci
+[ci-url]: https://github.com/expressjs/cookie-parser/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/cookie-parser/master
+[coveralls-url]: https://coveralls.io/r/expressjs/cookie-parser?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/cookie-parser
+[npm-url]: https://npmjs.org/package/cookie-parser
+[npm-version-image]: https://badgen.net/npm/v/cookie-parser
diff --git a/astro/src/content/resources/ja/middleware/cookie-session.md b/astro/src/content/resources/ja/middleware/cookie-session.md
new file mode 100644
index 0000000000..2d6d1f885b
--- /dev/null
+++ b/astro/src/content/resources/ja/middleware/cookie-session.md
@@ -0,0 +1,124 @@
+---
+title: Express cookie-session middleware
+module: cookie-session
+---
+
+# cookie-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Parse `Cookie` header and populate `req.cookies` with an object keyed by the
+cookie names. Optionally you may enable signed cookie support by passing a
+`secret` string, which assigns `req.secret` so it may be used by other
+middleware.
+
+## Installation
+
+```sh
+$ npm install cookie-parser
+```
+
+## API
+
+```js
+var cookieParser = require('cookie-parser');
+```
+
+### cookieParser(secret, options)
+
+Create a new cookie parser middleware function using the given `secret` and
+`options`.
+
+- `secret` a string or array used for signing cookies. This is optional and if
+ not specified, will not parse signed cookies. If a string is provided, this
+ is used as the secret. If an array is provided, an attempt will be made to
+ unsign the cookie with each secret in order.
+- `options` an object that is passed to `cookie.parse` as the second option. See
+ [cookie](https://www.npmjs.org/package/cookie) for more information.
+ - `decode` a function to decode the value of the cookie
+
+The middleware will parse the `Cookie` header on the request and expose the
+cookie data as the property `req.cookies` and, if a `secret` was provided, as
+the property `req.signedCookies`. These properties are name value pairs of the
+cookie name to cookie value.
+
+When `secret` is provided, this module will unsign and validate any signed cookie
+values and move those name value pairs from `req.cookies` into `req.signedCookies`.
+A signed cookie is a cookie that has a value prefixed with `s:`. Signed cookies
+that fail signature validation will have the value `false` instead of the tampered
+value.
+
+In addition, this module supports special "JSON cookies". These are cookie where
+the value is prefixed with `j:`. When these values are encountered, the value will
+be exposed as the result of `JSON.parse`. If parsing fails, the original value will
+remain.
+
+### cookieParser.JSONCookie(str)
+
+Parse a cookie value as a JSON cookie. This will return the parsed JSON value
+if it was a JSON cookie, otherwise, it will return the passed value.
+
+### cookieParser.JSONCookies(cookies)
+
+Given an object, this will iterate over the keys and call `JSONCookie` on each
+value, replacing the original value with the parsed value. This returns the
+same object that was passed in.
+
+### cookieParser.signedCookie(str, secret)
+
+Parse a cookie value as a signed cookie. This will return the parsed unsigned
+value if it was a signed cookie and the signature was valid. If the value was
+not signed, the original value is returned. If the value was signed but the
+signature could not be validated, `false` is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+### cookieParser.signedCookies(cookies, secret)
+
+Given an object, this will iterate over the keys and check if any value is a
+signed cookie. If it is a signed cookie and the signature is valid, the key
+will be deleted from the object and added to the new object that is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+## Example
+
+```js
+var express = require('express');
+var cookieParser = require('cookie-parser');
+
+var app = express();
+app.use(cookieParser());
+
+app.get('/', function (req, res) {
+ // Cookies that have not been signed
+ console.log('Cookies: ', req.cookies);
+
+ // Cookies that have been signed
+ console.log('Signed Cookies: ', req.signedCookies);
+});
+
+app.listen(8080);
+
+// curl command that sends an HTTP request with two cookies
+// curl http://127.0.0.1:8080 --cookie "Cho=Kim;Greet=Hello"
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/cookie-parser/master?label=ci
+[ci-url]: https://github.com/expressjs/cookie-parser/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/cookie-parser/master
+[coveralls-url]: https://coveralls.io/r/expressjs/cookie-parser?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/cookie-parser
+[npm-url]: https://npmjs.org/package/cookie-parser
+[npm-version-image]: https://badgen.net/npm/v/cookie-parser
diff --git a/astro/src/content/resources/ja/middleware/cors.md b/astro/src/content/resources/ja/middleware/cors.md
new file mode 100644
index 0000000000..55d70922cb
--- /dev/null
+++ b/astro/src/content/resources/ja/middleware/cors.md
@@ -0,0 +1,261 @@
+---
+title: Express cors middleware
+module: cors
+---
+
+# cors
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+CORS is a [Node.js](https://nodejs.org/en/) package for providing a [Connect](https://github.com/senchalabs/connect)/[Express](https://expressjs.com/) middleware that can be used to enable [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS) with various options.
+
+- [Installation](#installation)
+- [Usage](#usage)
+ - [Simple Usage](#simple-usage-enable-all-cors-requests)
+ - [Enable CORS for a Single Route](#enable-cors-for-a-single-route)
+ - [Configuring CORS](#configuring-cors)
+ - [Configuring CORS w/ Dynamic Origin](#configuring-cors-w-dynamic-origin)
+ - [Enabling CORS Pre-Flight](#enabling-cors-pre-flight)
+ - [Customizing CORS Settings Dynamically per Request](#customizing-cors-settings-dynamically-per-request)
+- [Configuration Options](#configuration-options)
+- [License](#license)
+- [Original Author](#original-author)
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/downloading-and-installing-packages-locally):
+
+```sh
+$ npm install cors
+```
+
+## Usage
+
+### Simple Usage (Enable _All_ CORS Requests)
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.use(cors());
+
+app.get('/products/:id', function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for all origins!' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Enable CORS for a Single Route
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.get('/products/:id', cors(), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for a Single Route' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Configuring CORS
+
+See the [configuration options](#configuration-options) for details.
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+var corsOptions = {
+ origin: 'http://example.com',
+ optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
+};
+
+app.get('/products/:id', cors(corsOptions), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for only example.com.' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Configuring CORS w/ Dynamic Origin
+
+This module supports validating the origin dynamically using a function provided
+to the `origin` option. This function will be passed a string that is the origin
+(or `undefined` if the request has no origin), and a `callback` with the signature
+`callback(error, origin)`.
+
+The `origin` argument to the callback can be any value allowed for the `origin`
+option of the middleware, except a function. See the
+[configuration options](#configuration-options) section for more information on all
+the possible value types.
+
+This function is designed to allow the dynamic loading of allowed origin(s) from
+a backing datasource, like a database.
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+var corsOptions = {
+ origin: function (origin, callback) {
+ // db.loadOrigins is an example call to load
+ // a list of origins from a backing database
+ db.loadOrigins(function (error, origins) {
+ callback(error, origins);
+ });
+ },
+};
+
+app.get('/products/:id', cors(corsOptions), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for an allowed domain.' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Enabling CORS Pre-Flight
+
+Certain CORS requests are considered 'complex' and require an initial
+`OPTIONS` request (called the "pre-flight request"). An example of a
+'complex' CORS request is one that uses an HTTP verb other than
+GET/HEAD/POST (such as DELETE) or that uses custom headers. To enable
+pre-flighting, you must add a new OPTIONS handler for the route you want
+to support:
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.options('/products/:id', cors()); // enable pre-flight request for DELETE request
+app.del('/products/:id', cors(), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for all origins!' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+You can also enable pre-flight across-the-board like so:
+
+```javascript
+app.options('*', cors()); // include before other routes
+```
+
+NOTE: When using this middleware as an application level middleware (for
+example, `app.use(cors())`), pre-flight requests are already handled for all
+routes.
+
+### Customizing CORS Settings Dynamically per Request
+
+For APIs that require different CORS configurations for specific routes or requests, you can dynamically generate CORS options based on the incoming request. The `cors` middleware allows you to achieve this by passing a function instead of static options. This function is called for each incoming request and must use the callback pattern to return the appropriate CORS options.
+
+The function accepts:
+
+1. **`req`**:
+ - The incoming request object.
+
+2. **`callback(error, corsOptions)`**:
+ - A function used to return the computed CORS options.
+ - **Arguments**:
+ - **`error`**: Pass `null` if there’s no error, or an error object to indicate a failure.
+ - **`corsOptions`**: An object specifying the CORS policy for the current request.
+
+Here’s an example that handles both public routes and restricted, credential-sensitive routes:
+
+```javascript
+var dynamicCorsOptions = function (req, callback) {
+ var corsOptions;
+ if (req.path.startsWith('/auth/connect/')) {
+ corsOptions = {
+ origin: 'http://mydomain.com', // Allow only a specific origin
+ credentials: true, // Enable cookies and credentials
+ };
+ } else {
+ corsOptions = { origin: '*' }; // Allow all origins for other routes
+ }
+ callback(null, corsOptions);
+};
+
+app.use(cors(dynamicCorsOptions));
+
+app.get('/auth/connect/twitter', function (req, res) {
+ res.send('CORS dynamically applied for Twitter authentication.');
+});
+
+app.get('/public', function (req, res) {
+ res.send('Public data with open CORS.');
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+## Configuration Options
+
+- `origin`: Configures the **Access-Control-Allow-Origin** CORS header. Possible values:
+ - `Boolean` - set `origin` to `true` to reflect the [request origin](https://datatracker.ietf.org/doc/html/draft-abarth-origin-09), as defined by `req.header('Origin')`, or set it to `false` to disable CORS.
+ - `String` - set `origin` to a specific origin. For example, if you set it to
+ - `"http://example.com"` only requests from "http://example.com" will be allowed.
+ - `"*"` for all domains to be allowed.
+ - `RegExp` - set `origin` to a regular expression pattern which will be used to test the request origin. If it's a match, the request origin will be reflected. For example the pattern `/example\.com$/` will reflect any request that is coming from an origin ending with "example.com".
+ - `Array` - set `origin` to an array of valid origins. Each origin can be a `String` or a `RegExp`. For example `["http://example1.com", /\.example2\.com$/]` will accept any request from "http://example1.com" or from a subdomain of "example2.com".
+ - `Function` - set `origin` to a function implementing some custom logic. The function takes the request origin as the first parameter and a callback (called as `callback(err, origin)`, where `origin` is a non-function value of the `origin` option) as the second.
+- `methods`: Configures the **Access-Control-Allow-Methods** CORS header. Expects a comma-delimited string (ex: 'GET,PUT,POST') or an array (ex: `['GET', 'PUT', 'POST']`).
+- `allowedHeaders`: Configures the **Access-Control-Allow-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Type,Authorization') or an array (ex: `['Content-Type', 'Authorization']`). If not specified, defaults to reflecting the headers specified in the request's **Access-Control-Request-Headers** header.
+- `exposedHeaders`: Configures the **Access-Control-Expose-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Range,X-Content-Range') or an array (ex: `['Content-Range', 'X-Content-Range']`). If not specified, no custom headers are exposed.
+- `credentials`: Configures the **Access-Control-Allow-Credentials** CORS header. Set to `true` to pass the header, otherwise it is omitted.
+- `maxAge`: Configures the **Access-Control-Max-Age** CORS header. Set to an integer to pass the header, otherwise it is omitted.
+- `preflightContinue`: Pass the CORS preflight response to the next handler.
+- `optionsSuccessStatus`: Provides a status code to use for successful `OPTIONS` requests, since some legacy browsers (IE11, various SmartTVs) choke on `204`.
+
+The default configuration is the equivalent of:
+
+```json
+{
+ "origin": "*",
+ "methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
+ "preflightContinue": false,
+ "optionsSuccessStatus": 204
+}
+```
+
+For details on the effect of each CORS header, read [this](https://web.dev/articles/cross-origin-resource-sharing) article.
+
+## License
+
+[MIT License](http://www.opensource.org/licenses/mit-license.php)
+
+## Original Author
+
+[Troy Goode](https://github.com/TroyGoode) ([troygoode@gmail.com](mailto:troygoode@gmail.com))
+
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/cors/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/cors?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/cors.svg
+[downloads-url]: https://npmjs.com/package/cors
+[github-actions-ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/cors/ci.yml?branch=master&label=ci
+[github-actions-ci-url]: https://github.com/expressjs/cors?query=workflow%3Aci
+[npm-image]: https://img.shields.io/npm/v/cors.svg
+[npm-url]: https://npmjs.com/package/cors
diff --git a/astro/src/content/resources/ja/middleware/errorhandler.md b/astro/src/content/resources/ja/middleware/errorhandler.md
new file mode 100644
index 0000000000..20df618320
--- /dev/null
+++ b/astro/src/content/resources/ja/middleware/errorhandler.md
@@ -0,0 +1,133 @@
+---
+title: Express errorhandler middleware
+module: errorhandler
+---
+
+# errorhandler
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Development-only error handler middleware.
+
+This middleware is only intended to be used in a development environment, as
+the _full error stack traces and internal details of any object passed to this
+module_ will be sent back to the client when an error occurs.
+
+When an object is provided to Express as an error, this module will display
+as much about this object as possible, and will do so by using content negotiation
+for the response between HTML, JSON, and plain text.
+
+- When the object is a standard `Error` object, the string provided by the
+ `stack` property will be returned in HTML/text responses.
+- When the object is a non-`Error` object, the result of
+ [util.inspect](https://nodejs.org/api/util.html#util_util_inspect_object_options)
+ will be returned in HTML/text responses.
+- For JSON responses, the result will be an object with all enumerable properties
+ from the object in the response.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install errorhandler
+```
+
+## API
+
+
+
+```js
+var errorhandler = require('errorhandler');
+```
+
+### errorhandler(options)
+
+Create new middleware to handle errors and respond with content negotiation.
+
+#### Options
+
+Error handler accepts these properties in the options object.
+
+##### log
+
+Provide a function to be called with the error and a string representation of
+the error. Can be used to write the error to any desired location, or set to
+`false` to only send the error back in the response. Called as
+`log(err, str, req, res)` where `err` is the `Error` object, `str` is a string
+representation of the error, `req` is the request object and `res` is the
+response object (note, this function is invoked _after_ the response has been
+written).
+
+The default value for this option is `true` unless `process.env.NODE_ENV === 'test'`.
+
+Possible values:
+
+- `true`: Log errors using `console.error(str)`.
+- `false`: Only send the error back in the response.
+- A function: pass the error to a function for handling.
+
+## Examples
+
+### Simple example
+
+Basic example of adding this middleware as the error handler only in development
+with `connect` (`express` also can be used in this example).
+
+```js
+var connect = require('connect');
+var errorhandler = require('errorhandler');
+
+var app = connect();
+
+// assumes NODE_ENV is set by the user
+if (process.env.NODE_ENV === 'development') {
+ // only use in development
+ app.use(errorhandler());
+}
+```
+
+### Custom output location
+
+Sometimes you may want to output the errors to a different location than STDERR
+during development, like a system notification, for example.
+
+
+
+```js
+var connect = require('connect');
+var errorhandler = require('errorhandler');
+var notifier = require('node-notifier');
+
+var app = connect();
+
+// assumes NODE_ENV is set by the user
+if (process.env.NODE_ENV === 'development') {
+ // only use in development
+ app.use(errorhandler({ log: errorNotification }));
+}
+
+function errorNotification(err, str, req) {
+ var title = 'Error in ' + req.method + ' ' + req.url;
+
+ notifier.notify({
+ title: title,
+ message: str,
+ });
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/errorhandler/master
+[coveralls-url]: https://coveralls.io/r/expressjs/errorhandler?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/errorhandler
+[npm-url]: https://npmjs.org/package/errorhandler
+[npm-version-image]: https://badgen.net/npm/v/errorhandler
diff --git a/astro/src/content/resources/ja/middleware/method-override.md b/astro/src/content/resources/ja/middleware/method-override.md
new file mode 100644
index 0000000000..7b97ab855e
--- /dev/null
+++ b/astro/src/content/resources/ja/middleware/method-override.md
@@ -0,0 +1,187 @@
+---
+title: Express method-override middleware
+module: method-override
+---
+
+# method-override
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][travis-image]][travis-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Lets you use HTTP verbs such as PUT or DELETE in places where the client doesn't support it.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install method-override
+```
+
+## API
+
+**NOTE** It is very important that this module is used **before** any module that
+needs to know the method of the request (for example, it _must_ be used prior to
+the `csurf` module).
+
+### methodOverride(getter, options)
+
+Create a new middleware function to override the `req.method` property with a new
+value. This value will be pulled from the provided `getter`.
+
+- `getter` - The getter to use to look up the overridden request method for the request. (default: `X-HTTP-Method-Override`)
+- `options.methods` - The allowed methods the original request must be in to check for a method override value. (default: `['POST']`)
+
+If the found method is supported by node.js core, then `req.method` will be set to
+this value, as if it has originally been that value. The previous `req.method`
+value will be stored in `req.originalMethod`.
+
+#### getter
+
+This is the method of getting the override value from the request. If a function is provided,
+the `req` is passed as the first argument, the `res` as the second argument and the method is
+expected to be returned. If a string is provided, the string is used to look up the method
+with the following rules:
+
+- If the string starts with `X-`, then it is treated as the name of a header and that header
+ is used for the method override. If the request contains the same header multiple times, the
+ first occurrence is used.
+- All other strings are treated as a key in the URL query string.
+
+#### options.methods
+
+This allows the specification of what methods(s) the request _MUST_ be in in order to check for
+the method override value. This defaults to only `POST` methods, which is the only method the
+override should arrive in. More methods may be specified here, but it may introduce security
+issues and cause weird behavior when requests travel through caches. This value is an array
+of methods in upper-case. `null` can be specified to allow all methods.
+
+## Examples
+
+### override using a header
+
+To use a header to override the method, specify the header name
+as a string argument to the `methodOverride` function. To then make
+the call, send a `POST` request to a URL with the overridden method
+as the value of that header. This method of using a header would
+typically be used in conjunction with `XMLHttpRequest` on implementations
+that do not support the method you are trying to use.
+
+```js
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// override with the X-HTTP-Method-Override header in the request
+app.use(methodOverride('X-HTTP-Method-Override'));
+```
+
+Example call with header override using `XMLHttpRequest`:
+
+
+
+```js
+const xhr = new XMLHttpRequest();
+xhr.onload = onload;
+xhr.open('post', '/resource', true);
+xhr.setRequestHeader('X-HTTP-Method-Override', 'DELETE');
+xhr.send();
+
+function onload() {
+ alert('got response: ' + this.responseText);
+}
+```
+
+### override using a query value
+
+To use a query string value to override the method, specify the query
+string key as a string argument to the `methodOverride` function. To
+then make the call, send a `POST` request to a URL with the overridden
+method as the value of that query string key. This method of using a
+query value would typically be used in conjunction with plain HTML
+`
+```
+
+### multiple format support
+
+```js
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// override with different headers; last one takes precedence
+app.use(methodOverride('X-HTTP-Method')); // Microsoft
+app.use(methodOverride('X-HTTP-Method-Override')); // Google/GData
+app.use(methodOverride('X-Method-Override')); // IBM
+```
+
+### custom logic
+
+You can implement any kind of custom logic with a function for the `getter`. The following
+implements the logic for looking in `req.body` that was in `method-override@1`:
+
+```js
+const bodyParser = require('body-parser');
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// NOTE: when using req.body, you must fully parse the request body
+// before you call methodOverride() in your middleware stack,
+// otherwise req.body will not be populated.
+app.use(bodyParser.urlencoded());
+app.use(
+ methodOverride(function (req, res) {
+ if (req.body && typeof req.body === 'object' && '_method' in req.body) {
+ // look in urlencoded POST bodies and delete it
+ const method = req.body._method;
+ delete req.body._method;
+ return method;
+ }
+ })
+);
+```
+
+Example call with query override using HTML `
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/method-override.svg
+[npm-url]: https://npmjs.org/package/method-override
+[travis-image]: https://img.shields.io/travis/expressjs/method-override/master.svg
+[travis-url]: https://travis-ci.org/expressjs/method-override
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/method-override/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/method-override?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/method-override.svg
+[downloads-url]: https://npmjs.org/package/method-override
diff --git a/astro/src/content/resources/ja/middleware/morgan.md b/astro/src/content/resources/ja/middleware/morgan.md
new file mode 100644
index 0000000000..5319d93d57
--- /dev/null
+++ b/astro/src/content/resources/ja/middleware/morgan.md
@@ -0,0 +1,458 @@
+---
+title: Express morgan middleware
+module: morgan
+---
+
+# morgan
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+HTTP request logger middleware for node.js
+
+> Named after [Dexter](http://en.wikipedia.org/wiki/Dexter_Morgan), a show you should not watch until completion.
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install morgan
+```
+
+## API
+
+
+
+```js
+var morgan = require('morgan');
+```
+
+### morgan(format, options)
+
+Create a new morgan logger middleware function using the given `format` and `options`.
+The `format` argument may be a string of a predefined name (see below for the names),
+a string of a format string, or a function that will produce a log entry.
+
+The `format` function will be called with three arguments `tokens`, `req`, and `res`,
+where `tokens` is an object with all defined tokens, `req` is the HTTP request and `res`
+is the HTTP response. The function is expected to return a string that will be the log
+line, or `undefined` / `null` to skip logging.
+
+#### Using a predefined format string
+
+
+
+```js
+morgan('tiny');
+```
+
+#### Using format string of predefined tokens
+
+
+
+```js
+morgan(':method :url :status :res[content-length] - :response-time ms');
+```
+
+#### Using a custom format function
+
+
+
+```js
+morgan(function (tokens, req, res) {
+ return [
+ tokens.method(req, res),
+ tokens.url(req, res),
+ tokens.status(req, res),
+ tokens.res(req, res, 'content-length'),
+ '-',
+ tokens['response-time'](req, res),
+ 'ms',
+ ].join(' ');
+});
+```
+
+#### Options
+
+Morgan accepts these properties in the options object.
+
+##### immediate
+
+Write log line on request instead of response. This means that a requests will
+be logged even if the server crashes, _but data from the response (like the
+response code, content length, etc.) cannot be logged_.
+
+##### skip
+
+Function to determine if logging is skipped, defaults to `false`. This function
+will be called as `skip(req, res)`.
+
+
+
+```js
+// EXAMPLE: only log error responses
+morgan('combined', {
+ skip: function (req, res) {
+ return res.statusCode < 400;
+ },
+});
+```
+
+##### stream
+
+Output stream for writing log lines, defaults to `process.stdout`.
+
+#### Predefined Formats
+
+There are various pre-defined formats provided:
+
+##### combined
+
+Standard Apache combined log output.
+
+```
+:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"
+# will output
+::1 - - [27/Nov/2024:06:21:42 +0000] "GET /combined HTTP/1.1" 200 2 "-" "curl/8.7.1"
+```
+
+##### common
+
+Standard Apache common log output.
+
+```
+:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length]
+# will output
+::1 - - [27/Nov/2024:06:21:46 +0000] "GET /common HTTP/1.1" 200 2
+```
+
+##### dev
+
+Concise output colored by response status for development use. The `:status`
+token will be colored green for success codes, red for server error codes,
+yellow for client error codes, cyan for redirection codes, and uncolored
+for information codes.
+
+```
+:method :url :status :response-time ms - :res[content-length]
+# will output
+GET /dev 200 0.224 ms - 2
+```
+
+##### short
+
+Shorter than default, also including response time.
+
+```
+:remote-addr :remote-user :method :url HTTP/:http-version :status :res[content-length] - :response-time ms
+# will output
+::1 - GET /short HTTP/1.1 200 2 - 0.283 ms
+```
+
+##### tiny
+
+The minimal output.
+
+```
+:method :url :status :res[content-length] - :response-time ms
+# will output
+GET /tiny 200 2 - 0.188 ms
+```
+
+#### Tokens
+
+##### Creating new tokens
+
+To define a token, simply invoke `morgan.token()` with the name and a callback function.
+This callback function is expected to return a string value. The value returned is then
+available as ":type" in this case:
+
+
+
+```js
+morgan.token('type', function (req, res) {
+ return req.headers['content-type'];
+});
+```
+
+Calling `morgan.token()` using the same name as an existing token will overwrite that
+token definition.
+
+The token function is expected to be called with the arguments `req` and `res`, representing
+the HTTP request and HTTP response. Additionally, the token can accept further arguments of
+it's choosing to customize behavior.
+
+##### :date[format]
+
+The current date and time in UTC. The available formats are:
+
+- `clf` for the common log format (`"10/Oct/2000:13:55:36 +0000"`)
+- `iso` for the common ISO 8601 date time format (`2000-10-10T13:55:36.000Z`)
+- `web` for the common RFC 1123 date time format (`Tue, 10 Oct 2000 13:55:36 GMT`)
+
+If no format is given, then the default is `web`.
+
+##### :http-version
+
+The HTTP version of the request.
+
+##### :method
+
+The HTTP method of the request.
+
+##### :pid
+
+The process ID of the Node.js process handling the request.
+
+##### :referrer
+
+The Referrer header of the request. This will use the standard mis-spelled Referer header if exists, otherwise Referrer.
+
+##### :remote-addr
+
+The remote address of the request. This will use `req.ip`, otherwise the standard `req.connection.remoteAddress` value (socket address).
+
+##### :remote-user
+
+The user authenticated as part of Basic auth for the request.
+
+##### :req[header]
+
+The given `header` of the request. If the header is not present, the
+value will be displayed as `"-"` in the log.
+
+##### :res[header]
+
+The given `header` of the response. If the header is not present, the
+value will be displayed as `"-"` in the log.
+
+##### :response-time[digits]
+
+The time between the request coming into `morgan` and when the response
+headers are written, in milliseconds.
+
+The `digits` argument is a number that specifies the number of digits to
+include on the number, defaulting to `3`, which provides microsecond precision.
+
+##### :status
+
+The status code of the response.
+
+If the request/response cycle completes before a response was sent to the
+client (for example, the TCP socket closed prematurely by a client aborting
+the request), then the status will be empty (displayed as `"-"` in the log).
+
+##### :total-time[digits]
+
+The time between the request coming into `morgan` and when the response
+has finished being written out to the connection, in milliseconds.
+
+The `digits` argument is a number that specifies the number of digits to
+include on the number, defaulting to `3`, which provides microsecond precision.
+
+##### :url
+
+The URL of the request. This will use `req.originalUrl` if exists, otherwise `req.url`.
+
+##### :user-agent
+
+The contents of the User-Agent header of the request.
+
+### morgan.compile(format)
+
+Compile a format string into a `format` function for use by `morgan`. A format string
+is a string that represents a single log line and can utilize token syntax.
+Tokens are references by `:token-name`. If tokens accept arguments, they can
+be passed using `[]`, for example: `:token-name[pretty]` would pass the string
+`'pretty'` as an argument to the token `token-name`.
+
+The function returned from `morgan.compile` takes three arguments `tokens`, `req`, and
+`res`, where `tokens` is object with all defined tokens, `req` is the HTTP request and
+`res` is the HTTP response. The function will return a string that will be the log line,
+or `undefined` / `null` to skip logging.
+
+Normally formats are defined using `morgan.format(name, format)`, but for certain
+advanced uses, this compile function is directly available.
+
+## Examples
+
+### express/connect
+
+Sample app that will log all request in the Apache combined format to STDOUT
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+
+var app = express();
+
+app.use(morgan('combined'));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### vanilla http server
+
+Sample app that will log all request in the Apache combined format to STDOUT
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var morgan = require('morgan');
+
+// create "middleware"
+var logger = morgan('combined');
+
+http.createServer(function (req, res) {
+ var done = finalhandler(req, res);
+ logger(req, res, function (err) {
+ if (err) return done(err);
+
+ // respond to request
+ res.setHeader('content-type', 'text/plain');
+ res.end('hello, world!');
+ });
+});
+```
+
+### write logs to a file
+
+#### single file
+
+Sample app that will log all requests in the Apache combined format to the file
+`access.log`.
+
+```js
+var express = require('express');
+var fs = require('fs');
+var morgan = require('morgan');
+var path = require('path');
+
+var app = express();
+
+// create a write stream (in append mode)
+var accessLogStream = fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' });
+
+// setup the logger
+app.use(morgan('combined', { stream: accessLogStream }));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+#### log file rotation
+
+Sample app that will log all requests in the Apache combined format to one log
+file per day in the `log/` directory using the
+[rotating-file-stream module](https://www.npmjs.com/package/rotating-file-stream).
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+var path = require('path');
+var rfs = require('rotating-file-stream'); // version 2.x
+
+var app = express();
+
+// create a rotating write stream
+var accessLogStream = rfs.createStream('access.log', {
+ interval: '1d', // rotate daily
+ path: path.join(__dirname, 'log'),
+});
+
+// setup the logger
+app.use(morgan('combined', { stream: accessLogStream }));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### split / dual logging
+
+The `morgan` middleware can be used as many times as needed, enabling
+combinations like:
+
+- Log entry on request and one on response
+- Log all requests to file, but errors to console
+- ... and more!
+
+Sample app that will log all requests to a file using Apache format, but
+error responses are logged to the console:
+
+```js
+var express = require('express');
+var fs = require('fs');
+var morgan = require('morgan');
+var path = require('path');
+
+var app = express();
+
+// log only 4xx and 5xx responses to console
+app.use(
+ morgan('dev', {
+ skip: function (req, res) {
+ return res.statusCode < 400;
+ },
+ })
+);
+
+// log all requests to access.log
+app.use(
+ morgan('common', {
+ stream: fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' }),
+ })
+);
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### use custom token formats
+
+Sample app that will use custom token formats. This adds an ID to all requests and displays it using the `:id` token.
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+var uuid = require('node-uuid');
+
+morgan.token('id', function getId(req) {
+ return req.id;
+});
+
+var app = express();
+
+app.use(assignId);
+app.use(morgan(':id :method :url :response-time'));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+
+function assignId(req, res, next) {
+ req.id = uuid.v4();
+ next();
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/morgan/master?label=ci
+[ci-url]: https://github.com/expressjs/morgan/actions/workflows/ci.yml
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/morgan/master
+[coveralls-url]: https://coveralls.io/r/expressjs/morgan?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/morgan
+[npm-url]: https://npmjs.org/package/morgan
+[npm-version-image]: https://badgen.net/npm/v/morgan
diff --git a/astro/src/content/resources/ja/middleware/multer.md b/astro/src/content/resources/ja/middleware/multer.md
new file mode 100644
index 0000000000..326786ab3d
--- /dev/null
+++ b/astro/src/content/resources/ja/middleware/multer.md
@@ -0,0 +1,352 @@
+---
+title: Express multer middleware
+module: multer
+---
+
+# Multer [![NPM Version][npm-version-image]][npm-url] [![NPM Downloads][npm-downloads-image]][npm-url] [![Build Status][ci-image]][ci-url] [![Test Coverage][test-image]][test-url] [![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+
+Multer is a node.js middleware for handling `multipart/form-data`, which is primarily used for uploading files. It is written
+on top of [busboy](https://github.com/mscdex/busboy) for maximum efficiency.
+
+**NOTE**: Multer will not process any form which is not multipart (`multipart/form-data`).
+
+## Translations
+
+This README is also available in other languages:
+
+| | |
+| ------------------------------------------------------------------------------ | --------------- |
+| [العربية](https://github.com/expressjs/multer/blob/main/doc/README-ar.md) | Arabic |
+| [简体中文](https://github.com/expressjs/multer/blob/main/doc/README-zh-cn.md) | Chinese |
+| [Français](https://github.com/expressjs/multer/blob/main/doc/README-fr.md) | French |
+| [한국어](https://github.com/expressjs/multer/blob/main/doc/README-ko.md) | Korean |
+| [Português](https://github.com/expressjs/multer/blob/main/doc/README-pt-br.md) | Portuguese (BR) |
+| [Русский язык](https://github.com/expressjs/multer/blob/main/doc/README-ru.md) | Russian |
+| [Español](https://github.com/expressjs/multer/blob/main/doc/README-es.md) | Spanish |
+| [O'zbek tili](https://github.com/expressjs/multer/blob/main/doc/README-uz.md) | Uzbek |
+| [Việt Nam](https://github.com/expressjs/multer/blob/main/doc/README-vi.md) | Vietnamese |
+
+## Installation
+
+```sh
+$ npm install multer
+```
+
+## Usage
+
+Multer adds a `body` object and a `file` or `files` object to the `request` object. The `body` object contains the values of the text fields of the form, the `file` or `files` object contains the files uploaded via the form.
+
+Basic usage example:
+
+Don't forget the `enctype="multipart/form-data"` in your form.
+
+```html
+
+```
+
+```javascript
+const express = require('express');
+const multer = require('multer');
+const upload = multer({ dest: 'uploads/' });
+
+const app = express();
+
+app.post('/profile', upload.single('avatar'), function (req, res, next) {
+ // req.file is the `avatar` file
+ // req.body will hold the text fields, if there were any
+});
+
+app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
+ // req.files is array of `photos` files
+ // req.body will contain the text fields, if there were any
+});
+
+const uploadMiddleware = upload.fields([
+ { name: 'avatar', maxCount: 1 },
+ { name: 'gallery', maxCount: 8 },
+]);
+app.post('/cool-profile', uploadMiddleware, function (req, res, next) {
+ // req.files is an object (String -> Array) where fieldname is the key, and the value is array of files
+ //
+ // e.g.
+ // req.files['avatar'][0] -> File
+ // req.files['gallery'] -> Array
+ //
+ // req.body will contain the text fields, if there were any
+});
+```
+
+In case you need to handle a text-only multipart form, you should use the `.none()` method:
+
+```javascript
+const express = require('express');
+const app = express();
+const multer = require('multer');
+const upload = multer();
+
+app.post('/profile', upload.none(), function (req, res, next) {
+ // req.body contains the text fields
+});
+```
+
+Here's an example on how multer is used in a HTML form. Take special note of the `enctype="multipart/form-data"` and `name="uploaded_file"` fields:
+
+```html
+
+```
+
+Then in your javascript file you would add these lines to access both the file and the body. It is important that you use the `name` field value from the form in your upload function. This tells multer which field on the request it should look for the files in. If these fields aren't the same in the HTML form and on your server, your upload will fail:
+
+```javascript
+const multer = require('multer');
+const upload = multer({ dest: './public/data/uploads/' });
+app.post('/stats', upload.single('uploaded_file'), function (req, res) {
+ // req.file is the name of your file in the form above, here 'uploaded_file'
+ // req.body will hold the text fields, if there were any
+ console.log(req.file, req.body);
+});
+```
+
+## API
+
+### File information
+
+Each file contains the following information:
+
+| Key | Description | Note |
+| -------------- | --------------------------------------------- | --------------- |
+| `fieldname` | Field name specified in the form |
+| `originalname` | Name of the file on the user's computer |
+| `encoding` | Encoding type of the file |
+| `mimetype` | Mime type of the file |
+| `size` | Size of the file in bytes |
+| `destination` | The folder to which the file has been saved | `DiskStorage` |
+| `filename` | The name of the file within the `destination` | `DiskStorage` |
+| `path` | The full path to the uploaded file | `DiskStorage` |
+| `buffer` | A `Buffer` of the entire file | `MemoryStorage` |
+
+### `multer(opts)`
+
+Multer accepts an options object, the most basic of which is the `dest`
+property, which tells Multer where to upload the files. In case you omit the
+options object, the files will be kept in memory and never written to disk.
+
+By default, Multer will rename the files so as to avoid naming conflicts. The
+renaming function can be customized according to your needs.
+
+The following are the options that can be passed to Multer.
+
+| Key | Description |
+| ------------------- | --------------------------------------------------------- |
+| `dest` or `storage` | Where to store the files |
+| `fileFilter` | Function to control which files are accepted |
+| `limits` | Limits of the uploaded data |
+| `preservePath` | Keep the full path of files instead of just the base name |
+
+In an average web app, only `dest` might be required, and configured as shown in
+the following example.
+
+```javascript
+const upload = multer({ dest: 'uploads/' });
+```
+
+If you want more control over your uploads, you'll want to use the `storage`
+option instead of `dest`. Multer ships with storage engines `DiskStorage`
+and `MemoryStorage`; More engines are available from third parties.
+
+#### `.single(fieldname)`
+
+Accept a single file with the name `fieldname`. The single file will be stored
+in `req.file`.
+
+#### `.array(fieldname[, maxCount])`
+
+Accept an array of files, all with the name `fieldname`. Optionally error out if
+more than `maxCount` files are uploaded. The array of files will be stored in
+`req.files`.
+
+#### `.fields(fields)`
+
+Accept a mix of files, specified by `fields`. An object with arrays of files
+will be stored in `req.files`.
+
+`fields` should be an array of objects with `name` and optionally a `maxCount`.
+Example:
+
+```javascript
+[
+ { name: 'avatar', maxCount: 1 },
+ { name: 'gallery', maxCount: 8 },
+];
+```
+
+#### `.none()`
+
+Accept only text fields. If any file upload is made, error with code
+"LIMIT_UNEXPECTED_FILE" will be issued.
+
+#### `.any()`
+
+Accepts all files that comes over the wire. An array of files will be stored in
+`req.files`.
+
+**WARNING:** Make sure that you always handle the files that a user uploads.
+Never add multer as a global middleware since a malicious user could upload
+files to a route that you didn't anticipate. Only use this function on routes
+where you are handling the uploaded files.
+
+### `storage`
+
+#### `DiskStorage`
+
+The disk storage engine gives you full control on storing files to disk.
+
+```javascript
+const storage = multer.diskStorage({
+ destination: function (req, file, cb) {
+ cb(null, '/tmp/my-uploads');
+ },
+ filename: function (req, file, cb) {
+ const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
+ cb(null, file.fieldname + '-' + uniqueSuffix);
+ },
+});
+
+const upload = multer({ storage: storage });
+```
+
+There are two options available, `destination` and `filename`. They are both
+functions that determine where the file should be stored.
+
+`destination` is used to determine within which folder the uploaded files should
+be stored. This can also be given as a `string` (e.g. `'/tmp/uploads'`). If no
+`destination` is given, the operating system's default directory for temporary
+files is used.
+
+**Note:** You are responsible for creating the directory when providing
+`destination` as a function. When passing a string, multer will make sure that
+the directory is created for you.
+
+`filename` is used to determine what the file should be named inside the folder.
+If no `filename` is given, each file will be given a random name that doesn't
+include any file extension.
+
+**Note:** Multer will not append any file extension for you, your function
+should return a filename complete with a file extension.
+
+Each function gets passed both the request (`req`) and some information about
+the file (`file`) to aid with the decision.
+
+Note that `req.body` might not have been fully populated yet. It depends on the
+order that the client transmits fields and files to the server.
+
+For understanding the calling convention used in the callback (needing to pass
+null as the first param), refer to
+[Node.js error handling](https://web.archive.org/web/20220417042018/https://www.joyent.com/node-js/production/design/errors)
+
+#### `MemoryStorage`
+
+The memory storage engine stores the files in memory as `Buffer` objects. It
+doesn't have any options.
+
+```javascript
+const storage = multer.memoryStorage();
+const upload = multer({ storage: storage });
+```
+
+When using memory storage, the file info will contain a field called
+`buffer` that contains the entire file.
+
+**WARNING**: Uploading very large files, or relatively small files in large
+numbers very quickly, can cause your application to run out of memory when
+memory storage is used.
+
+### `limits`
+
+An object specifying the size limits of the following optional properties. Multer passes this object into busboy directly, and the details of the properties can be found on [busboy's page](https://github.com/mscdex/busboy#busboy-methods).
+
+The following integer values are available:
+
+| Key | Description | Default |
+| --------------- | ----------------------------------------------------------------------- | --------- |
+| `fieldNameSize` | Max field name size | 100 bytes |
+| `fieldSize` | Max field value size (in bytes) | 1MB |
+| `fields` | Max number of non-file fields | Infinity |
+| `fileSize` | For multipart forms, the max file size (in bytes) | Infinity |
+| `files` | For multipart forms, the max number of file fields | Infinity |
+| `parts` | For multipart forms, the max number of parts (fields + files) | Infinity |
+| `headerPairs` | For multipart forms, the max number of header key=>value pairs to parse | 2000 |
+
+Specifying the limits can help protect your site against denial of service (DoS) attacks.
+
+### `fileFilter`
+
+Set this to a function to control which files should be uploaded and which
+should be skipped. The function should look like this:
+
+```javascript
+function fileFilter(req, file, cb) {
+ // The function should call `cb` with a boolean
+ // to indicate if the file should be accepted
+
+ // To reject this file pass `false`, like so:
+ cb(null, false);
+
+ // To accept the file pass `true`, like so:
+ cb(null, true);
+
+ // You can always pass an error if something goes wrong:
+ cb(new Error("I don't have a clue!"));
+}
+```
+
+## Error handling
+
+When encountering an error, Multer will delegate the error to Express. You can
+display a nice error page using [the standard express way](http://expressjs.com/guide/error-handling.html).
+
+If you want to catch errors specifically from Multer, you can call the
+middleware function by yourself. Also, if you want to catch only [the Multer errors](https://github.com/expressjs/multer/blob/main/lib/multer-error.js), you can use the `MulterError` class that is attached to the `multer` object itself (e.g. `err instanceof multer.MulterError`).
+
+```javascript
+const multer = require('multer');
+const upload = multer().single('avatar');
+
+app.post('/profile', function (req, res) {
+ upload(req, res, function (err) {
+ if (err instanceof multer.MulterError) {
+ // A Multer error occurred when uploading.
+ } else if (err) {
+ // An unknown error occurred when uploading.
+ }
+
+ // Everything went fine.
+ });
+});
+```
+
+## Custom storage engine
+
+For information on how to build your own storage engine, see [Multer Storage Engine](https://github.com/expressjs/multer/blob/main/StorageEngine.md).
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://github.com/expressjs/multer/actions/workflows/ci.yml/badge.svg
+[ci-url]: https://github.com/expressjs/multer/actions/workflows/ci.yml
+[test-url]: https://coveralls.io/r/expressjs/multer?branch=main
+[test-image]: https://badgen.net/coveralls/c/github/expressjs/multer/main
+[npm-downloads-image]: https://badgen.net/npm/dm/multer
+[npm-url]: https://npmjs.org/package/multer
+[npm-version-image]: https://badgen.net/npm/v/multer
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/multer/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer
diff --git a/astro/src/content/resources/ja/middleware/overview.md b/astro/src/content/resources/ja/middleware/overview.md
new file mode 100755
index 0000000000..46217759e7
--- /dev/null
+++ b/astro/src/content/resources/ja/middleware/overview.md
@@ -0,0 +1,40 @@
+---
+title: Express middleware
+description: Explore a list of Express.js middleware modules maintained by the Express team and the community, including built-in middleware and popular third-party modules.
+module: mw-home
+---
+
+## Express middleware
+
+The Express middleware modules listed here are maintained by the
+[Expressjs team](https://github.com/orgs/expressjs/people).
+
+| Middleware module | Description |
+| ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
+| [body-parser](/en/resources/middleware/body-parser) | Parse HTTP request body. |
+| [compression](/en/resources/middleware/compression) | Compress HTTP responses. |
+| [cookie-parser](/en/resources/middleware/cookie-parser) | Parse cookie header and populate `req.cookies`. See also [cookies](https://github.com/jed/cookies). |
+| [cookie-session](/en/resources/middleware/cookie-session) | Establish cookie-based sessions. |
+| [cors](/en/resources/middleware/cors) | Enable cross-origin resource sharing (CORS) with various options. |
+| [errorhandler](/en/resources/middleware/errorhandler) | Development error-handling/debugging. |
+| [method-override](/en/resources/middleware/method-override) | Override HTTP methods using header. |
+| [morgan](/en/resources/middleware/morgan) | HTTP request logger. |
+| [multer](/en/resources/middleware/multer) | Handle multi-part form data. |
+| [response-time](/en/resources/middleware/response-time) | Record HTTP response time. |
+| [serve-favicon](/en/resources/middleware/serve-favicon) | Serve a favicon. |
+| [serve-index](/en/resources/middleware/serve-index) | Serve directory listing for a given path. |
+| [serve-static](/en/resources/middleware/serve-static) | Serve static files. |
+| [session](/en/resources/middleware/session) | Establish server-based sessions (development only). |
+| [timeout](/en/resources/middleware/timeout) | Set a timeout perioHTTP request processing. |
+| [vhost](/en/resources/middleware/vhost) | Create virtual domains. |
+
+## Additional middleware modules
+
+These are some additional popular middleware modules.
+
+{% include community-caveat.html %}
+
+| Middleware module | Description |
+| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
+| [helmet](https://github.com/helmetjs/helmet) | Helps secure your apps by setting various HTTP headers. |
+| [passport](https://github.com/jaredhanson/passport) | Authentication using "strategies" such as OAuth, OpenID and many others. See [passportjs.org](https://passportjs.org/) for more information. |
diff --git a/astro/src/content/resources/ja/middleware/response-time.md b/astro/src/content/resources/ja/middleware/response-time.md
new file mode 100644
index 0000000000..f911f480f5
--- /dev/null
+++ b/astro/src/content/resources/ja/middleware/response-time.md
@@ -0,0 +1,314 @@
+---
+title: Express response-time middleware
+module: response-time
+---
+
+# compression
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+[![Funding][funding-image]][funding-url]
+
+Node.js compression middleware.
+
+The following compression codings are supported:
+
+- deflate
+- gzip
+- br (brotli)
+
+**Note** Brotli is supported only since Node.js versions v11.7.0 and v10.16.0.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```bash
+$ npm install compression
+```
+
+## API
+
+```js
+var compression = require('compression');
+```
+
+### compression([options])
+
+Returns the compression middleware using the given `options`. The middleware
+will attempt to compress response bodies for all requests that traverse through
+the middleware, based on the given `options`.
+
+This middleware will never compress responses that include a `Cache-Control`
+header with the [`no-transform` directive](https://tools.ietf.org/html/rfc7234#section-5.2.2.4),
+as compressing will transform the body.
+
+#### Options
+
+`compression()` accepts these properties in the options object. In addition to
+those listed below, [zlib](https://nodejs.org/api/zlib.html) options may be
+passed in to the options object or
+[brotli](https://nodejs.org/api/zlib.html#zlib_class_brotlioptions) options.
+
+##### chunkSize
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_CHUNK`, or `16384`.
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### filter
+
+Type: `Function`
+
+A function to decide if the response should be considered for compression.
+This function is called as `filter(req, res)` and is expected to return
+`true` to consider the response for compression, or `false` to not compress
+the response.
+
+The default filter function uses the [compressible](https://www.npmjs.com/package/compressible)
+module to determine if `res.getHeader('Content-Type')` is compressible.
+
+##### level
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_COMPRESSION`, or `-1`
+
+The level of zlib compression to apply to responses. A higher level will result
+in better compression, but will take longer to complete. A lower level will
+result in less compression, but will be much faster.
+
+This is an integer in the range of `0` (no compression) to `9` (maximum
+compression). The special value `-1` can be used to mean the "default
+compression level", which is a default compromise between speed and
+compression (currently equivalent to level 6).
+
+- `-1` Default compression level (also `zlib.constants.Z_DEFAULT_COMPRESSION`).
+- `0` No compression (also `zlib.constants.Z_NO_COMPRESSION`).
+- `1` Fastest compression (also `zlib.constants.Z_BEST_SPEED`).
+- `2`
+- `3`
+- `4`
+- `5`
+- `6` (currently what `zlib.constants.Z_DEFAULT_COMPRESSION` points to).
+- `7`
+- `8`
+- `9` Best compression (also `zlib.constants.Z_BEST_COMPRESSION`).
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### memLevel
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_MEMLEVEL`, or `8`
+
+This specifies how much memory should be allocated for the internal compression
+state and is an integer in the range of `1` (minimum level) and `9` (maximum
+level).
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### brotli
+
+Type: `Object`
+
+This specifies the options for configuring Brotli. See [Node.js documentation](https://nodejs.org/api/zlib.html#class-brotlioptions) for a complete list of available options.
+
+##### strategy
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_STRATEGY`
+
+This is used to tune the compression algorithm. This value only affects the
+compression ratio, not the correctness of the compressed output, even if it
+is not set appropriately.
+
+- `zlib.constants.Z_DEFAULT_STRATEGY` Use for normal data.
+- `zlib.constants.Z_FILTERED` Use for data produced by a filter (or predictor).
+ Filtered data consists mostly of small values with a somewhat random
+ distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect is to force more Huffman coding and less
+ string matching; it is somewhat intermediate between `zlib.constants.Z_DEFAULT_STRATEGY`
+ and `zlib.constants.Z_HUFFMAN_ONLY`.
+- `zlib.constants.Z_FIXED` Use to prevent the use of dynamic Huffman codes, allowing
+ for a simpler decoder for special applications.
+- `zlib.constants.Z_HUFFMAN_ONLY` Use to force Huffman encoding only (no string match).
+- `zlib.constants.Z_RLE` Use to limit match distances to one (run-length encoding).
+ This is designed to be almost as fast as `zlib.constants.Z_HUFFMAN_ONLY`, but give
+ better compression for PNG image data.
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### threshold
+
+Type: `Number` or `String`
+Default: `1kb`
+
+The byte threshold for the response body size before compression is considered
+for the response. This is a number of bytes or any string
+accepted by the [bytes](https://www.npmjs.com/package/bytes) module.
+
+**Note** this is only an advisory setting; if the response size cannot be determined
+at the time the response headers are written, then it is assumed the response is
+_over_ the threshold. To guarantee the response size can be determined, be sure
+set a `Content-Length` response header.
+
+##### windowBits
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_WINDOWBITS`, or `15`
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### enforceEncoding
+
+Type: `String`
+Default: `identity`
+
+This is the default encoding to use when the client does not specify an encoding in the request's [Accept-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) header.
+
+#### .filter
+
+The default `filter` function. This is used to construct a custom filter
+function that is an extension of the default function.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+app.use(compression({ filter: shouldCompress }));
+
+function shouldCompress(req, res) {
+ if (req.headers['x-no-compression']) {
+ // don't compress responses with this request header
+ return false;
+ }
+
+ // fallback to standard filter function
+ return compression.filter(req, res);
+}
+```
+
+### res.flush
+
+This module adds a `res.flush()` method to force the partially-compressed
+response to be flushed to the client.
+
+## Examples
+
+### express
+
+When using this module with express, simply `app.use` the module as
+high as you like. Requests that pass through the middleware will be compressed.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress all responses
+app.use(compression());
+
+// add all routes
+```
+
+### Node.js HTTP server
+
+```js
+var compression = require('compression')({ threshold: 0 });
+var http = require('http');
+
+function createServer(fn) {
+ return http.createServer(function (req, res) {
+ compression(req, res, function (err) {
+ if (err) {
+ res.statusCode = err.status || 500;
+ res.end(err.message);
+ return;
+ }
+
+ fn(req, res);
+ });
+ });
+}
+
+var server = createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello world!');
+});
+
+server.listen(3000, () => {
+ console.log('> Listening at http://localhost:3000');
+});
+```
+
+### Server-Sent Events
+
+Because of the nature of compression this module does not work out of the box
+with server-sent events. To compress content, a window of the output needs to
+be buffered up in order to get good compression. Typically when using server-sent
+events, there are certain block of data that need to reach the client.
+
+You can achieve this by calling `res.flush()` when you need the data written to
+actually make it to the client.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress responses
+app.use(compression());
+
+// server-sent event stream
+app.get('/events', function (req, res) {
+ res.setHeader('Content-Type', 'text/event-stream');
+ res.setHeader('Cache-Control', 'no-cache');
+
+ // send a ping approx every 2 seconds
+ var timer = setInterval(function () {
+ res.write('data: ping\n\n');
+
+ // !!! this is the important part
+ res.flush();
+ }, 2000);
+
+ res.on('close', function () {
+ clearInterval(timer);
+ });
+});
+```
+
+## Contributing
+
+The Express.js project welcomes all constructive contributions. Contributions take many forms,
+from code for bug fixes and enhancements, to additions and fixes to documentation, additional
+tests, triaging incoming pull requests and issues, and more!
+
+See the [Contributing Guide](https://github.com/expressjs/express/blob/master/Contributing.md) for more technical details on contributing.
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://badgen.net/npm/v/compression
+[npm-url]: https://npmjs.org/package/compression
+[downloads-image]: https://badgen.net/npm/dm/compression
+[downloads-url]: https://npmcharts.com/compare/compression?minimal=true
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/compression/master?label=CI
+[github-actions-ci-url]: https://github.com/expressjs/compression/actions?query=workflow%3Aci
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/compression/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/compression
+[funding-url]: https://opencollective.com/express
+[funding-image]: https://badgen.net/badge/icon/sponsor/pink?icon=github&label=Open%20Collective
diff --git a/astro/src/content/resources/ja/middleware/serve-favicon.md b/astro/src/content/resources/ja/middleware/serve-favicon.md
new file mode 100644
index 0000000000..7a77865c6b
--- /dev/null
+++ b/astro/src/content/resources/ja/middleware/serve-favicon.md
@@ -0,0 +1,156 @@
+---
+title: Express serve-favicon middleware
+module: serve-favicon
+---
+
+# serve-index
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Linux Build Status][ci-image]][ci-url]
+[![Windows Build][appveyor-image]][appveyor-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+Serves pages that contain directory listings for a given path.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-index
+```
+
+## API
+
+```js
+var serveIndex = require('serve-index');
+```
+
+### serveIndex(path, options)
+
+Returns middlware that serves an index of the directory in the given `path`.
+
+The `path` is based off the `req.url` value, so a `req.url` of `'/some/dir`
+with a `path` of `'public'` will look at `'public/some/dir'`. If you are using
+something like `express`, you can change the URL "base" with `app.use` (see
+the express example).
+
+#### Options
+
+Serve index accepts these properties in the options object.
+
+##### filter
+
+Apply this filter function to files. Defaults to `false`. The `filter` function
+is called for each file, with the signature `filter(filename, index, files, dir)`
+where `filename` is the name of the file, `index` is the array index, `files` is
+the array of files and `dir` is the absolute path the file is located (and thus,
+the directory the listing is for).
+
+##### hidden
+
+Display hidden (dot) files. Defaults to `false`.
+
+##### icons
+
+Display icons. Defaults to `false`.
+
+##### stylesheet
+
+Optional path to a CSS stylesheet. Defaults to a built-in stylesheet.
+
+##### template
+
+Optional path to an HTML template or a function that will render a HTML
+string. Defaults to a built-in template.
+
+When given a string, the string is used as a file path to load and then the
+following tokens are replaced in templates:
+
+- `{directory}` with the name of the directory.
+- `{files}` with the HTML of an unordered list of file links.
+- `{linked-path}` with the HTML of a link to the directory.
+- `{style}` with the specified stylesheet and embedded images.
+
+When given as a function, the function is called as `template(locals, callback)`
+and it needs to invoke `callback(error, htmlString)`. The following are the
+provided locals:
+
+- `directory` is the directory being displayed (where `/` is the root).
+- `displayIcons` is a Boolean for if icons should be rendered or not.
+- `fileList` is a sorted array of files in the directory. The array contains
+ objects with the following properties:
+ - `name` is the relative name for the file.
+ - `stat` is a `fs.Stats` object for the file.
+- `path` is the full filesystem path to `directory`.
+- `style` is the default stylesheet or the contents of the `stylesheet` option.
+- `viewName` is the view name provided by the `view` option.
+
+##### view
+
+Display mode. `tiles` and `details` are available. Defaults to `tiles`.
+
+## Examples
+
+### Serve directory indexes with vanilla node.js http server
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var serveIndex = require('serve-index');
+var serveStatic = require('serve-static');
+
+// Serve directory indexes for public/ftp folder (with icons)
+var index = serveIndex('public/ftp', { icons: true });
+
+// Serve up public/ftp folder files
+var serve = serveStatic('public/ftp');
+
+// Create server
+var server = http.createServer(function onRequest(req, res) {
+ var done = finalhandler(req, res);
+ serve(req, res, function onNext(err) {
+ if (err) return done(err);
+ index(req, res, done);
+ });
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve directory indexes with express
+
+```js
+var express = require('express');
+var serveIndex = require('serve-index');
+
+var app = express();
+
+// Serve URLs like /ftp/thing as public/ftp/thing
+// The express.static serves the file contents
+// The serveIndex is this module serving the directory
+app.use('/ftp', express.static('public/ftp'), serveIndex('public/ftp', { icons: true }));
+
+// Listen
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE). The [Silk](http://www.famfamfam.com/lab/icons/silk/) icons
+are created by/copyright of [FAMFAMFAM](http://www.famfamfam.com/).
+
+[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/serve-index/master.svg?label=windows
+[appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index
+[ci-image]: https://badgen.net/github/checks/expressjs/serve-index/master?label=ci
+[ci-url]: https://github.com/expressjs/serve-index/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/serve-index/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-index?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/serve-index.svg
+[downloads-url]: https://npmjs.org/package/serve-index
+[npm-image]: https://img.shields.io/npm/v/serve-index.svg
+[npm-url]: https://npmjs.org/package/serve-index
diff --git a/astro/src/content/resources/ja/middleware/serve-index.md b/astro/src/content/resources/ja/middleware/serve-index.md
new file mode 100644
index 0000000000..da03cf94b2
--- /dev/null
+++ b/astro/src/content/resources/ja/middleware/serve-index.md
@@ -0,0 +1,156 @@
+---
+title: Express serve-index middleware
+module: serve-index
+---
+
+# serve-index
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Linux Build Status][ci-image]][ci-url]
+[![Windows Build][appveyor-image]][appveyor-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+Serves pages that contain directory listings for a given path.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-index
+```
+
+## API
+
+```js
+var serveIndex = require('serve-index');
+```
+
+### serveIndex(path, options)
+
+Returns middlware that serves an index of the directory in the given `path`.
+
+The `path` is based off the `req.url` value, so a `req.url` of `'/some/dir`
+with a `path` of `'public'` will look at `'public/some/dir'`. If you are using
+something like `express`, you can change the URL "base" with `app.use` (see
+the express example).
+
+#### Options
+
+Serve index accepts these properties in the options object.
+
+##### filter
+
+Apply this filter function to files. Defaults to `false`. The `filter` function
+is called for each file, with the signature `filter(filename, index, files, dir)`
+where `filename` is the name of the file, `index` is the array index, `files` is
+the array of files and `dir` is the absolute path the file is located (and thus,
+the directory the listing is for).
+
+##### hidden
+
+Display hidden (dot) files. Defaults to `false`.
+
+##### icons
+
+Display icons. Defaults to `false`.
+
+##### stylesheet
+
+Optional path to a CSS stylesheet. Defaults to a built-in stylesheet.
+
+##### template
+
+Optional path to an HTML template or a function that will render a HTML
+string. Defaults to a built-in template.
+
+When given a string, the string is used as a file path to load and then the
+following tokens are replaced in templates:
+
+- `{directory}` with the name of the directory.
+- `{files}` with the HTML of an unordered list of file links.
+- `{linked-path}` with the HTML of a link to the directory.
+- `{style}` with the specified stylesheet and embedded images.
+
+When given as a function, the function is called as `template(locals, callback)`
+and it needs to invoke `callback(error, htmlString)`. The following are the
+provided locals:
+
+- `directory` is the directory being displayed (where `/` is the root).
+- `displayIcons` is a Boolean for if icons should be rendered or not.
+- `fileList` is a sorted array of files in the directory. The array contains
+ objects with the following properties:
+ - `name` is the relative name for the file.
+ - `stat` is a `fs.Stats` object for the file.
+- `path` is the full filesystem path to `directory`.
+- `style` is the default stylesheet or the contents of the `stylesheet` option.
+- `viewName` is the view name provided by the `view` option.
+
+##### view
+
+Display mode. `tiles` and `details` are available. Defaults to `tiles`.
+
+## Examples
+
+### Serve directory indexes with vanilla node.js http server
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var serveIndex = require('serve-index');
+var serveStatic = require('serve-static');
+
+// Serve directory indexes for public/ftp folder (with icons)
+var index = serveIndex('public/ftp', { icons: true });
+
+// Serve up public/ftp folder files
+var serve = serveStatic('public/ftp');
+
+// Create server
+var server = http.createServer(function onRequest(req, res) {
+ var done = finalhandler(req, res);
+ serve(req, res, function onNext(err) {
+ if (err) return done(err);
+ index(req, res, done);
+ });
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve directory indexes with express
+
+```js
+var express = require('express');
+var serveIndex = require('serve-index');
+
+var app = express();
+
+// Serve URLs like /ftp/thing as public/ftp/thing
+// The express.static serves the file contents
+// The serveIndex is this module serving the directory
+app.use('/ftp', express.static('public/ftp'), serveIndex('public/ftp', { icons: true }));
+
+// Listen
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE). The [Silk](http://www.famfamfam.com/lab/icons/silk/) icons
+are created by/copyright of [FAMFAMFAM](http://www.famfamfam.com/).
+
+[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/serve-index/master.svg?label=windows
+[appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index
+[ci-image]: https://badgen.net/github/checks/expressjs/serve-index/master?label=ci
+[ci-url]: https://github.com/expressjs/serve-index/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/serve-index/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-index?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/serve-index.svg
+[downloads-url]: https://npmjs.org/package/serve-index
+[npm-image]: https://img.shields.io/npm/v/serve-index.svg
+[npm-url]: https://npmjs.org/package/serve-index
diff --git a/astro/src/content/resources/ja/middleware/serve-static.md b/astro/src/content/resources/ja/middleware/serve-static.md
new file mode 100644
index 0000000000..b048165d7b
--- /dev/null
+++ b/astro/src/content/resources/ja/middleware/serve-static.md
@@ -0,0 +1,260 @@
+---
+title: Express serve-static middleware
+module: serve-static
+---
+
+# serve-static
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![CI][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-static
+```
+
+## API
+
+```js
+const serveStatic = require('serve-static');
+```
+
+### serveStatic(root, options)
+
+Create a new middleware function to serve files from within a given root
+directory. The file to serve will be determined by combining `req.url`
+with the provided root directory. When a file is not found, instead of
+sending a 404 response, this module will instead call `next()` to move on
+to the next middleware, allowing for stacking and fall-backs.
+
+#### Options
+
+##### acceptRanges
+
+Enable or disable accepting ranged requests, defaults to true.
+Disabling this will not send `Accept-Ranges` and ignore the contents
+of the `Range` request header.
+
+##### cacheControl
+
+Enable or disable setting `Cache-Control` response header, defaults to
+true. Disabling this will ignore the `immutable` and `maxAge` options.
+
+##### dotfiles
+
+Set how "dotfiles" are treated when encountered. A dotfile is a file
+or directory that begins with a dot ("."). Note this check is done on
+the path itself without checking if the path actually exists on the
+disk. If `root` is specified, only the dotfiles above the root are
+checked (i.e. the root itself can be within a dotfile when set
+to "deny").
+
+- `'allow'` No special treatment for dotfiles.
+- `'deny'` Deny a request for a dotfile and 403/`next()`.
+- `'ignore'` Pretend like the dotfile does not exist and 404/`next()`.
+
+The default value is `'ignore'`.
+
+##### etag
+
+Enable or disable etag generation, defaults to true.
+
+##### extensions
+
+Set file extension fallbacks. When set, if a file is not found, the given
+extensions will be added to the file name and search for. The first that
+exists will be served. Example: `['html', 'htm']`.
+
+The default value is `false`.
+
+##### fallthrough
+
+Set the middleware to have client errors fall-through as just unhandled
+requests, otherwise forward a client error. The difference is that client
+errors like a bad request or a request to a non-existent file will cause
+this middleware to simply `next()` to your next middleware when this value
+is `true`. When this value is `false`, these errors (even 404s), will invoke
+`next(err)`.
+
+Typically `true` is desired such that multiple physical directories can be
+mapped to the same web address or for routes to fill in non-existent files.
+
+The value `false` can be used if this middleware is mounted at a path that
+is designed to be strictly a single file system directory, which allows for
+short-circuiting 404s for less overhead. This middleware will also reply to
+all methods.
+
+The default value is `true`.
+
+##### immutable
+
+Enable or disable the `immutable` directive in the `Cache-Control` response
+header, defaults to `false`. If set to `true`, the `maxAge` option should
+also be specified to enable caching. The `immutable` directive will prevent
+supported clients from making conditional requests during the life of the
+`maxAge` option to check if the file has changed.
+
+##### index
+
+By default this module will send "index.html" files in response to a request
+on a directory. To disable this set `false` or to supply a new index pass a
+string or an array in preferred order.
+
+##### lastModified
+
+Enable or disable `Last-Modified` header, defaults to true. Uses the file
+system's last modified value.
+
+##### maxAge
+
+Provide a max-age in milliseconds for http caching, defaults to 0. This
+can also be a string accepted by the [ms](https://www.npmjs.org/package/ms#readme)
+module.
+
+##### redirect
+
+Redirect to trailing "/" when the pathname is a dir. Defaults to `true`.
+
+##### setHeaders
+
+Function to set custom headers on response. Alterations to the headers need to
+occur synchronously. The function is called as `fn(res, path, stat)`, where
+the arguments are:
+
+- `res` the response object
+- `path` the file path that is being sent
+- `stat` the stat object of the file that is being sent
+
+## Examples
+
+### Serve files with vanilla node.js http server
+
+```js
+const finalhandler = require('finalhandler');
+const http = require('http');
+const serveStatic = require('serve-static');
+
+// Serve up public/ftp folder
+const serve = serveStatic('public/ftp', { index: ['index.html', 'index.htm'] });
+
+// Create server
+const server = http.createServer((req, res) => {
+ serve(req, res, finalhandler(req, res));
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve all files as downloads
+
+```js
+const contentDisposition = require('content-disposition');
+const finalhandler = require('finalhandler');
+const http = require('http');
+const serveStatic = require('serve-static');
+
+// Serve up public/ftp folder
+const serve = serveStatic('public/ftp', {
+ index: false,
+ setHeaders: setHeaders,
+});
+
+// Set header to force download
+function setHeaders(res, path) {
+ res.setHeader('Content-Disposition', contentDisposition(path));
+}
+
+// Create server
+const server = http.createServer((req, res) => {
+ serve(req, res, finalhandler(req, res));
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serving using express
+
+#### Simple
+
+This is a simple example of using Express.
+
+```js
+const express = require('express');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(serveStatic('public/ftp', { index: ['default.html', 'default.htm'] }));
+app.listen(3000);
+```
+
+#### Multiple roots
+
+This example shows a simple way to search through multiple directories.
+Files are searched for in `public-optimized/` first, then `public/` second
+as a fallback.
+
+```js
+const express = require('express');
+const path = require('path');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(serveStatic(path.join(__dirname, 'public-optimized')));
+app.use(serveStatic(path.join(__dirname, 'public')));
+app.listen(3000);
+```
+
+#### Different settings for paths
+
+This example shows how to set a different max age depending on the served
+file. In this example, HTML files are not cached, while everything else
+is for 1 day.
+
+```js
+const express = require('express');
+const path = require('path');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(
+ serveStatic(path.join(__dirname, 'public'), {
+ maxAge: '1d',
+ setHeaders: setCustomCacheControl,
+ })
+);
+
+app.listen(3000);
+
+function setCustomCacheControl(res, file) {
+ if (path.extname(file) === '.html') {
+ // Custom Cache-Control for HTML files
+ res.setHeader('Cache-Control', 'public, max-age=0');
+ }
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/serve-static/master
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-static?branch=master
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/serve-static/master?label=linux
+[github-actions-ci-url]: https://github.com/expressjs/serve-static/actions/workflows/ci.yml
+[node-image]: https://badgen.net/npm/node/serve-static
+[node-url]: https://nodejs.org/en/download/
+[npm-downloads-image]: https://badgen.net/npm/dm/serve-static
+[npm-url]: https://npmjs.org/package/serve-static
+[npm-version-image]: https://badgen.net/npm/v/serve-static
diff --git a/astro/src/content/resources/ja/middleware/session.md b/astro/src/content/resources/ja/middleware/session.md
new file mode 100644
index 0000000000..90f3837a42
--- /dev/null
+++ b/astro/src/content/resources/ja/middleware/session.md
@@ -0,0 +1,1046 @@
+---
+title: Express session middleware
+module: session
+---
+
+# express-session
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][node-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install express-session
+```
+
+## API
+
+```js
+var session = require('express-session');
+```
+
+### session(options)
+
+Create a session middleware with the given `options`.
+
+**Note** Session data is _not_ saved in the cookie itself, just the session ID.
+Session data is stored server-side.
+
+**Note** Since version 1.5.0, the [`cookie-parser` middleware](https://www.npmjs.com/package/cookie-parser)
+no longer needs to be used for this module to work. This module now directly reads
+and writes cookies on `req`/`res`. Using `cookie-parser` may result in issues
+if the `secret` is not the same between this module and `cookie-parser`.
+
+**Warning** The default server-side session storage, `MemoryStore`, is _purposely_
+not designed for a production environment. It will leak memory under most
+conditions, does not scale past a single process, and is meant for debugging and
+developing.
+
+For a list of stores, see [compatible session stores](#compatible-session-stores).
+
+#### Options
+
+`express-session` accepts these properties in the options object.
+
+##### cookie
+
+Settings object for the session ID cookie. The default value is
+`{ path: '/', httpOnly: true, secure: false, maxAge: null }`.
+
+The following are options that can be set in this object.
+
+##### cookie.domain
+
+Specifies the value for the `Domain` `Set-Cookie` attribute. By default, no domain
+is set, and most clients will consider the cookie to apply to only the current
+domain.
+
+##### cookie.expires
+
+Specifies the `Date` object to be the value for the `Expires` `Set-Cookie` attribute.
+By default, no expiration is set, and most clients will consider this a
+"non-persistent cookie" and will delete it on a condition like exiting a web browser
+application.
+
+**Note** If both `expires` and `maxAge` are set in the options, then the last one
+defined in the object is what is used.
+
+**Note** The `expires` option should not be set directly; instead only use the `maxAge`
+option.
+
+##### cookie.httpOnly
+
+Specifies the `boolean` value for the `HttpOnly` `Set-Cookie` attribute. When truthy,
+the `HttpOnly` attribute is set, otherwise it is not. By default, the `HttpOnly`
+attribute is set.
+
+**Note** be careful when setting this to `true`, as compliant clients will not allow
+client-side JavaScript to see the cookie in `document.cookie`.
+
+##### cookie.maxAge
+
+Specifies the `number` (in milliseconds) to use when calculating the `Expires`
+`Set-Cookie` attribute. This is done by taking the current server time and adding
+`maxAge` milliseconds to the value to calculate an `Expires` datetime. By default,
+no maximum age is set.
+
+**Note** If both `expires` and `maxAge` are set in the options, then the last one
+defined in the object is what is used.
+
+##### cookie.partitioned
+
+Specifies the `boolean` value for the [`Partitioned` `Set-Cookie`](rfc-cutler-httpbis-partitioned-cookies)
+attribute. When truthy, the `Partitioned` attribute is set, otherwise it is not.
+By default, the `Partitioned` attribute is not set.
+
+**Note** This is an attribute that has not yet been fully standardized, and may
+change in the future. This also means many clients may ignore this attribute until
+they understand it.
+
+More information about can be found in [the proposal](https://github.com/privacycg/CHIPS).
+
+##### cookie.path
+
+Specifies the value for the `Path` `Set-Cookie`. By default, this is set to `'/'`, which
+is the root path of the domain.
+
+##### cookie.priority
+
+Specifies the `string` to be the value for the [`Priority` `Set-Cookie` attribute][rfc-west-cookie-priority-00-4.1].
+
+- `'low'` will set the `Priority` attribute to `Low`.
+- `'medium'` will set the `Priority` attribute to `Medium`, the default priority when not set.
+- `'high'` will set the `Priority` attribute to `High`.
+
+More information about the different priority levels can be found in
+[the specification][rfc-west-cookie-priority-00-4.1].
+
+**Note** This is an attribute that has not yet been fully standardized, and may change in the future.
+This also means many clients may ignore this attribute until they understand it.
+
+##### cookie.sameSite
+
+Specifies the `boolean` or `string` to be the value for the `SameSite` `Set-Cookie` attribute.
+By default, this is `false`.
+
+- `true` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
+- `false` will not set the `SameSite` attribute.
+- `'lax'` will set the `SameSite` attribute to `Lax` for lax same site enforcement.
+- `'none'` will set the `SameSite` attribute to `None` for an explicit cross-site cookie.
+- `'strict'` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
+
+More information about the different enforcement levels can be found in
+[the specification][rfc-6265bis-03-4.1.2.7].
+
+**Note** This is an attribute that has not yet been fully standardized, and may change in
+the future. This also means many clients may ignore this attribute until they understand it.
+
+**Note** There is a [draft spec](https://tools.ietf.org/html/draft-west-cookie-incrementalism-01)
+that requires that the `Secure` attribute be set to `true` when the `SameSite` attribute has been
+set to `'none'`. Some web browsers or other clients may be adopting this specification.
+
+##### cookie.secure
+
+Specifies the `boolean` value for the `Secure` `Set-Cookie` attribute. When truthy,
+the `Secure` attribute is set, otherwise it is not. By default, the `Secure`
+attribute is not set.
+
+**Note** be careful when setting this to `true`, as compliant clients will not send
+the cookie back to the server in the future if the browser does not have an HTTPS
+connection.
+
+Please note that `secure: true` is a **recommended** option. However, it requires
+an https-enabled website, i.e., HTTPS is necessary for secure cookies. If `secure`
+is set, and you access your site over HTTP, the cookie will not be set. If you
+have your node.js behind a proxy and are using `secure: true`, you need to set
+"trust proxy" in express:
+
+```js
+var app = express();
+app.set('trust proxy', 1); // trust first proxy
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ cookie: { secure: true },
+ })
+);
+```
+
+For using secure cookies in production, but allowing for testing in development,
+the following is an example of enabling this setup based on `NODE_ENV` in express:
+
+```js
+var app = express();
+var sess = {
+ secret: 'keyboard cat',
+ cookie: {},
+};
+
+if (app.get('env') === 'production') {
+ app.set('trust proxy', 1); // trust first proxy
+ sess.cookie.secure = true; // serve secure cookies
+}
+
+app.use(session(sess));
+```
+
+The `cookie.secure` option can also be set to the special value `'auto'` to have
+this setting automatically match the determined security of the connection. Be
+careful when using this setting if the site is available both as HTTP and HTTPS,
+as once the cookie is set on HTTPS, it will no longer be visible over HTTP. This
+is useful when the Express `"trust proxy"` setting is properly setup to simplify
+development vs production configuration.
+
+##### genid
+
+Function to call to generate a new session ID. Provide a function that returns
+a string that will be used as a session ID. The function is given `req` as the
+first argument if you want to use some value attached to `req` when generating
+the ID.
+
+The default value is a function which uses the `uid-safe` library to generate IDs.
+
+**NOTE** be careful to generate unique IDs so your sessions do not conflict.
+
+```js
+app.use(
+ session({
+ genid: function (req) {
+ return genuuid(); // use UUIDs for session IDs
+ },
+ secret: 'keyboard cat',
+ })
+);
+```
+
+##### name
+
+The name of the session ID cookie to set in the response (and read from in the
+request).
+
+The default value is `'connect.sid'`.
+
+**Note** if you have multiple apps running on the same hostname (this is just
+the name, i.e. `localhost` or `127.0.0.1`; different schemes and ports do not
+name a different hostname), then you need to separate the session cookies from
+each other. The simplest method is to simply set different `name`s per app.
+
+##### proxy
+
+Trust the reverse proxy when setting secure cookies (via the "X-Forwarded-Proto"
+header).
+
+The default value is `undefined`.
+
+- `true` The "X-Forwarded-Proto" header will be used.
+- `false` All headers are ignored and the connection is considered secure only
+ if there is a direct TLS/SSL connection.
+- `undefined` Uses the "trust proxy" setting from express
+
+##### resave
+
+Forces the session to be saved back to the session store, even if the session
+was never modified during the request. Depending on your store this may be
+necessary, but it can also create race conditions where a client makes two
+parallel requests to your server and changes made to the session in one
+request may get overwritten when the other request ends, even if it made no
+changes (this behavior also depends on what store you're using).
+
+The default value is `true`, but using the default has been deprecated,
+as the default will change in the future. Please research into this setting
+and choose what is appropriate to your use-case. Typically, you'll want
+`false`.
+
+How do I know if this is necessary for my store? The best way to know is to
+check with your store if it implements the `touch` method. If it does, then
+you can safely set `resave: false`. If it does not implement the `touch`
+method and your store sets an expiration date on stored sessions, then you
+likely need `resave: true`.
+
+##### rolling
+
+Force the session identifier cookie to be set on every response. The expiration
+is reset to the original [`maxAge`](#cookiemaxage), resetting the expiration
+countdown.
+
+The default value is `false`.
+
+With this enabled, the session identifier cookie will expire in
+[`maxAge`](#cookiemaxage) since the last response was sent instead of in
+[`maxAge`](#cookiemaxage) since the session was last modified by the server.
+
+This is typically used in conjunction with short, non-session-length
+[`maxAge`](#cookiemaxage) values to provide a quick timeout of the session data
+with reduced potential of it occurring during on going server interactions.
+
+**Note** When this option is set to `true` but the `saveUninitialized` option is
+set to `false`, the cookie will not be set on a response with an uninitialized
+session. This option only modifies the behavior when an existing session was
+loaded for the request.
+
+##### saveUninitialized
+
+Forces a session that is "uninitialized" to be saved to the store. A session is
+uninitialized when it is new but not modified. Choosing `false` is useful for
+implementing login sessions, reducing server storage usage, or complying with
+laws that require permission before setting a cookie. Choosing `false` will also
+help with race conditions where a client makes multiple parallel requests
+without a session.
+
+The default value is `true`, but using the default has been deprecated, as the
+default will change in the future. Please research into this setting and
+choose what is appropriate to your use-case.
+
+**Note** if you are using Session in conjunction with PassportJS, Passport
+will add an empty Passport object to the session for use after a user is
+authenticated, which will be treated as a modification to the session, causing
+it to be saved. _This has been fixed in PassportJS 0.3.0_
+
+##### secret
+
+**Required option**
+
+This is the secret used to sign the session ID cookie. The secret can be any type
+of value that is supported by Node.js `crypto.createHmac` (like a string or a
+`Buffer`). This can be either a single secret, or an array of multiple secrets. If
+an array of secrets is provided, only the first element will be used to sign the
+session ID cookie, while all the elements will be considered when verifying the
+signature in requests. The secret itself should be not easily parsed by a human and
+would best be a random set of characters. A best practice may include:
+
+- The use of environment variables to store the secret, ensuring the secret itself
+ does not exist in your repository.
+- Periodic updates of the secret, while ensuring the previous secret is in the
+ array.
+
+Using a secret that cannot be guessed will reduce the ability to hijack a session to
+only guessing the session ID (as determined by the `genid` option).
+
+Changing the secret value will invalidate all existing sessions. In order to rotate
+the secret without invalidating sessions, provide an array of secrets, with the new
+secret as first element of the array, and including previous secrets as the later
+elements.
+
+**Note** HMAC-256 is used to sign the session ID. For this reason, the secret should
+contain at least 32 bytes of entropy.
+
+##### store
+
+The session store instance, defaults to a new `MemoryStore` instance.
+
+##### unset
+
+Control the result of unsetting `req.session` (through `delete`, setting to `null`,
+etc.).
+
+The default value is `'keep'`.
+
+- `'destroy'` The session will be destroyed (deleted) when the response ends.
+- `'keep'` The session in the store will be kept, but modifications made during
+ the request are ignored and not saved.
+
+### req.session
+
+To store or access session data, simply use the request property `req.session`,
+which is (generally) serialized as JSON by the store, so nested objects
+are typically fine. For example below is a user-specific view counter:
+
+```js
+// Use the session middleware
+app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 } }));
+
+// Access the session as req.session
+app.get('/', function (req, res, next) {
+ if (req.session.views) {
+ req.session.views++;
+ res.setHeader('Content-Type', 'text/html');
+ res.write('views: ' + req.session.views + '
');
+ res.write('expires in: ' + req.session.cookie.maxAge / 1000 + 's
');
+ res.end();
+ } else {
+ req.session.views = 1;
+ res.end('welcome to the session demo. refresh!');
+ }
+});
+```
+
+#### Session.regenerate(callback)
+
+To regenerate the session simply invoke the method. Once complete,
+a new SID and `Session` instance will be initialized at `req.session`
+and the `callback` will be invoked.
+
+```js
+req.session.regenerate(function (err) {
+ // will have a new session here
+});
+```
+
+#### Session.destroy(callback)
+
+Destroys the session and will unset the `req.session` property.
+Once complete, the `callback` will be invoked.
+
+```js
+req.session.destroy(function (err) {
+ // cannot access session here
+});
+```
+
+#### Session.reload(callback)
+
+Reloads the session data from the store and re-populates the
+`req.session` object. Once complete, the `callback` will be invoked.
+
+```js
+req.session.reload(function (err) {
+ // session updated
+});
+```
+
+#### Session.save(callback)
+
+Save the session back to the store, replacing the contents on the store with the
+contents in memory (though a store may do something else--consult the store's
+documentation for exact behavior).
+
+This method is automatically called at the end of the HTTP response if the
+session data has been altered (though this behavior can be altered with various
+options in the middleware constructor). Because of this, typically this method
+does not need to be called.
+
+There are some cases where it is useful to call this method, for example,
+redirects, long-lived requests or in WebSockets.
+
+```js
+req.session.save(function (err) {
+ // session saved
+});
+```
+
+#### Session.touch()
+
+Updates the `.maxAge` property. Typically this is
+not necessary to call, as the session middleware does this for you.
+
+### req.session.id
+
+Each session has a unique ID associated with it. This property is an
+alias of [`req.sessionID`](#reqsessionid-1) and cannot be modified.
+It has been added to make the session ID accessible from the `session`
+object.
+
+### req.session.cookie
+
+Each session has a unique cookie object accompany it. This allows
+you to alter the session cookie per visitor. For example we can
+set `req.session.cookie.expires` to `false` to enable the cookie
+to remain for only the duration of the user-agent.
+
+#### Cookie.maxAge
+
+Alternatively `req.session.cookie.maxAge` will return the time
+remaining in milliseconds, which we may also re-assign a new value
+to adjust the `.expires` property appropriately. The following
+are essentially equivalent
+
+```js
+var hour = 3600000;
+req.session.cookie.expires = new Date(Date.now() + hour);
+req.session.cookie.maxAge = hour;
+```
+
+For example when `maxAge` is set to `60000` (one minute), and 30 seconds
+has elapsed it will return `30000` until the current request has completed,
+at which time `req.session.touch()` is called to reset
+`req.session.cookie.maxAge` to its original value.
+
+```js
+req.session.cookie.maxAge; // => 30000
+```
+
+#### Cookie.originalMaxAge
+
+The `req.session.cookie.originalMaxAge` property returns the original
+`maxAge` (time-to-live), in milliseconds, of the session cookie.
+
+### req.sessionID
+
+To get the ID of the loaded session, access the request property
+`req.sessionID`. This is simply a read-only value set when a session
+is loaded/created.
+
+## Session Store Implementation
+
+Every session store _must_ be an `EventEmitter` and implement specific
+methods. The following methods are the list of **required**, **recommended**,
+and **optional**.
+
+- Required methods are ones that this module will always call on the store.
+- Recommended methods are ones that this module will call on the store if
+ available.
+- Optional methods are ones this module does not call at all, but helps
+ present uniform stores to users.
+
+For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo.
+
+### store.all(callback)
+
+**Optional**
+
+This optional method is used to get all sessions in the store as an array. The
+`callback` should be called as `callback(error, sessions)`.
+
+### store.destroy(sid, callback)
+
+**Required**
+
+This required method is used to destroy/delete a session from the store given
+a session ID (`sid`). The `callback` should be called as `callback(error)` once
+the session is destroyed.
+
+### store.clear(callback)
+
+**Optional**
+
+This optional method is used to delete all sessions from the store. The
+`callback` should be called as `callback(error)` once the store is cleared.
+
+### store.length(callback)
+
+**Optional**
+
+This optional method is used to get the count of all sessions in the store.
+The `callback` should be called as `callback(error, len)`.
+
+### store.get(sid, callback)
+
+**Required**
+
+This required method is used to get a session from the store given a session
+ID (`sid`). The `callback` should be called as `callback(error, session)`.
+
+The `session` argument should be a session if found, otherwise `null` or
+`undefined` if the session was not found (and there was no error). A special
+case is made when `error.code === 'ENOENT'` to act like `callback(null, null)`.
+
+### store.set(sid, session, callback)
+
+**Required**
+
+This required method is used to upsert a session into the store given a
+session ID (`sid`) and session (`session`) object. The callback should be
+called as `callback(error)` once the session has been set in the store.
+
+### store.touch(sid, session, callback)
+
+**Recommended**
+
+This recommended method is used to "touch" a given session given a
+session ID (`sid`) and session (`session`) object. The `callback` should be
+called as `callback(error)` once the session has been touched.
+
+This is primarily used when the store will automatically delete idle sessions
+and this method is used to signal to the store the given session is active,
+potentially resetting the idle timer.
+
+## Compatible Session Stores
+
+The following modules implement a session store that is compatible with this
+module. Please make a PR to add additional modules :)
+
+[![★][aerospike-session-store-image] aerospike-session-store][aerospike-session-store-url] A session store using [Aerospike](http://www.aerospike.com/).
+
+[aerospike-session-store-url]: https://www.npmjs.com/package/aerospike-session-store
+[aerospike-session-store-image]: https://badgen.net/github/stars/aerospike/aerospike-session-store-expressjs?label=%E2%98%85
+
+[![★][better-sqlite3-session-store-image] better-sqlite3-session-store][better-sqlite3-session-store-url] A session store based on [better-sqlite3](https://github.com/JoshuaWise/better-sqlite3).
+
+[better-sqlite3-session-store-url]: https://www.npmjs.com/package/better-sqlite3-session-store
+[better-sqlite3-session-store-image]: https://badgen.net/github/stars/timdaub/better-sqlite3-session-store?label=%E2%98%85
+
+[![★][cassandra-store-image] cassandra-store][cassandra-store-url] An Apache Cassandra-based session store.
+
+[cassandra-store-url]: https://www.npmjs.com/package/cassandra-store
+[cassandra-store-image]: https://badgen.net/github/stars/webcc/cassandra-store?label=%E2%98%85
+
+[![★][cluster-store-image] cluster-store][cluster-store-url] A wrapper for using in-process / embedded
+stores - such as SQLite (via knex), leveldb, files, or memory - with node cluster (desirable for Raspberry Pi 2
+and other multi-core embedded devices).
+
+[cluster-store-url]: https://www.npmjs.com/package/cluster-store
+[cluster-store-image]: https://badgen.net/github/stars/coolaj86/cluster-store?label=%E2%98%85
+
+[![★][connect-arango-image] connect-arango][connect-arango-url] An ArangoDB-based session store.
+
+[connect-arango-url]: https://www.npmjs.com/package/connect-arango
+[connect-arango-image]: https://badgen.net/github/stars/AlexanderArvidsson/connect-arango?label=%E2%98%85
+
+[![★][connect-azuretables-image] connect-azuretables][connect-azuretables-url] An [Azure Table Storage](https://azure.microsoft.com/en-gb/services/storage/tables/)-based session store.
+
+[connect-azuretables-url]: https://www.npmjs.com/package/connect-azuretables
+[connect-azuretables-image]: https://badgen.net/github/stars/mike-goodwin/connect-azuretables?label=%E2%98%85
+
+[![★][connect-cloudant-store-image] connect-cloudant-store][connect-cloudant-store-url] An [IBM Cloudant](https://cloudant.com/)-based session store.
+
+[connect-cloudant-store-url]: https://www.npmjs.com/package/connect-cloudant-store
+[connect-cloudant-store-image]: https://badgen.net/github/stars/adriantanasa/connect-cloudant-store?label=%E2%98%85
+
+[![★][connect-cosmosdb-image] connect-cosmosdb][connect-cosmosdb-url] An Azure [Cosmos DB](https://azure.microsoft.com/en-us/products/cosmos-db/)-based session store.
+
+[connect-cosmosdb-url]: https://www.npmjs.com/package/connect-cosmosdb
+[connect-cosmosdb-image]: https://badgen.net/github/stars/thekillingspree/connect-cosmosdb?label=%E2%98%85
+
+[![★][connect-couchbase-image] connect-couchbase][connect-couchbase-url] A [couchbase](http://www.couchbase.com/)-based session store.
+
+[connect-couchbase-url]: https://www.npmjs.com/package/connect-couchbase
+[connect-couchbase-image]: https://badgen.net/github/stars/christophermina/connect-couchbase?label=%E2%98%85
+
+[![★][connect-datacache-image] connect-datacache][connect-datacache-url] An [IBM Bluemix Data Cache](http://www.ibm.com/cloud-computing/bluemix/)-based session store.
+
+[connect-datacache-url]: https://www.npmjs.com/package/connect-datacache
+[connect-datacache-image]: https://badgen.net/github/stars/adriantanasa/connect-datacache?label=%E2%98%85
+
+[![★][@google-cloud/connect-datastore-image] @google-cloud/connect-datastore][@google-cloud/connect-datastore-url] A [Google Cloud Datastore](https://cloud.google.com/datastore/docs/concepts/overview)-based session store.
+
+[@google-cloud/connect-datastore-url]: https://www.npmjs.com/package/@google-cloud/connect-datastore
+[@google-cloud/connect-datastore-image]: https://badgen.net/github/stars/GoogleCloudPlatform/cloud-datastore-session-node?label=%E2%98%85
+
+[![★][connect-db2-image] connect-db2][connect-db2-url] An IBM DB2-based session store built using [ibm_db](https://www.npmjs.com/package/ibm_db) module.
+
+[connect-db2-url]: https://www.npmjs.com/package/connect-db2
+[connect-db2-image]: https://badgen.net/github/stars/wallali/connect-db2?label=%E2%98%85
+
+[![★][connect-dynamodb-image] connect-dynamodb][connect-dynamodb-url] A DynamoDB-based session store.
+
+[connect-dynamodb-url]: https://www.npmjs.com/package/connect-dynamodb
+[connect-dynamodb-image]: https://badgen.net/github/stars/ca98am79/connect-dynamodb?label=%E2%98%85
+
+[![★][@google-cloud/connect-firestore-image] @google-cloud/connect-firestore][@google-cloud/connect-firestore-url] A [Google Cloud Firestore](https://cloud.google.com/firestore/docs/overview)-based session store.
+
+[@google-cloud/connect-firestore-url]: https://www.npmjs.com/package/@google-cloud/connect-firestore
+[@google-cloud/connect-firestore-image]: https://badgen.net/github/stars/googleapis/nodejs-firestore-session?label=%E2%98%85
+
+[![★][connect-hazelcast-image] connect-hazelcast][connect-hazelcast-url] Hazelcast session store for Connect and Express.
+
+[connect-hazelcast-url]: https://www.npmjs.com/package/connect-hazelcast
+[connect-hazelcast-image]: https://badgen.net/github/stars/huseyinbabal/connect-hazelcast?label=%E2%98%85
+
+[![★][connect-loki-image] connect-loki][connect-loki-url] A Loki.js-based session store.
+
+[connect-loki-url]: https://www.npmjs.com/package/connect-loki
+[connect-loki-image]: https://badgen.net/github/stars/Requarks/connect-loki?label=%E2%98%85
+
+[![★][connect-lowdb-image] connect-lowdb][connect-lowdb-url] A lowdb-based session store.
+
+[connect-lowdb-url]: https://www.npmjs.com/package/connect-lowdb
+[connect-lowdb-image]: https://badgen.net/github/stars/travishorn/connect-lowdb?label=%E2%98%85
+
+[![★][connect-memcached-image] connect-memcached][connect-memcached-url] A memcached-based session store.
+
+[connect-memcached-url]: https://www.npmjs.com/package/connect-memcached
+[connect-memcached-image]: https://badgen.net/github/stars/balor/connect-memcached?label=%E2%98%85
+
+[![★][connect-memjs-image] connect-memjs][connect-memjs-url] A memcached-based session store using
+[memjs](https://www.npmjs.com/package/memjs) as the memcached client.
+
+[connect-memjs-url]: https://www.npmjs.com/package/connect-memjs
+[connect-memjs-image]: https://badgen.net/github/stars/liamdon/connect-memjs?label=%E2%98%85
+
+[![★][connect-ml-image] connect-ml][connect-ml-url] A MarkLogic Server-based session store.
+
+[connect-ml-url]: https://www.npmjs.com/package/connect-ml
+[connect-ml-image]: https://badgen.net/github/stars/bluetorch/connect-ml?label=%E2%98%85
+
+[![★][connect-monetdb-image] connect-monetdb][connect-monetdb-url] A MonetDB-based session store.
+
+[connect-monetdb-url]: https://www.npmjs.com/package/connect-monetdb
+[connect-monetdb-image]: https://badgen.net/github/stars/MonetDB/npm-connect-monetdb?label=%E2%98%85
+
+[![★][connect-mongo-image] connect-mongo][connect-mongo-url] A MongoDB-based session store.
+
+[connect-mongo-url]: https://www.npmjs.com/package/connect-mongo
+[connect-mongo-image]: https://badgen.net/github/stars/kcbanner/connect-mongo?label=%E2%98%85
+
+[![★][connect-mongodb-session-image] connect-mongodb-session][connect-mongodb-session-url] Lightweight MongoDB-based session store built and maintained by MongoDB.
+
+[connect-mongodb-session-url]: https://www.npmjs.com/package/connect-mongodb-session
+[connect-mongodb-session-image]: https://badgen.net/github/stars/mongodb-js/connect-mongodb-session?label=%E2%98%85
+
+[![★][connect-mssql-v2-image] connect-mssql-v2][connect-mssql-v2-url] A Microsoft SQL Server-based session store based on [connect-mssql](https://www.npmjs.com/package/connect-mssql).
+
+[connect-mssql-v2-url]: https://www.npmjs.com/package/connect-mssql-v2
+[connect-mssql-v2-image]: https://badgen.net/github/stars/jluboff/connect-mssql-v2?label=%E2%98%85
+
+[![★][connect-neo4j-image] connect-neo4j][connect-neo4j-url] A [Neo4j](https://neo4j.com)-based session store.
+
+[connect-neo4j-url]: https://www.npmjs.com/package/connect-neo4j
+[connect-neo4j-image]: https://badgen.net/github/stars/MaxAndersson/connect-neo4j?label=%E2%98%85
+
+[![★][connect-ottoman-image] connect-ottoman][connect-ottoman-url] A [couchbase ottoman](http://www.couchbase.com/)-based session store.
+
+[connect-ottoman-url]: https://www.npmjs.com/package/connect-ottoman
+[connect-ottoman-image]: https://badgen.net/github/stars/noiissyboy/connect-ottoman?label=%E2%98%85
+
+[![★][connect-pg-simple-image] connect-pg-simple][connect-pg-simple-url] A PostgreSQL-based session store.
+
+[connect-pg-simple-url]: https://www.npmjs.com/package/connect-pg-simple
+[connect-pg-simple-image]: https://badgen.net/github/stars/voxpelli/node-connect-pg-simple?label=%E2%98%85
+
+[![★][connect-redis-image] connect-redis][connect-redis-url] A Redis-based session store.
+
+[connect-redis-url]: https://www.npmjs.com/package/connect-redis
+[connect-redis-image]: https://badgen.net/github/stars/tj/connect-redis?label=%E2%98%85
+
+[![★][connect-session-firebase-image] connect-session-firebase][connect-session-firebase-url] A session store based on the [Firebase Realtime Database](https://firebase.google.com/docs/database/)
+
+[connect-session-firebase-url]: https://www.npmjs.com/package/connect-session-firebase
+[connect-session-firebase-image]: https://badgen.net/github/stars/benweier/connect-session-firebase?label=%E2%98%85
+
+[![★][connect-session-knex-image] connect-session-knex][connect-session-knex-url] A session store using
+[Knex.js](http://knexjs.org/), which is a SQL query builder for PostgreSQL, MySQL, MariaDB, SQLite3, and Oracle.
+
+[connect-session-knex-url]: https://www.npmjs.com/package/connect-session-knex
+[connect-session-knex-image]: https://badgen.net/github/stars/llambda/connect-session-knex?label=%E2%98%85
+
+[![★][connect-session-sequelize-image] connect-session-sequelize][connect-session-sequelize-url] A session store using
+[Sequelize.js](http://sequelizejs.com/), which is a Node.js / io.js ORM for PostgreSQL, MySQL, SQLite and MSSQL.
+
+[connect-session-sequelize-url]: https://www.npmjs.com/package/connect-session-sequelize
+[connect-session-sequelize-image]: https://badgen.net/github/stars/mweibel/connect-session-sequelize?label=%E2%98%85
+
+[![★][connect-sqlite3-image] connect-sqlite3][connect-sqlite3-url] A [SQLite3](https://github.com/mapbox/node-sqlite3) session store modeled after the TJ's `connect-redis` store.
+
+[connect-sqlite3-url]: https://www.npmjs.com/package/connect-sqlite3
+[connect-sqlite3-image]: https://badgen.net/github/stars/rawberg/connect-sqlite3?label=%E2%98%85
+
+[![★][connect-typeorm-image] connect-typeorm][connect-typeorm-url] A [TypeORM](https://github.com/typeorm/typeorm)-based session store.
+
+[connect-typeorm-url]: https://www.npmjs.com/package/connect-typeorm
+[connect-typeorm-image]: https://badgen.net/github/stars/makepost/connect-typeorm?label=%E2%98%85
+
+[![★][couchdb-expression-image] couchdb-expression][couchdb-expression-url] A [CouchDB](https://couchdb.apache.org/)-based session store.
+
+[couchdb-expression-url]: https://www.npmjs.com/package/couchdb-expression
+[couchdb-expression-image]: https://badgen.net/github/stars/tkshnwesper/couchdb-expression?label=%E2%98%85
+
+[![★][dynamodb-store-image] dynamodb-store][dynamodb-store-url] A DynamoDB-based session store.
+
+[dynamodb-store-url]: https://www.npmjs.com/package/dynamodb-store
+[dynamodb-store-image]: https://badgen.net/github/stars/rafaelrpinto/dynamodb-store?label=%E2%98%85
+
+[![★][dynamodb-store-v3-image] dynamodb-store-v3][dynamodb-store-v3-url] Implementation of a session store using DynamoDB backed by the [AWS SDK for JavaScript v3](https://github.com/aws/aws-sdk-js-v3).
+
+[dynamodb-store-v3-url]: https://www.npmjs.com/package/dynamodb-store-v3
+[dynamodb-store-v3-image]: https://badgen.net/github/stars/FryDay/dynamodb-store-v3?label=%E2%98%85
+
+[![★][express-etcd-image] express-etcd][express-etcd-url] An [etcd](https://github.com/stianeikeland/node-etcd) based session store.
+
+[express-etcd-url]: https://www.npmjs.com/package/express-etcd
+[express-etcd-image]: https://badgen.net/github/stars/gildean/express-etcd?label=%E2%98%85
+
+[![★][express-mysql-session-image] express-mysql-session][express-mysql-session-url] A session store using native
+[MySQL](https://www.mysql.com/) via the [node-mysql](https://github.com/felixge/node-mysql) module.
+
+[express-mysql-session-url]: https://www.npmjs.com/package/express-mysql-session
+[express-mysql-session-image]: https://badgen.net/github/stars/chill117/express-mysql-session?label=%E2%98%85
+
+[![★][express-nedb-session-image] express-nedb-session][express-nedb-session-url] A NeDB-based session store.
+
+[express-nedb-session-url]: https://www.npmjs.com/package/express-nedb-session
+[express-nedb-session-image]: https://badgen.net/github/stars/louischatriot/express-nedb-session?label=%E2%98%85
+
+[![★][express-oracle-session-image] express-oracle-session][express-oracle-session-url] A session store using native
+[oracle](https://www.oracle.com/) via the [node-oracledb](https://www.npmjs.com/package/oracledb) module.
+
+[express-oracle-session-url]: https://www.npmjs.com/package/express-oracle-session
+[express-oracle-session-image]: https://badgen.net/github/stars/slumber86/express-oracle-session?label=%E2%98%85
+
+[![★][express-session-cache-manager-image] express-session-cache-manager][express-session-cache-manager-url]
+A store that implements [cache-manager](https://www.npmjs.com/package/cache-manager), which supports
+a [variety of storage types](https://www.npmjs.com/package/cache-manager#store-engines).
+
+[express-session-cache-manager-url]: https://www.npmjs.com/package/express-session-cache-manager
+[express-session-cache-manager-image]: https://badgen.net/github/stars/theogravity/express-session-cache-manager?label=%E2%98%85
+
+[![★][express-session-etcd3-image] express-session-etcd3][express-session-etcd3-url] An [etcd3](https://github.com/mixer/etcd3) based session store.
+
+[express-session-etcd3-url]: https://www.npmjs.com/package/express-session-etcd3
+[express-session-etcd3-image]: https://badgen.net/github/stars/willgm/express-session-etcd3?label=%E2%98%85
+
+[![★][express-session-level-image] express-session-level][express-session-level-url] A [LevelDB](https://github.com/Level/levelup) based session store.
+
+[express-session-level-url]: https://www.npmjs.com/package/express-session-level
+[express-session-level-image]: https://badgen.net/github/stars/tgohn/express-session-level?label=%E2%98%85
+
+[![★][express-session-rsdb-image] express-session-rsdb][express-session-rsdb-url] Session store based on Rocket-Store: A very simple, super fast and yet powerful, flat file database.
+
+[express-session-rsdb-url]: https://www.npmjs.com/package/express-session-rsdb
+[express-session-rsdb-image]: https://badgen.net/github/stars/paragi/express-session-rsdb?label=%E2%98%85
+
+[![★][express-sessions-image] express-sessions][express-sessions-url] A session store supporting both MongoDB and Redis.
+
+[express-sessions-url]: https://www.npmjs.com/package/express-sessions
+[express-sessions-image]: https://badgen.net/github/stars/konteck/express-sessions?label=%E2%98%85
+
+[![★][firestore-store-image] firestore-store][firestore-store-url] A [Firestore](https://github.com/hendrysadrak/firestore-store)-based session store.
+
+[firestore-store-url]: https://www.npmjs.com/package/firestore-store
+[firestore-store-image]: https://badgen.net/github/stars/hendrysadrak/firestore-store?label=%E2%98%85
+
+[![★][fortune-session-image] fortune-session][fortune-session-url] A [Fortune.js](https://github.com/fortunejs/fortune)
+based session store. Supports all backends supported by Fortune (MongoDB, Redis, Postgres, NeDB).
+
+[fortune-session-url]: https://www.npmjs.com/package/fortune-session
+[fortune-session-image]: https://badgen.net/github/stars/aliceklipper/fortune-session?label=%E2%98%85
+
+[![★][hazelcast-store-image] hazelcast-store][hazelcast-store-url] A Hazelcast-based session store built on the [Hazelcast Node Client](https://www.npmjs.com/package/hazelcast-client).
+
+[hazelcast-store-url]: https://www.npmjs.com/package/hazelcast-store
+[hazelcast-store-image]: https://badgen.net/github/stars/jackspaniel/hazelcast-store?label=%E2%98%85
+
+[![★][level-session-store-image] level-session-store][level-session-store-url] A LevelDB-based session store.
+
+[level-session-store-url]: https://www.npmjs.com/package/level-session-store
+[level-session-store-image]: https://badgen.net/github/stars/toddself/level-session-store?label=%E2%98%85
+
+[![★][lowdb-session-store-image] lowdb-session-store][lowdb-session-store-url] A [lowdb](https://www.npmjs.com/package/lowdb)-based session store.
+
+[lowdb-session-store-url]: https://www.npmjs.com/package/lowdb-session-store
+[lowdb-session-store-image]: https://badgen.net/github/stars/fhellwig/lowdb-session-store?label=%E2%98%85
+
+[![★][medea-session-store-image] medea-session-store][medea-session-store-url] A Medea-based session store.
+
+[medea-session-store-url]: https://www.npmjs.com/package/medea-session-store
+[medea-session-store-image]: https://badgen.net/github/stars/BenjaminVadant/medea-session-store?label=%E2%98%85
+
+[![★][memorystore-image] memorystore][memorystore-url] A memory session store made for production.
+
+[memorystore-url]: https://www.npmjs.com/package/memorystore
+[memorystore-image]: https://badgen.net/github/stars/roccomuso/memorystore?label=%E2%98%85
+
+[![★][mssql-session-store-image] mssql-session-store][mssql-session-store-url] A SQL Server-based session store.
+
+[mssql-session-store-url]: https://www.npmjs.com/package/mssql-session-store
+[mssql-session-store-image]: https://badgen.net/github/stars/jwathen/mssql-session-store?label=%E2%98%85
+
+[![★][nedb-session-store-image] nedb-session-store][nedb-session-store-url] An alternate NeDB-based (either in-memory or file-persisted) session store.
+
+[nedb-session-store-url]: https://www.npmjs.com/package/nedb-session-store
+[nedb-session-store-image]: https://badgen.net/github/stars/JamesMGreene/nedb-session-store?label=%E2%98%85
+
+[![★][@quixo3/prisma-session-store-image] @quixo3/prisma-session-store][@quixo3/prisma-session-store-url] A session store for the [Prisma Framework](https://www.prisma.io).
+
+[@quixo3/prisma-session-store-url]: https://www.npmjs.com/package/@quixo3/prisma-session-store
+[@quixo3/prisma-session-store-image]: https://badgen.net/github/stars/kleydon/prisma-session-store?label=%E2%98%85
+
+[![★][restsession-image] restsession][restsession-url] Store sessions utilizing a RESTful API
+
+[restsession-url]: https://www.npmjs.com/package/restsession
+[restsession-image]: https://badgen.net/github/stars/jankal/restsession?label=%E2%98%85
+
+[![★][sequelstore-connect-image] sequelstore-connect][sequelstore-connect-url] A session store using [Sequelize.js](http://sequelizejs.com/).
+
+[sequelstore-connect-url]: https://www.npmjs.com/package/sequelstore-connect
+[sequelstore-connect-image]: https://badgen.net/github/stars/MattMcFarland/sequelstore-connect?label=%E2%98%85
+
+[![★][session-file-store-image] session-file-store][session-file-store-url] A file system-based session store.
+
+[session-file-store-url]: https://www.npmjs.com/package/session-file-store
+[session-file-store-image]: https://badgen.net/github/stars/valery-barysok/session-file-store?label=%E2%98%85
+
+[![★][session-pouchdb-store-image] session-pouchdb-store][session-pouchdb-store-url] Session store for PouchDB / CouchDB. Accepts embedded, custom, or remote PouchDB instance and realtime synchronization.
+
+[session-pouchdb-store-url]: https://www.npmjs.com/package/session-pouchdb-store
+[session-pouchdb-store-image]: https://badgen.net/github/stars/solzimer/session-pouchdb-store?label=%E2%98%85
+
+[![★][@cyclic.sh/session-store-image] @cyclic.sh/session-store][@cyclic.sh/session-store-url] A DynamoDB-based session store for [Cyclic.sh](https://www.cyclic.sh/) apps.
+
+[@cyclic.sh/session-store-url]: https://www.npmjs.com/package/@cyclic.sh/session-store
+[@cyclic.sh/session-store-image]: https://badgen.net/github/stars/cyclic-software/session-store?label=%E2%98%85
+
+[![★][@databunker/session-store-image] @databunker/session-store][@databunker/session-store-url] A [Databunker](https://databunker.org/)-based encrypted session store.
+
+[@databunker/session-store-url]: https://www.npmjs.com/package/@databunker/session-store
+[@databunker/session-store-image]: https://badgen.net/github/stars/securitybunker/databunker-session-store?label=%E2%98%85
+
+[![★][sessionstore-image] sessionstore][sessionstore-url] A session store that works with various databases.
+
+[sessionstore-url]: https://www.npmjs.com/package/sessionstore
+[sessionstore-image]: https://badgen.net/github/stars/adrai/sessionstore?label=%E2%98%85
+
+[![★][tch-nedb-session-image] tch-nedb-session][tch-nedb-session-url] A file system session store based on NeDB.
+
+[tch-nedb-session-url]: https://www.npmjs.com/package/tch-nedb-session
+[tch-nedb-session-image]: https://badgen.net/github/stars/tomaschyly/NeDBSession?label=%E2%98%85
+
+## Examples
+
+### View counter
+
+A simple example using `express-session` to store page views for a user.
+
+```js
+var express = require('express');
+var parseurl = require('parseurl');
+var session = require('express-session');
+
+var app = express();
+
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ })
+);
+
+app.use(function (req, res, next) {
+ if (!req.session.views) {
+ req.session.views = {};
+ }
+
+ // get the url pathname
+ var pathname = parseurl(req).pathname;
+
+ // count the views
+ req.session.views[pathname] = (req.session.views[pathname] || 0) + 1;
+
+ next();
+});
+
+app.get('/foo', function (req, res, next) {
+ res.send('you viewed this page ' + req.session.views['/foo'] + ' times');
+});
+
+app.get('/bar', function (req, res, next) {
+ res.send('you viewed this page ' + req.session.views['/bar'] + ' times');
+});
+
+app.listen(3000);
+```
+
+### User login
+
+A simple example using `express-session` to keep a user log in session.
+
+```js
+var escapeHtml = require('escape-html');
+var express = require('express');
+var session = require('express-session');
+
+var app = express();
+
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ })
+);
+
+// middleware to test if authenticated
+function isAuthenticated(req, res, next) {
+ if (req.session.user) next();
+ else next('route');
+}
+
+app.get('/', isAuthenticated, function (req, res) {
+ // this is only called when there is an authentication user due to isAuthenticated
+ res.send('hello, ' + escapeHtml(req.session.user) + '!' + ' Logout ');
+});
+
+app.get('/', function (req, res) {
+ res.send(
+ ''
+ );
+});
+
+app.post('/login', express.urlencoded({ extended: false }), function (req, res) {
+ // login logic to validate req.body.user and req.body.pass
+ // would be implemented here. for this example any combo works
+
+ // regenerate the session, which is good practice to help
+ // guard against forms of session fixation
+ req.session.regenerate(function (err) {
+ if (err) next(err);
+
+ // store user information in session, typically a user id
+ req.session.user = req.body.user;
+
+ // save the session before redirection to ensure page
+ // load does not happen before session is saved
+ req.session.save(function (err) {
+ if (err) return next(err);
+ res.redirect('/');
+ });
+ });
+});
+
+app.get('/logout', function (req, res, next) {
+ // logout logic
+
+ // clear the user from the session object and save.
+ // this will ensure that re-using the old session id
+ // does not have a logged in user
+ req.session.user = null;
+ req.session.save(function (err) {
+ if (err) next(err);
+
+ // regenerate the session, which is good practice to help
+ // guard against forms of session fixation
+ req.session.regenerate(function (err) {
+ if (err) next(err);
+ res.redirect('/');
+ });
+ });
+});
+
+app.listen(3000);
+```
+
+## Debugging
+
+This module uses the [debug](https://www.npmjs.com/package/debug) module
+internally to log information about session operations.
+
+To see all the internal logs, set the `DEBUG` environment variable to
+`express-session` when launching your app (`npm start`, in this example):
+
+```sh
+$ DEBUG=express-session npm start
+```
+
+On Windows, use the corresponding command;
+
+```sh
+> set DEBUG=express-session & npm start
+```
+
+## License
+
+[MIT](LICENSE)
+
+[rfc-6265bis-03-4.1.2.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7
+[rfc-cutler-httpbis-partitioned-cookies]: https://tools.ietf.org/html/draft-cutler-httpbis-partitioned-cookies/
+[rfc-west-cookie-priority-00-4.1]: https://tools.ietf.org/html/draft-west-cookie-priority-00#section-4.1
+[ci-image]: https://badgen.net/github/checks/expressjs/session/master?label=ci
+[ci-url]: https://github.com/expressjs/session/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/session/master
+[coveralls-url]: https://coveralls.io/r/expressjs/session?branch=master
+[node-url]: https://nodejs.org/en/download
+[npm-downloads-image]: https://badgen.net/npm/dm/express-session
+[npm-url]: https://npmjs.org/package/express-session
+[npm-version-image]: https://badgen.net/npm/v/express-session
diff --git a/astro/src/content/resources/ja/middleware/timeout.md b/astro/src/content/resources/ja/middleware/timeout.md
new file mode 100644
index 0000000000..f6057aedfd
--- /dev/null
+++ b/astro/src/content/resources/ja/middleware/timeout.md
@@ -0,0 +1,176 @@
+---
+title: Express timeout middleware
+module: timeout
+---
+
+# connect-timeout
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][travis-image]][travis-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Times out a request in the Connect/Express application framework.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install connect-timeout
+```
+
+## API
+
+**NOTE** This module is not recommend as a "top-level" middleware (i.e.
+`app.use(timeout('5s'))`) unless you take precautions to halt your own
+middleware processing. See [as top-level middleware](#as-top-level-middleware)
+for how to use as a top-level middleware.
+
+While the library will emit a 'timeout' event when requests exceed the given
+timeout, node will continue processing the slow request until it terminates.
+Slow requests will continue to use CPU and memory, even if you are returning
+a HTTP response in the timeout callback. For better control over CPU/memory,
+you may need to find the events that are taking a long time (3rd party HTTP
+requests, disk I/O, database calls) and find a way to cancel them, and/or
+close the attached sockets.
+
+### timeout(time, [options])
+
+Returns middleware that times out in `time` milliseconds. `time` can also
+be a string accepted by the [ms](https://www.npmjs.org/package/ms#readme)
+module. On timeout, `req` will emit `"timeout"`.
+
+#### Options
+
+The `timeout` function takes an optional `options` object that may contain
+any of the following keys:
+
+##### respond
+
+Controls if this module will "respond" in the form of forwarding an error.
+If `true`, the timeout error is passed to `next()` so that you may customize
+the response behavior. This error has a `.timeout` property as well as
+`.status == 503`. This defaults to `true`.
+
+### req.clearTimeout()
+
+Clears the timeout on the request. The timeout is completely removed and
+will not fire for this request in the future.
+
+### req.timedout
+
+`true` if timeout fired; `false` otherwise.
+
+## Examples
+
+### as top-level middleware
+
+Because of the way middleware processing works, once this module
+passes the request to the next middleware (which it has to do in order
+for you to do work), it can no longer stop the flow, so you must take
+care to check if the request has timedout before you continue to act
+on the request.
+
+```javascript
+var bodyParser = require('body-parser');
+var cookieParser = require('cookie-parser');
+var express = require('express');
+var timeout = require('connect-timeout');
+
+// example of using this top-level; note the use of haltOnTimedout
+// after every middleware; it will stop the request flow on a timeout
+var app = express();
+app.use(timeout('5s'));
+app.use(bodyParser());
+app.use(haltOnTimedout);
+app.use(cookieParser());
+app.use(haltOnTimedout);
+
+// Add your routes here, etc.
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+app.listen(3000);
+```
+
+### express 3.x
+
+```javascript
+var express = require('express');
+var bodyParser = require('body-parser');
+var timeout = require('connect-timeout');
+
+var app = express();
+app.post('/save', timeout('5s'), bodyParser.json(), haltOnTimedout, function (req, res, next) {
+ savePost(req.body, function (err, id) {
+ if (err) return next(err);
+ if (req.timedout) return;
+ res.send('saved as id ' + id);
+ });
+});
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+function savePost(post, cb) {
+ setTimeout(
+ function () {
+ cb(null, (Math.random() * 40000) >>> 0);
+ },
+ (Math.random() * 7000) >>> 0
+ );
+}
+
+app.listen(3000);
+```
+
+### connect
+
+```javascript
+var bodyParser = require('body-parser');
+var connect = require('connect');
+var timeout = require('connect-timeout');
+
+var app = connect();
+app.use('/save', timeout('5s'), bodyParser.json(), haltOnTimedout, function (req, res, next) {
+ savePost(req.body, function (err, id) {
+ if (err) return next(err);
+ if (req.timedout) return;
+ res.send('saved as id ' + id);
+ });
+});
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+function savePost(post, cb) {
+ setTimeout(
+ function () {
+ cb(null, (Math.random() * 40000) >>> 0);
+ },
+ (Math.random() * 7000) >>> 0
+ );
+}
+
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/connect-timeout.svg
+[npm-url]: https://npmjs.org/package/connect-timeout
+[travis-image]: https://img.shields.io/travis/expressjs/timeout/master.svg
+[travis-url]: https://travis-ci.org/expressjs/timeout
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/timeout/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/timeout?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/connect-timeout.svg
+[downloads-url]: https://npmjs.org/package/connect-timeout
diff --git a/astro/src/content/resources/ja/middleware/vhost.md b/astro/src/content/resources/ja/middleware/vhost.md
new file mode 100644
index 0000000000..72f49d7f93
--- /dev/null
+++ b/astro/src/content/resources/ja/middleware/vhost.md
@@ -0,0 +1,174 @@
+---
+title: Express vhost middleware
+module: vhost
+---
+
+# vhost
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Install
+
+```sh
+$ npm install vhost
+```
+
+## API
+
+```js
+var vhost = require('vhost');
+```
+
+### vhost(hostname, handle)
+
+Create a new middleware function to hand off request to `handle` when the incoming
+host for the request matches `hostname`. The function is called as
+`handle(req, res, next)`, like a standard middleware.
+
+`hostname` can be a string or a RegExp object. When `hostname` is a string it can
+contain `*` to match 1 or more characters in that section of the hostname. When
+`hostname` is a RegExp, it will be forced to case-insensitive (since hostnames are)
+and will be forced to match based on the start and end of the hostname.
+
+When host is matched and the request is sent down to a vhost handler, the `req.vhost`
+property will be populated with an object. This object will have numeric properties
+corresponding to each wildcard (or capture group if RegExp object provided) and the
+`hostname` that was matched.
+
+```js
+var connect = require('connect');
+var vhost = require('vhost');
+var app = connect();
+
+app.use(
+ vhost('*.*.example.com', function handle(req, res, next) {
+ // for match of "foo.bar.example.com:8080" against "*.*.example.com":
+ console.dir(req.vhost.host); // => 'foo.bar.example.com:8080'
+ console.dir(req.vhost.hostname); // => 'foo.bar.example.com'
+ console.dir(req.vhost.length); // => 2
+ console.dir(req.vhost[0]); // => 'foo'
+ console.dir(req.vhost[1]); // => 'bar'
+ })
+);
+```
+
+## Examples
+
+### using with connect for static serving
+
+```js
+var connect = require('connect');
+var serveStatic = require('serve-static');
+var vhost = require('vhost');
+
+var mailapp = connect();
+
+// add middlewares to mailapp for mail.example.com
+
+// create app to serve static files on subdomain
+var staticapp = connect();
+staticapp.use(serveStatic('public'));
+
+// create main app
+var app = connect();
+
+// add vhost routing to main app for mail
+app.use(vhost('mail.example.com', mailapp));
+
+// route static assets for "assets-*" subdomain to get
+// around max host connections limit on browsers
+app.use(vhost('assets-*.example.com', staticapp));
+
+// add middlewares and main usage to app
+
+app.listen(3000);
+```
+
+### using with connect for user subdomains
+
+```js
+var connect = require('connect');
+var serveStatic = require('serve-static');
+var vhost = require('vhost');
+
+var mainapp = connect();
+
+// add middlewares to mainapp for the main web site
+
+// create app that will server user content from public/{username}/
+var userapp = connect();
+
+userapp.use(function (req, res, next) {
+ var username = req.vhost[0]; // username is the "*"
+
+ // pretend request was for /{username}/* for file serving
+ req.originalUrl = req.url;
+ req.url = '/' + username + req.url;
+
+ next();
+});
+userapp.use(serveStatic('public'));
+
+// create main app
+var app = connect();
+
+// add vhost routing for main app
+app.use(vhost('userpages.local', mainapp));
+app.use(vhost('www.userpages.local', mainapp));
+
+// listen on all subdomains for user pages
+app.use(vhost('*.userpages.local', userapp));
+
+app.listen(3000);
+```
+
+### using with any generic request handler
+
+```js
+var connect = require('connect');
+var http = require('http');
+var vhost = require('vhost');
+
+// create main app
+var app = connect();
+
+app.use(
+ vhost('mail.example.com', function (req, res) {
+ // handle req + res belonging to mail.example.com
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello from mail!');
+ })
+);
+
+// an external api server in any framework
+var httpServer = http.createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello from the api!');
+});
+
+app.use(
+ vhost('api.example.com', function (req, res) {
+ // handle req + res belonging to api.example.com
+ // pass the request to a standard Node.js HTTP server
+ httpServer.emit('request', req, res);
+ })
+);
+
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/vhost.svg
+[npm-url]: https://npmjs.org/package/vhost
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/vhost/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/vhost
+[downloads-image]: https://img.shields.io/npm/dm/vhost.svg
+[downloads-url]: https://npmjs.org/package/vhost
+[github-actions-ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/vhost/ci.yml?branch=master&label=ci
+[github-actions-ci-url]: https://github.com/expressjs/vhost/actions/workflows/ci.yml
diff --git a/astro/src/content/resources/ja/utils.md b/astro/src/content/resources/ja/utils.md
new file mode 100644
index 0000000000..546b2f09b4
--- /dev/null
+++ b/astro/src/content/resources/ja/utils.md
@@ -0,0 +1,22 @@
+---
+title: Express utilities
+description: Discover utility modules related to Express.js and Node.js, including tools for cookies, CSRF protection, URL parsing, routing, and more to enhance your applications.
+---
+
+## Express utility functions
+
+The [pillarjs](https://github.com/pillarjs) GitHub organization contains a number of modules
+for utility functions that may be generally useful.
+
+| Utility modules | Description |
+| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| [cookies](https://www.npmjs.com/package/cookies) | Get and set HTTP(S) cookies that can be signed to prevent tampering, using Keygrip. Can be used with the Node.js HTTP library or as Express middleware. |
+| [csrf](https://www.npmjs.com/package/csrf) | Contains the logic behind CSRF token creation and verification. Use this module to create custom CSRF middleware. |
+| [finalhandler](https://www.npmjs.com/package/finalhandler) | Function to invoke as the final step to respond to HTTP request. |
+| [parseurl](https://www.npmjs.com/package/parseurl) | Parse a URL with caching. |
+| [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) | Turn an Express-style path string such as ``/user/:name` into a regular expression. |
+| [resolve-path](https://www.npmjs.com/package/resolve-path) | Resolves a relative path against a root path with validation. |
+| [router](https://www.npmjs.com/package/router) | Simple middleware-style router. |
+| [send](https://www.npmjs.com/package/send) | Library for streaming files as a HTTP response, with support for partial responses (ranges), conditional-GET negotiation, and granular events. |
+
+For additional low-level HTTP-related modules, see [jshttp](https://github.com/jshttp).
diff --git a/astro/src/content/resources/ko/community.md b/astro/src/content/resources/ko/community.md
new file mode 100755
index 0000000000..e40d97e421
--- /dev/null
+++ b/astro/src/content/resources/ko/community.md
@@ -0,0 +1,70 @@
+---
+title: Express community
+description: Connect with the Express.js community, learn about the technical committee, find resources, explore community-contributed modules, and get involved in discussions.
+---
+
+# Community
+
+## Technical committee
+
+The Express technical committee meets online every two weeks (as needed) to discuss development and maintenance of Express,
+and other issues relevant to the Express project. Each meeting is typically announced in an
+[expressjs/discussions issue](https://github.com/expressjs/discussions/issues) with a link to join or view the meeting, which is
+open to all observers.
+
+The meetings are recorded; for a list of the recordings, see the [Express.js YouTube channel](https://www.youtube.com/channel/UCYjxjAeH6TRik9Iwy5nXw7g).
+
+Members of the Express technical committee are:
+
+**Active:**
+
+- [@blakeembrey](https://github.com/blakeembrey) - Blake Embrey
+- [@crandmck](https://github.com/crandmck) - Rand McKinney
+- [@LinusU](https://github.com/LinusU) - Linus Unnebäck
+- [@ulisesgascon](https://github.com/ulisesGascon) - Ulises Gascón
+- [@sheplu](https://github.com/sheplu) - Jean Burellier
+- [@wesleytodd](https://github.com/wesleytodd) - Wes Todd
+- [@jonchurch](https://github.com/jonchurch) - Jon Church
+- [@ctcpip](https://github.com/ctcpip/) - Chris de Almeida
+
+**Inactive:**
+
+- [@dougwilson](https://github.com/dougwilson) - Douglas Wilson
+- [@hacksparrow](https://github.com/hacksparrow) - Hage Yaapa
+- [@jonathanong](https://github.com/jonathanong) - jongleberry
+- [@niftylettuce](https://github.com/niftylettuce) - niftylettuce
+- [@troygoode](https://github.com/troygoode) - Troy Goode
+
+## Express is made of many modules
+
+Our vibrant community has created a large variety of extensions,
+[middleware modules](/en/resources/middleware) and higher-level frameworks.
+
+Additionally, the Express community maintains modules in these two GitHub orgs:
+
+- [jshttp](https://github.com/jshttp) modules providing useful utility functions; see [Utility modules](/en/resources/utils).
+- [pillarjs](https://github.com/pillarjs): low-level modules that Express uses internally.
+
+To keep up with what is going on in the whole community, check out the [ExpressJS StatusBoard](https://expressjs.github.io/statusboard/).
+
+## Issues
+
+If you've come across what you think is a bug, or just want to make
+a feature request open a ticket in the [issue queue](https://github.com/expressjs/express/issues).
+
+## Examples
+
+View dozens of Express application [examples](https://github.com/expressjs/express/tree/master/examples)
+in the repository covering everything from API design and authentication to template engine integration.
+
+## Github Discussions
+
+The [GitHub Discussions](https://github.com/expressjs/discussions) section is an excellent space to engage in conversations about the development and maintenance of Express, as well as to share ideas and discuss topics related to its usage.
+
+# Branding of Express.js
+
+## Express.js Logo
+
+Express is a project of the OpenJS Foundation. Please review the [trademark policy](https://trademark-policy.openjsf.org/) for information about permissible use of Express.js logos and marks.
+
+
diff --git a/astro/src/content/resources/ko/contributing.md b/astro/src/content/resources/ko/contributing.md
new file mode 100644
index 0000000000..82c6b8fed7
--- /dev/null
+++ b/astro/src/content/resources/ko/contributing.md
@@ -0,0 +1,482 @@
+---
+title: Contributing to Express
+description: Find out how to contribute to Express.js, including guidelines for reporting issues, submitting pull requests, becoming a collaborator, and understanding security policies.
+---
+
+# Contributing to Express
+
+### Looking to contribute to Expressjs.com? Click [here](#expressjs-website-contributing).
+
+Express and the other projects in the [expressjs organization on GitHub](https://github.com/expressjs) are projects of the [OpenJs Foundation](https://openjsf.org/).
+These projects are governed under the general policies and guidelines of the Node.js Foundation along with the additional guidelines below.
+
+- [Technical committee](#technical-committee)
+- [Community contributing guide](#community-contributing-guide)
+- [Collaborator's guide](#collaborators-guide)
+- [Security policies and procedures](#security-policies-and-procedures)
+
+## Technical committee
+
+The Express technical committee consists of active project members, and guides development and maintenance of the Express project. For more information, see [Express Community - Technical committee](/en/resources/community/#technical-committee).
+
+## Community contributing guide
+
+
+
+The goal of this document is to create a contribution process that:
+
+- Encourages new contributions.
+- Encourages contributors to remain involved.
+- Avoids unnecessary processes and bureaucracy whenever possible.
+- Creates a transparent decision making process that makes it clear how
+ contributors can be involved in decision making.
+
+### Vocabulary
+
+- A **Contributor** is any individual creating or commenting on an issue or pull request.
+- A **Committer** is a subset of contributors who have been given write access to the repository.
+- A **Project Captain** is the lead maintainer of a repository.
+- A **TC (Technical Committee)** is a group of committers representing the required technical
+ expertise to resolve rare disputes.
+- A **Triager** is a subset of contributors who have been given triage access to the repository.
+
+### Logging Issues
+
+Log an issue for any question or problem you might have. When in doubt, log an issue, and
+any additional policies about what to include will be provided in the responses. The only
+exception is security disclosures which should be sent privately.
+
+Committers may direct you to another repository, ask for additional clarifications, and
+add appropriate metadata before the issue is addressed.
+
+Please be courteous and respectful. Every participant is expected to follow the
+project's Code of Conduct.
+
+### Contributions
+
+Any change to resources in this repository must be through pull requests. This applies to all changes
+to documentation, code, binary files, etc. Even long term committers and TC members must use
+pull requests.
+
+No pull request can be merged without being reviewed.
+
+For non-trivial contributions, pull requests should sit for at least 36 hours to ensure that
+contributors in other timezones have time to review. Consideration should also be given to
+weekends and other holiday periods to ensure active committers all have reasonable time to
+become involved in the discussion and review process if they wish.
+
+The default for each contribution is that it is accepted once no committer has an objection.
+During a review, committers may also request that a specific contributor who is most versed in a
+particular area gives a "LGTM" before the PR can be merged. There is no additional "sign off"
+process for contributions to land. Once all issues brought by committers are addressed it can
+be landed by any committer.
+
+In the case of an objection being raised in a pull request by another committer, all involved
+committers should seek to arrive at a consensus by way of addressing concerns being expressed
+by discussion, compromise on the proposed change, or withdrawal of the proposed change.
+
+If a contribution is controversial and committers cannot agree about how to get it to land
+or if it should land then it should be escalated to the TC. TC members should regularly
+discuss pending contributions in order to find a resolution. It is expected that only a
+small minority of issues be brought to the TC for resolution and that discussion and
+compromise among committers be the default resolution mechanism.
+
+### Becoming a Triager
+
+Anyone can become a triager! Read more about the process of being a triager in
+[the triage process document](https://github.com/expressjs/discussions/blob/master/Triager-Guide.md).
+
+Currently, any existing [organization member](https://github.com/orgs/expressjs/people) can nominate
+a new triager. If you are interested in becoming a triager, our best advice is to actively participate
+in the community by helping triaging issues and pull requests. As well we recommend
+to engage in other community activities like attending the TC meetings, and participating in the Slack
+discussions. If you feel ready and have been helping triage some issues, reach out to an active member of the organization to ask if they'd
+be willing to support you. If they agree, they can create a pull request to formalize your nomination. In the case of an objection to the nomination, the triage team is responsible for working with the individuals involved and finding a resolution.
+
+You can also reach out to any of the [organization members](https://github.com/orgs/expressjs/people)
+if you have questions or need guidance.
+
+### Becoming a Committer
+
+All contributors who have landed significant and valuable contributions should be onboarded in a timely manner,
+and added as a committer, and be given write access to the repository.
+
+Committers are expected to follow this policy and continue to send pull requests, go through
+proper review, and have other committers merge their pull requests.
+
+### TC Process
+
+The TC uses a "consensus seeking" process for issues that are escalated to the TC.
+The group tries to find a resolution that has no open objections among TC members.
+If a consensus cannot be reached that has no objections then a majority wins vote
+is called. It is also expected that the majority of decisions made by the TC are via
+a consensus seeking process and that voting is only used as a last-resort.
+
+Resolution may involve returning the issue to project captains with suggestions on
+how to move forward towards a consensus. It is not expected that a meeting of the TC
+will resolve all issues on its agenda during that meeting and may prefer to continue
+the discussion happening among the project captains.
+
+Members can be added to the TC at any time. Any TC member can nominate another committer
+to the TC and the TC uses its standard consensus seeking process to evaluate whether or
+not to add this new member. The TC will consist of a minimum of 3 active members and a
+maximum of 10. If the TC should drop below 5 members the active TC members should nominate
+someone new. If a TC member is stepping down, they are encouraged (but not required) to
+nominate someone to take their place.
+
+TC members will be added as admin's on the Github orgs, npm orgs, and other resources as
+necessary to be effective in the role.
+
+To remain "active" a TC member should have participation within the last 12 months and miss
+no more than six consecutive TC meetings. Our goal is to increase participation, not punish
+people for any lack of participation, this guideline should be only be used as such
+(replace an inactive member with a new active one, for example). Members who do not meet this
+are expected to step down. If A TC member does not step down, an issue can be opened in the
+discussions repo to move them to inactive status. TC members who step down or are removed due
+to inactivity will be moved into inactive status.
+
+Inactive status members can become active members by self nomination if the TC is not already
+larger than the maximum of 10. They will also be given preference if, while at max size, an
+active member steps down.
+
+### Project Captains
+
+The Express TC can designate captains for individual projects/repos in the
+organizations. These captains are responsible for being the primary
+day-to-day maintainers of the repo on a technical and community front.
+Repo captains are empowered with repo ownership and package publication rights.
+When there are conflicts, especially on topics that effect the Express project
+at large, captains are responsible to raise it up to the TC and drive
+those conflicts to resolution. Captains are also responsible for making sure
+community members follow the community guidelines, maintaining the repo
+and the published package, as well as in providing user support.
+
+Like TC members, Repo captains are a subset of committers.
+
+To become a captain for a project the candidate is expected to participate in that
+project for at least 6 months as a committer prior to the request. They should have
+helped with code contributions as well as triaging issues. They are also required to
+have 2FA enabled on both their GitHub and npm accounts.
+
+Any TC member or an existing captain on the **same** repo can nominate another committer
+to the captain role. To do so, they should submit a PR to this document, updating the
+**Active Project Captains** section (while maintaining the sort order) with the project
+name, the nominee's GitHub handle, and their npm username (if different).
+
+- Repos can have as many captains as make sense for the scope of work.
+- A TC member or an existing repo captain **on the same project** can nominate a new captain.
+ Repo captains from other projects should not nominate captains for a different project.
+
+The PR will require at least 2 approvals from TC members and 2 weeks hold time to allow
+for comment and/or dissent. When the PR is merged, a TC member will add them to the
+proper GitHub/npm groups.
+
+#### Active Projects and Captains
+
+The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members)
+
+#### Current Initiative Captains
+
+The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains)
+
+### Inactivity and Emeritus Policy for Any Role
+
+To support the health and continuity of the project, all individuals holding a role within the community (such as Triager, Committer, WG member, Project Captain, or TC member) are encouraged to maintain active participation.
+
+Inactivity is defined as the absence of meaningful involvement in the project—such as contributions, code reviews, triage, meeting attendance, or discussion participation—for a continuous period of 6 months.
+
+#### Exceptions
+
+Anyone may request a temporary leave from active participation due to personal or professional reasons. In such cases, the individual should inform the relevant team or the Technical Committee (TC). During this time, the inactivity policy is paused, and the individual will not be flagged as inactive.
+
+#### Inactivity Process
+
+- If someone is deemed inactive, the individual may be transitioned to an emeritus role that reflects their past contributions. A best effort will be made to inform them that this has occurred. They may request to be reinstated when they are ready to be active again.
+- The emeritus status helps preserve a clear record of contributors who have meaningfully shaped the project over time.
+
+#### Accountability
+
+- The Technical Committee (TC) and the respective captains of each package/team are responsible for assessing activity levels and enacting this policy fairly and transparently, in coordination with other relevant teams.
+- In case of disagreement, the situation can be discussed and resolved by consensus within the TC or appropriate team.
+
+### Developer's Certificate of Origin 1.1
+
+```text
+By making a contribution to this project, I certify that:
+
+ (a) The contribution was created in whole or in part by me and I
+ have the right to submit it under the open source license
+ indicated in the file; or
+
+ (b) The contribution is based upon previous work that, to the best
+ of my knowledge, is covered under an appropriate open source
+ license and I have the right under that license to submit that
+ work with modifications, whether created in whole or in part
+ by me, under the same open source license (unless I am
+ permitted to submit under a different license), as indicated
+ in the file; or
+
+ (c) The contribution was provided directly to me by some other
+ person who certified (a), (b) or (c) and I have not modified
+ it.
+
+ (d) I understand and agree that this project and the contribution
+ are public and that a record of the contribution (including all
+ personal information I submit with it, including my sign-off) is
+ maintained indefinitely and may be redistributed consistent with
+ this project or the open source license(s) involved.
+```
+
+## Collaborator's guide
+
+
+
+### Website Issues
+
+Open issues for the expressjs.com website in https://github.com/expressjs/expressjs.com.
+
+For issues in other Express managed repos (everything in `expressjs`, `pillarjs` or `jshttp` other than `expressjs/express`), be sure to check their contributing guide and open issues and PRs in the appropriate repository.
+
+### PRs and Code contributions
+
+- Tests must pass.
+- Follow the [JavaScript Standard Style](https://standardjs.com/) and `npm run lint`.
+- If you fix a bug, add a test.
+
+### Branches
+
+Use the `master` branch for bug fixes or minor work that is intended for the
+current release stream.
+
+Use the correspondingly named branch, e.g. `6.x`, for anything intended for
+a future release of Express.
+
+### Steps for contributing
+
+1. Create an issue for the
+ bug you want to fix or the feature that you want to add.
+2. Create your own fork on GitHub, then
+ checkout your fork.
+3. Write your code in your local copy. It's good practice to create a branch for
+ each new issue you work on, although not compulsory.
+4. To run the test suite, first install the dependencies by running `npm install`,
+ then run `npm test`.
+5. Ensure your code is linted by running `npm run lint` -- fix any issue you
+ see listed.
+6. If the tests pass, you can commit your changes to your fork and then create
+ a pull request from there. Make sure to reference your issue from the pull
+ request comments by including the issue number e.g. `#123`.
+
+### Issues which are questions
+
+We will typically close any vague issues or questions that are specific to some
+app you are writing. Please double check the docs and other references before
+being trigger happy with posting a question issue.
+
+Things that will help get your question issue looked at:
+
+- Full and runnable JS code.
+- Clear description of the problem or unexpected behavior.
+- Clear description of the expected result.
+- Steps you have taken to debug it yourself.
+
+If you post a question and do not outline the above items or make it easy for
+us to understand and reproduce your issue, it will be closed.
+
+If your question meets all of the above requirements but you do not believe it needs to be looked at
+by the maintainers
+(for example, if you are just looking for community input) please open it as a discussion topic instead
+of an issue. If you
+are unsure and open an issue, we may move it to discussions if we triage them and decide they do
+not need high
+visibility or maintainer input.
+
+## Security Policies and Procedures
+
+
+
+This document outlines security procedures and general policies for the Express
+project.
+
+- [Reporting a Bug](#reporting-a-bug)
+- [Disclosure Policy](#disclosure-policy)
+- [Comments on this Policy](#comments-on-this-policy)
+
+### Reporting a Bug
+
+The Express team and community take all security bugs in Express seriously.
+Thank you for improving the security of Express. We appreciate your efforts and
+responsible disclosure and will make every effort to acknowledge your
+contributions.
+
+Report security bugs by emailing `express-security@lists.openjsf.org`.
+
+To ensure the timely response to your report, please ensure that the entirety
+of the report is contained within the email body and not solely behind a web
+link or an attachment.
+
+The lead maintainer will acknowledge your email within 48 hours, and will send a
+more detailed response within 48 hours indicating the next steps in handling
+your report. After the initial reply to your report, the security team will
+endeavor to keep you informed of the progress towards a fix and full
+announcement, and may ask for additional information or guidance.
+
+Report security bugs in third-party modules to the person or team maintaining
+the module.
+
+### Pre-release Versions
+
+Alpha and Beta releases are unstable and **not suitable for production use**.
+Vulnerabilities found in pre-releases should be reported according to the [Reporting a Bug](#reporting-a-bug) section.
+Due to the unstable nature of the branch it is not guaranteed that any fixes will be released in the next pre-release.
+
+### Disclosure Policy
+
+When the security team receives a security bug report, they will assign it to a
+primary handler. This person will coordinate the fix and release process,
+involving the following steps:
+
+- Confirm the problem and determine the affected versions.
+- Audit code to find any potential similar problems.
+- Prepare fixes for all releases still under maintenance. These fixes will be
+ released as fast as possible to npm.
+
+### The Express Threat Model
+
+We are currently working on a new version of the security model, the most updated version can be found [here](https://github.com/expressjs/security-wg/blob/main/docs/ThreatModel.md)
+
+### Comments on this Policy
+
+If you have suggestions on how this process could be improved please submit a
+pull request.
+
+---
+
+# Contributing to Expressjs.com {#expressjs-website-contributing}
+
+
+
+### The Official Documentation of the Express.js Framework
+
+This is the contribution documentation for the [expressjs.com](https://github.com/expressjs/expressjs.com) website.
+
+#### Need some ideas? These are some typical issues.
+
+1. **Website issues**: If you see anything on the site that could use a tune-up, think about how to fix it.
+ - Display or screen sizing problems
+ - Mobile responsiveness issues
+ - Missing or broken accessibility features
+ - Website outages
+ - Broken links
+ - Page structure or user interface enhancements
+
+2. **Content Issues**: Fix anything related to site content or typos.
+ - Spelling errors
+ - Incorrect/outdated Express.js documentation
+ - Missing content
+
+3. **Translation Issues**: Fix any translation errors or contribute new content.
+ - Fix spelling errors
+ - Fix incorrect/poorly translated words
+ - Check out the [Contributing translations](#contributing-translations) section below for a contributing guide.
+
+#### Want to work on a backlog issue?
+
+We often have bugs or enhancements that need work. You can find these under our repo's [Issues tab](https://github.com/expressjs/expressjs.com/issues). Check out the tags to find something that's a good match for you.
+
+#### Have an idea? Found a bug?
+
+If you've found a bug or a typo, or if you have an idea for an enhancement, you can:
+
+- Submit a [new issue](https://github.com/expressjs/expressjs.com/issues/new/choose) on our repo. Do this for larger proposals, or if you'd like to discuss or get feedback first.
+
+- Make a [GitHub pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). If you have already done work, and it's ready to go, feel free to send it our way.
+
+## Getting Started
+
+The steps below will guide you through the Expressjs.com contribution process.
+
+#### Step 1: (OPTIONAL) Open a New Issue
+
+So you've found a problem that you want to fix, or have a site enhancement you want to make.
+
+1. If you want to get feedback or discuss, open a discussion [issue](https://github.com/expressjs/expressjs.com/issues/new/choose) prior to starting work. This is not required, but encouraged for larger proposals.
+ - While we highly encourage this step, it is only for submissions proposing significant change. It helps us to clarify and focus the work, and ensure it aligns with overall project priorities.
+ - For submissions proposing minor improvements or corrections, this is not needed. You can skip this step.
+ - When opening an issue please give it a title and fill in the description section. The more details you provide, the more feedback we can give.
+
+2. After receiving your issue the Express.js documentation team will respond with feedback. We read every submission and always try to respond quickly with feedback.
+ - For submissions proposing significant change, we encourage you to follow the review process before starting work.
+
+#### Step 2: Get the Application Code Base
+
+Clone the repo and get the code:
+
+```sh
+git clone https://github.com/expressjs/expressjs.com.git
+```
+
+After you've got the code you're ready to start making your changes!
+
+But just in case you need a little extra explanation, this section below outlines the main sections of the code base, where most changes are likely to be made.
+
+**Markdown Page Files**:
+
+- These files render to html and make up the individual pages of the site. Most of the site's documentation text content is written in `md` files.
+- Change these to make changes to individual pages' content/text or markup.
+- Each language has its own complete set of pages, located under their respective language directories - all the Spanish markdown content is found in the `es` directory, for example.
+
+**Includes Partials and Layout Templates**
+
+- `_includes` are partials that are imported and reused across multiple pages.
+ - These are used to import text content for reuse across pages, such as the API documentation, e.g., `_includes > api > en > 5x`, which is included in every language.
+ - These are used to include the page components that make up site-wide user interface and periphery structure, e.g., Header, Footer, etc.
+- `_layouts` are the templates used to wrap the site's individual pages.
+ - These are used to display the structure of the site's periphery, such as the header and footer, and for injecting and displaying individual markdown pages inside the `content` tag.
+
+**Blog Markdown Files**
+
+- These files make up the individual blog posts. If you want to contribute a blog post please
+ follow the specific instructions for [How to write a blog post.](https://expressjs.com/en/blog/write-post)
+- Located under the `_posts` directory.
+
+**CSS or Javascript**
+
+- All css and js files are kept in `css` and `js` folders on the project root.
+
+The Express.js website is built using [Jekyll](https://jekyllrb.com/) and is hosted on [GitHub Pages](https://pages.github.com/).
+
+#### Step 3: Running the Application
+
+Now you'll need a way to see your changes, which means you'll need a running version of the application. You have two options.
+
+1. **Run Locally**: This gets the local version of the application up and running on your machine. Follow our [Local Setup Guide](https://github.com/expressjs/expressjs.com?tab=readme-ov-file#build-the-website-locally) to use this option.
+ - This is the recommended option for moderate to complex work.
+
+2. **Run using Deploy Preview**: Use this option if you don't want to bother with a local installation. Part of our continuous integration pipeline includes [Netlify Deploy Preview](https://docs.netlify.com/deploy/deploy-types/deploy-previews/).
+ 1. To use this you'll need to get your changes online - after you've made your first commit on your feature branch, make a _draft_ pull request.
+ 2. After the build steps are complete, you'll have access to a **Deploy Preview** tab that will run your changes on the web, rebuilding after each commit is pushed.
+ 3. After you are completely done your work, and it's ready for review, remove the draft status on your pull request and submit your work.
+
+## Contributing translations
+
+We use Crowdin to manage our translations in multiple languages and achieve automatic translation with artificial intelligence. Since these translations can be inefficient in some cases, we need help from the community to provide accurate and helpful translations.
+
+The documentation is translated into these languages:
+
+- Chinese Simplified (`zh-cn`)
+- Chinese Traditional (`zh-tw`)
+- English (`en`)
+- French (`fr`)
+- German (`de`)
+- Italian (`it`)
+- Japanese (`ja`)
+- Korean (`ko`)
+- Brazilian Portuguese (`pt-br`)
+- Spanish (`es`)
+
+### How to translate
+
+1. Request to join the Express.js Website project on [Crowdin](https://express.crowdin.com/website)
+2. [Select the language you want to translate](https://support.crowdin.com/for-translators/#starting-translation)
+3. [Start translating](https://support.crowdin.com/online-editor/)
diff --git a/astro/src/content/resources/ko/glossary.md b/astro/src/content/resources/ko/glossary.md
new file mode 100755
index 0000000000..8b45bf01eb
--- /dev/null
+++ b/astro/src/content/resources/ko/glossary.md
@@ -0,0 +1,62 @@
+---
+title: Express glossary
+description: A comprehensive glossary of terms related to Express.js, Node.js, middleware, routing, and other key concepts to help you understand and use Express effectively.
+---
+
+# Glossary
+
+### application
+
+In general, one or more programs that are designed to carry out operations for a specific purpose. In the context of Express, a program that uses the Express API running on the Node.js platform. Might also refer to an [app object](/en/api#express).
+
+### API
+
+Application programming interface. Spell out the abbreviation when it is first used.
+
+### Express
+
+A fast, un-opinionated, minimalist web framework for Node.js applications. In general, "Express" is preferred to "Express.js," though the latter is acceptable.
+
+### libuv
+
+A multi-platform support library which focuses on asynchronous I/O, primarily developed for use by Node.js.
+
+### middleware
+
+A function that is invoked by the Express routing layer before the final request handler, and thus sits in the middle between a raw request and the final intended route. A few fine points of terminology around middleware:
+
+- `var foo = require('middleware')` is called _requiring_ or _using_ a Node.js module. Then the statement `var mw = foo()` typically returns the middleware.
+- `app.use(mw)` is called _adding the middleware to the global processing stack_.
+- `app.get('/foo', mw, function (req, res) { ... })` is called _adding the middleware to the "GET /foo" processing stack_.
+
+### Node.js
+
+A software platform that is used to build scalable network applications. Node.js uses JavaScript as its scripting language, and achieves high throughput via non-blocking I/O and a single-threaded event loop. See [nodejs.org](https://nodejs.org/en/). **Usage note**: Initially, "Node.js," thereafter "Node".
+
+### open-source, open source
+
+When used as an adjective, hyphenate; for example: "This is open-source software." See [Open-source software on Wikipedia](http://en.wikipedia.org/wiki/Open-source_software).
+
+{% capture english-rules %}
+
+Although it is common not to hyphenate this term, we are using the standard English rules for hyphenating a compound adjective.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=english-rules %}
+
+### request
+
+An HTTP request. A client submits an HTTP request message to a server, which returns a response. The request must use one of several [request methods](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods) such as GET, POST, and so on.
+
+### response
+
+An HTTP response. A server returns an HTTP response message to the client. The response contains completion status information about the request and might also contain requested content in its message body.
+
+### route
+
+Part of a URL that identifies a resource. For example, in `http://foo.com/products/id`, "/products/id" is the route.
+
+### router
+
+See [router](/en/api#router) in the API reference.
diff --git a/astro/src/content/resources/ko/middleware/body-parser.md b/astro/src/content/resources/ko/middleware/body-parser.md
new file mode 100644
index 0000000000..e82649a95c
--- /dev/null
+++ b/astro/src/content/resources/ko/middleware/body-parser.md
@@ -0,0 +1,498 @@
+---
+title: Express body-parser middleware
+module: body-parser
+---
+
+# body-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+
+Node.js body parsing middleware.
+
+Parse incoming request bodies in a middleware before your handlers, available
+under the `req.body` property.
+
+**Note** As `req.body`'s shape is based on user-controlled input, all
+properties and values in this object are untrusted and should be validated
+before trusting. For example, `req.body.foo.toString()` may fail in multiple
+ways, for example the `foo` property may not be there or may not be a string,
+and `toString` may not be a function and instead a string or other user input.
+
+[Learn about the anatomy of an HTTP transaction in Node.js](https://nodejs.org/en/learn/http/anatomy-of-an-http-transaction).
+
+_This does not handle multipart bodies_, due to their complex and typically
+large nature. For multipart bodies, you may be interested in the following
+modules:
+
+- [busboy](https://www.npmjs.com/package/busboy#readme) and
+ [connect-busboy](https://www.npmjs.com/package/connect-busboy#readme)
+- [multiparty](https://www.npmjs.com/package/multiparty#readme) and
+ [connect-multiparty](https://www.npmjs.com/package/connect-multiparty#readme)
+- [formidable](https://www.npmjs.com/package/formidable#readme)
+- [multer](https://www.npmjs.com/package/multer#readme)
+
+This module provides the following parsers:
+
+- [JSON body parser](#bodyparserjsonoptions)
+- [Raw body parser](#bodyparserrawoptions)
+- [Text body parser](#bodyparsertextoptions)
+- [URL-encoded form body parser](#bodyparserurlencodedoptions)
+
+Other body parsers you might be interested in:
+
+- [body](https://www.npmjs.com/package/body#readme)
+- [co-body](https://www.npmjs.com/package/co-body#readme)
+
+## Installation
+
+```sh
+$ npm install body-parser
+```
+
+## API
+
+```js
+const bodyParser = require('body-parser');
+```
+
+The `bodyParser` object exposes various factories to create middlewares. All
+middlewares will populate the `req.body` property with the parsed body when
+the `Content-Type` request header matches the `type` option.
+
+The various errors returned by this module are described in the
+[errors section](#errors).
+
+### bodyParser.json([options])
+
+Returns middleware that only parses `json` and only looks at requests where
+the `Content-Type` header matches the `type` option. This parser accepts any
+Unicode encoding of the body and supports automatic inflation of `gzip`,
+`br` (brotli) and `deflate` encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`).
+
+#### Options
+
+The `json` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### defaultCharset
+
+Specify the default character set for the json content if the charset is not
+specified in the `Content-Type` header of the request. Defaults to `utf-8`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### reviver
+
+The `reviver` option is passed directly to `JSON.parse` as the second
+argument. You can find more information on this argument
+[in the MDN documentation about JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Example.3A_Using_the_reviver_parameter).
+
+##### strict
+
+When set to `true`, will only accept arrays and objects; when `false` will
+accept anything `JSON.parse` accepts. Defaults to `true`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not a
+function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `json`), a mime type (like `application/json`), or
+a mime type with a wildcard (like `*/*` or `*/json`). If a function, the `type`
+option is called as `fn(req)` and the request is parsed if it returns a truthy
+value. Defaults to `application/json`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.raw([options])
+
+Returns middleware that parses all bodies as a `Buffer` and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser supports automatic inflation of `gzip`, `br` (brotli) and `deflate`
+encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This will be a `Buffer` object
+of the body.
+
+#### Options
+
+The `raw` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function.
+If not a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this
+can be an extension name (like `bin`), a mime type (like
+`application/octet-stream`), or a mime type with a wildcard (like `*/*` or
+`application/*`). If a function, the `type` option is called as `fn(req)`
+and the request is parsed if it returns a truthy value. Defaults to
+`application/octet-stream`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.text([options])
+
+Returns middleware that parses all bodies as a string and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser supports automatic inflation of `gzip`, `br` (brotli) and `deflate`
+encodings.
+
+A new `body` string containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This will be a string of the
+body.
+
+#### Options
+
+The `text` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### defaultCharset
+
+Specify the default character set for the text content if the charset is not
+specified in the `Content-Type` header of the request. Defaults to `utf-8`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not
+a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `txt`), a mime type (like `text/plain`), or a mime
+type with a wildcard (like `*/*` or `text/*`). If a function, the `type`
+option is called as `fn(req)` and the request is parsed if it returns a
+truthy value. Defaults to `text/plain`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.urlencoded([options])
+
+Returns middleware that only parses `urlencoded` bodies and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser accepts only UTF-8 encoding of the body and supports automatic
+inflation of `gzip`, `br` (brotli) and `deflate` encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This object will contain
+key-value pairs, where the value can be a string or array (when `extended` is
+`false`), or any type (when `extended` is `true`).
+
+#### Options
+
+The `urlencoded` function takes an optional `options` object that may contain
+any of the following keys:
+
+##### extended
+
+The "extended" syntax allows for rich objects and arrays to be encoded into the
+URL-encoded format, allowing for a JSON-like experience with URL-encoded. For
+more information, please [see the qs
+library](https://www.npmjs.com/package/qs#readme).
+
+Defaults to `false`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### parameterLimit
+
+The `parameterLimit` option controls the maximum number of parameters that
+are allowed in the URL-encoded data. If a request contains more parameters
+than this value, a 413 will be returned to the client. Defaults to `1000`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not
+a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `urlencoded`), a mime type (like
+`application/x-www-form-urlencoded`), or a mime type with a wildcard (like
+`*/x-www-form-urlencoded`). If a function, the `type` option is called as
+`fn(req)` and the request is parsed if it returns a truthy value. Defaults
+to `application/x-www-form-urlencoded`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+##### defaultCharset
+
+The default charset to parse as, if not specified in content-type. Must be
+either `utf-8` or `iso-8859-1`. Defaults to `utf-8`.
+
+##### charsetSentinel
+
+Whether to let the value of the `utf8` parameter take precedence as the charset
+selector. It requires the form to contain a parameter named `utf8` with a value
+of `✓`. Defaults to `false`.
+
+##### interpretNumericEntities
+
+Whether to decode numeric entities such as `☺` when parsing an iso-8859-1
+form. Defaults to `false`.
+
+##### depth
+
+The `depth` option is used to configure the maximum depth of the `qs` library when `extended` is `true`. This allows you to limit the amount of keys that are parsed and can be useful to prevent certain types of abuse. Defaults to `32`. It is recommended to keep this value as low as possible.
+
+## Errors
+
+The middlewares provided by this module create errors using the
+[`http-errors` module](https://www.npmjs.com/package/http-errors). The errors
+will typically have a `status`/`statusCode` property that contains the suggested
+HTTP response code, an `expose` property to determine if the `message` property
+should be displayed to the client, a `type` property to determine the type of
+error without matching against the `message`, and a `body` property containing
+the read body, if available.
+
+The following are the common errors created, though any error can come through
+for various reasons.
+
+### content encoding unsupported
+
+This error will occur when the request had a `Content-Encoding` header that
+contained an encoding but the "inflation" option was set to `false`. The
+`status` property is set to `415`, the `type` property is set to
+`'encoding.unsupported'`, and the `charset` property will be set to the
+encoding that is unsupported.
+
+### entity parse failed
+
+This error will occur when the request contained an entity that could not be
+parsed by the middleware. The `status` property is set to `400`, the `type`
+property is set to `'entity.parse.failed'`, and the `body` property is set to
+the entity value that failed parsing.
+
+### entity verify failed
+
+This error will occur when the request contained an entity that could not be
+failed verification by the defined `verify` option. The `status` property is
+set to `403`, the `type` property is set to `'entity.verify.failed'`, and the
+`body` property is set to the entity value that failed verification.
+
+### request aborted
+
+This error will occur when the request is aborted by the client before reading
+the body has finished. The `received` property will be set to the number of
+bytes received before the request was aborted and the `expected` property is
+set to the number of expected bytes. The `status` property is set to `400`
+and `type` property is set to `'request.aborted'`.
+
+### request entity too large
+
+This error will occur when the request body's size is larger than the "limit"
+option. The `limit` property will be set to the byte limit and the `length`
+property will be set to the request body's length. The `status` property is
+set to `413` and the `type` property is set to `'entity.too.large'`.
+
+### request size did not match content length
+
+This error will occur when the request's length did not match the length from
+the `Content-Length` header. This typically occurs when the request is malformed,
+typically when the `Content-Length` header was calculated based on characters
+instead of bytes. The `status` property is set to `400` and the `type` property
+is set to `'request.size.invalid'`.
+
+### stream encoding should not be set
+
+This error will occur when something called the `req.setEncoding` method prior
+to this middleware. This module operates directly on bytes only and you cannot
+call `req.setEncoding` when using this module. The `status` property is set to
+`500` and the `type` property is set to `'stream.encoding.set'`.
+
+### stream is not readable
+
+This error will occur when the request is no longer readable when this middleware
+attempts to read it. This typically means something other than a middleware from
+this module read the request body already and the middleware was also configured to
+read the same request. The `status` property is set to `500` and the `type`
+property is set to `'stream.not.readable'`.
+
+### too many parameters
+
+This error will occur when the content of the request exceeds the configured
+`parameterLimit` for the `urlencoded` parser. The `status` property is set to
+`413` and the `type` property is set to `'parameters.too.many'`.
+
+### unsupported charset "BOGUS"
+
+This error will occur when the request had a charset parameter in the
+`Content-Type` header, but the `iconv-lite` module does not support it OR the
+parser does not support it. The charset is contained in the message as well
+as in the `charset` property. The `status` property is set to `415`, the
+`type` property is set to `'charset.unsupported'`, and the `charset` property
+is set to the charset that is unsupported.
+
+### unsupported content encoding "bogus"
+
+This error will occur when the request had a `Content-Encoding` header that
+contained an unsupported encoding. The encoding is contained in the message
+as well as in the `encoding` property. The `status` property is set to `415`,
+the `type` property is set to `'encoding.unsupported'`, and the `encoding`
+property is set to the encoding that is unsupported.
+
+### The input exceeded the depth
+
+This error occurs when using `bodyParser.urlencoded` with the `extended` property set to `true` and the input exceeds the configured `depth` option. The `status` property is set to `400`. It is recommended to review the `depth` option and evaluate if it requires a higher value. When the `depth` option is set to `32` (default value), the error will not be thrown.
+
+## Examples
+
+### Express/Connect top-level generic
+
+This example demonstrates adding a generic JSON and URL-encoded parser as a
+top-level middleware, which will parse the bodies of all incoming requests.
+This is the simplest setup.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// parse application/x-www-form-urlencoded
+app.use(bodyParser.urlencoded());
+
+// parse application/json
+app.use(bodyParser.json());
+
+app.use(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.write('you posted:\n');
+ res.end(String(JSON.stringify(req.body, null, 2)));
+});
+```
+
+### Express route-specific
+
+This example demonstrates adding body parsers specifically to the routes that
+need them. In general, this is the most recommended way to use body-parser with
+Express.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// create application/json parser
+const jsonParser = bodyParser.json();
+
+// create application/x-www-form-urlencoded parser
+const urlencodedParser = bodyParser.urlencoded();
+
+// POST /login gets urlencoded bodies
+app.post('/login', urlencodedParser, function (req, res) {
+ if (!req.body || !req.body.username) res.sendStatus(400);
+ res.send('welcome, ' + req.body.username);
+});
+
+// POST /api/users gets JSON bodies
+app.post('/api/users', jsonParser, function (req, res) {
+ if (!req.body) res.sendStatus(400);
+ // create user in req.body
+});
+```
+
+### Change accepted type for parsers
+
+All the parsers accept a `type` option which allows you to change the
+`Content-Type` that the middleware will parse.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// parse various different custom JSON types as JSON
+app.use(bodyParser.json({ type: 'application/*+json' }));
+
+// parse some custom thing into a Buffer
+app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }));
+
+// parse an HTML body into a string
+app.use(bodyParser.text({ type: 'text/html' }));
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/body-parser/ci.yml?branch=master&label=ci
+[ci-url]: https://github.com/expressjs/body-parser/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coverallsCoverage/github/expressjs/body-parser?branch=master
+[coveralls-url]: https://coveralls.io/r/expressjs/body-parser?branch=master
+[npm-downloads-image]: https://img.shields.io/npm/dm/body-parser
+[npm-url]: https://npmjs.com/package/body-parser
+[npm-version-image]: https://img.shields.io/npm/v/body-parser
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/body-parser/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/body-parser
diff --git a/astro/src/content/resources/ko/middleware/compression.md b/astro/src/content/resources/ko/middleware/compression.md
new file mode 100644
index 0000000000..6ac63fcb7a
--- /dev/null
+++ b/astro/src/content/resources/ko/middleware/compression.md
@@ -0,0 +1,314 @@
+---
+title: Express compression middleware
+module: compression
+---
+
+# compression
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+[![Funding][funding-image]][funding-url]
+
+Node.js compression middleware.
+
+The following compression codings are supported:
+
+- deflate
+- gzip
+- br (brotli)
+
+**Note** Brotli is supported only since Node.js versions v11.7.0 and v10.16.0.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```bash
+$ npm install compression
+```
+
+## API
+
+```js
+var compression = require('compression');
+```
+
+### compression([options])
+
+Returns the compression middleware using the given `options`. The middleware
+will attempt to compress response bodies for all requests that traverse through
+the middleware, based on the given `options`.
+
+This middleware will never compress responses that include a `Cache-Control`
+header with the [`no-transform` directive](https://tools.ietf.org/html/rfc7234#section-5.2.2.4),
+as compressing will transform the body.
+
+#### Options
+
+`compression()` accepts these properties in the options object. In addition to
+those listed below, [zlib](https://nodejs.org/api/zlib.html) options may be
+passed in to the options object or
+[brotli](https://nodejs.org/api/zlib.html#zlib_class_brotlioptions) options.
+
+##### chunkSize
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_CHUNK`, or `16384`.
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### filter
+
+Type: `Function`
+
+A function to decide if the response should be considered for compression.
+This function is called as `filter(req, res)` and is expected to return
+`true` to consider the response for compression, or `false` to not compress
+the response.
+
+The default filter function uses the [compressible](https://www.npmjs.com/package/compressible)
+module to determine if `res.getHeader('Content-Type')` is compressible.
+
+##### level
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_COMPRESSION`, or `-1`
+
+The level of zlib compression to apply to responses. A higher level will result
+in better compression, but will take longer to complete. A lower level will
+result in less compression, but will be much faster.
+
+This is an integer in the range of `0` (no compression) to `9` (maximum
+compression). The special value `-1` can be used to mean the "default
+compression level", which is a default compromise between speed and
+compression (currently equivalent to level 6).
+
+- `-1` Default compression level (also `zlib.constants.Z_DEFAULT_COMPRESSION`).
+- `0` No compression (also `zlib.constants.Z_NO_COMPRESSION`).
+- `1` Fastest compression (also `zlib.constants.Z_BEST_SPEED`).
+- `2`
+- `3`
+- `4`
+- `5`
+- `6` (currently what `zlib.constants.Z_DEFAULT_COMPRESSION` points to).
+- `7`
+- `8`
+- `9` Best compression (also `zlib.constants.Z_BEST_COMPRESSION`).
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### memLevel
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_MEMLEVEL`, or `8`
+
+This specifies how much memory should be allocated for the internal compression
+state and is an integer in the range of `1` (minimum level) and `9` (maximum
+level).
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### brotli
+
+Type: `Object`
+
+This specifies the options for configuring Brotli. See [Node.js documentation](https://nodejs.org/api/zlib.html#class-brotlioptions) for a complete list of available options.
+
+##### strategy
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_STRATEGY`
+
+This is used to tune the compression algorithm. This value only affects the
+compression ratio, not the correctness of the compressed output, even if it
+is not set appropriately.
+
+- `zlib.constants.Z_DEFAULT_STRATEGY` Use for normal data.
+- `zlib.constants.Z_FILTERED` Use for data produced by a filter (or predictor).
+ Filtered data consists mostly of small values with a somewhat random
+ distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect is to force more Huffman coding and less
+ string matching; it is somewhat intermediate between `zlib.constants.Z_DEFAULT_STRATEGY`
+ and `zlib.constants.Z_HUFFMAN_ONLY`.
+- `zlib.constants.Z_FIXED` Use to prevent the use of dynamic Huffman codes, allowing
+ for a simpler decoder for special applications.
+- `zlib.constants.Z_HUFFMAN_ONLY` Use to force Huffman encoding only (no string match).
+- `zlib.constants.Z_RLE` Use to limit match distances to one (run-length encoding).
+ This is designed to be almost as fast as `zlib.constants.Z_HUFFMAN_ONLY`, but give
+ better compression for PNG image data.
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### threshold
+
+Type: `Number` or `String`
+Default: `1kb`
+
+The byte threshold for the response body size before compression is considered
+for the response. This is a number of bytes or any string
+accepted by the [bytes](https://www.npmjs.com/package/bytes) module.
+
+**Note** this is only an advisory setting; if the response size cannot be determined
+at the time the response headers are written, then it is assumed the response is
+_over_ the threshold. To guarantee the response size can be determined, be sure
+set a `Content-Length` response header.
+
+##### windowBits
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_WINDOWBITS`, or `15`
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### enforceEncoding
+
+Type: `String`
+Default: `identity`
+
+This is the default encoding to use when the client does not specify an encoding in the request's [Accept-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) header.
+
+#### .filter
+
+The default `filter` function. This is used to construct a custom filter
+function that is an extension of the default function.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+app.use(compression({ filter: shouldCompress }));
+
+function shouldCompress(req, res) {
+ if (req.headers['x-no-compression']) {
+ // don't compress responses with this request header
+ return false;
+ }
+
+ // fallback to standard filter function
+ return compression.filter(req, res);
+}
+```
+
+### res.flush
+
+This module adds a `res.flush()` method to force the partially-compressed
+response to be flushed to the client.
+
+## Examples
+
+### express
+
+When using this module with express, simply `app.use` the module as
+high as you like. Requests that pass through the middleware will be compressed.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress all responses
+app.use(compression());
+
+// add all routes
+```
+
+### Node.js HTTP server
+
+```js
+var compression = require('compression')({ threshold: 0 });
+var http = require('http');
+
+function createServer(fn) {
+ return http.createServer(function (req, res) {
+ compression(req, res, function (err) {
+ if (err) {
+ res.statusCode = err.status || 500;
+ res.end(err.message);
+ return;
+ }
+
+ fn(req, res);
+ });
+ });
+}
+
+var server = createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello world!');
+});
+
+server.listen(3000, () => {
+ console.log('> Listening at http://localhost:3000');
+});
+```
+
+### Server-Sent Events
+
+Because of the nature of compression this module does not work out of the box
+with server-sent events. To compress content, a window of the output needs to
+be buffered up in order to get good compression. Typically when using server-sent
+events, there are certain block of data that need to reach the client.
+
+You can achieve this by calling `res.flush()` when you need the data written to
+actually make it to the client.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress responses
+app.use(compression());
+
+// server-sent event stream
+app.get('/events', function (req, res) {
+ res.setHeader('Content-Type', 'text/event-stream');
+ res.setHeader('Cache-Control', 'no-cache');
+
+ // send a ping approx every 2 seconds
+ var timer = setInterval(function () {
+ res.write('data: ping\n\n');
+
+ // !!! this is the important part
+ res.flush();
+ }, 2000);
+
+ res.on('close', function () {
+ clearInterval(timer);
+ });
+});
+```
+
+## Contributing
+
+The Express.js project welcomes all constructive contributions. Contributions take many forms,
+from code for bug fixes and enhancements, to additions and fixes to documentation, additional
+tests, triaging incoming pull requests and issues, and more!
+
+See the [Contributing Guide](https://github.com/expressjs/express/blob/master/Contributing.md) for more technical details on contributing.
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://badgen.net/npm/v/compression
+[npm-url]: https://npmjs.org/package/compression
+[downloads-image]: https://badgen.net/npm/dm/compression
+[downloads-url]: https://npmcharts.com/compare/compression?minimal=true
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/compression/master?label=CI
+[github-actions-ci-url]: https://github.com/expressjs/compression/actions?query=workflow%3Aci
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/compression/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/compression
+[funding-url]: https://opencollective.com/express
+[funding-image]: https://badgen.net/badge/icon/sponsor/pink?icon=github&label=Open%20Collective
diff --git a/astro/src/content/resources/ko/middleware/cookie-parser.md b/astro/src/content/resources/ko/middleware/cookie-parser.md
new file mode 100644
index 0000000000..2a59496387
--- /dev/null
+++ b/astro/src/content/resources/ko/middleware/cookie-parser.md
@@ -0,0 +1,124 @@
+---
+title: Express cookie-parser middleware
+module: cookie-parser
+---
+
+# cookie-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Parse `Cookie` header and populate `req.cookies` with an object keyed by the
+cookie names. Optionally you may enable signed cookie support by passing a
+`secret` string, which assigns `req.secret` so it may be used by other
+middleware.
+
+## Installation
+
+```sh
+$ npm install cookie-parser
+```
+
+## API
+
+```js
+var cookieParser = require('cookie-parser');
+```
+
+### cookieParser(secret, options)
+
+Create a new cookie parser middleware function using the given `secret` and
+`options`.
+
+- `secret` a string or array used for signing cookies. This is optional and if
+ not specified, will not parse signed cookies. If a string is provided, this
+ is used as the secret. If an array is provided, an attempt will be made to
+ unsign the cookie with each secret in order.
+- `options` an object that is passed to `cookie.parse` as the second option. See
+ [cookie](https://www.npmjs.org/package/cookie) for more information.
+ - `decode` a function to decode the value of the cookie
+
+The middleware will parse the `Cookie` header on the request and expose the
+cookie data as the property `req.cookies` and, if a `secret` was provided, as
+the property `req.signedCookies`. These properties are name value pairs of the
+cookie name to cookie value.
+
+When `secret` is provided, this module will unsign and validate any signed cookie
+values and move those name value pairs from `req.cookies` into `req.signedCookies`.
+A signed cookie is a cookie that has a value prefixed with `s:`. Signed cookies
+that fail signature validation will have the value `false` instead of the tampered
+value.
+
+In addition, this module supports special "JSON cookies". These are cookie where
+the value is prefixed with `j:`. When these values are encountered, the value will
+be exposed as the result of `JSON.parse`. If parsing fails, the original value will
+remain.
+
+### cookieParser.JSONCookie(str)
+
+Parse a cookie value as a JSON cookie. This will return the parsed JSON value
+if it was a JSON cookie, otherwise, it will return the passed value.
+
+### cookieParser.JSONCookies(cookies)
+
+Given an object, this will iterate over the keys and call `JSONCookie` on each
+value, replacing the original value with the parsed value. This returns the
+same object that was passed in.
+
+### cookieParser.signedCookie(str, secret)
+
+Parse a cookie value as a signed cookie. This will return the parsed unsigned
+value if it was a signed cookie and the signature was valid. If the value was
+not signed, the original value is returned. If the value was signed but the
+signature could not be validated, `false` is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+### cookieParser.signedCookies(cookies, secret)
+
+Given an object, this will iterate over the keys and check if any value is a
+signed cookie. If it is a signed cookie and the signature is valid, the key
+will be deleted from the object and added to the new object that is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+## Example
+
+```js
+var express = require('express');
+var cookieParser = require('cookie-parser');
+
+var app = express();
+app.use(cookieParser());
+
+app.get('/', function (req, res) {
+ // Cookies that have not been signed
+ console.log('Cookies: ', req.cookies);
+
+ // Cookies that have been signed
+ console.log('Signed Cookies: ', req.signedCookies);
+});
+
+app.listen(8080);
+
+// curl command that sends an HTTP request with two cookies
+// curl http://127.0.0.1:8080 --cookie "Cho=Kim;Greet=Hello"
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/cookie-parser/master?label=ci
+[ci-url]: https://github.com/expressjs/cookie-parser/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/cookie-parser/master
+[coveralls-url]: https://coveralls.io/r/expressjs/cookie-parser?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/cookie-parser
+[npm-url]: https://npmjs.org/package/cookie-parser
+[npm-version-image]: https://badgen.net/npm/v/cookie-parser
diff --git a/astro/src/content/resources/ko/middleware/cookie-session.md b/astro/src/content/resources/ko/middleware/cookie-session.md
new file mode 100644
index 0000000000..2d6d1f885b
--- /dev/null
+++ b/astro/src/content/resources/ko/middleware/cookie-session.md
@@ -0,0 +1,124 @@
+---
+title: Express cookie-session middleware
+module: cookie-session
+---
+
+# cookie-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Parse `Cookie` header and populate `req.cookies` with an object keyed by the
+cookie names. Optionally you may enable signed cookie support by passing a
+`secret` string, which assigns `req.secret` so it may be used by other
+middleware.
+
+## Installation
+
+```sh
+$ npm install cookie-parser
+```
+
+## API
+
+```js
+var cookieParser = require('cookie-parser');
+```
+
+### cookieParser(secret, options)
+
+Create a new cookie parser middleware function using the given `secret` and
+`options`.
+
+- `secret` a string or array used for signing cookies. This is optional and if
+ not specified, will not parse signed cookies. If a string is provided, this
+ is used as the secret. If an array is provided, an attempt will be made to
+ unsign the cookie with each secret in order.
+- `options` an object that is passed to `cookie.parse` as the second option. See
+ [cookie](https://www.npmjs.org/package/cookie) for more information.
+ - `decode` a function to decode the value of the cookie
+
+The middleware will parse the `Cookie` header on the request and expose the
+cookie data as the property `req.cookies` and, if a `secret` was provided, as
+the property `req.signedCookies`. These properties are name value pairs of the
+cookie name to cookie value.
+
+When `secret` is provided, this module will unsign and validate any signed cookie
+values and move those name value pairs from `req.cookies` into `req.signedCookies`.
+A signed cookie is a cookie that has a value prefixed with `s:`. Signed cookies
+that fail signature validation will have the value `false` instead of the tampered
+value.
+
+In addition, this module supports special "JSON cookies". These are cookie where
+the value is prefixed with `j:`. When these values are encountered, the value will
+be exposed as the result of `JSON.parse`. If parsing fails, the original value will
+remain.
+
+### cookieParser.JSONCookie(str)
+
+Parse a cookie value as a JSON cookie. This will return the parsed JSON value
+if it was a JSON cookie, otherwise, it will return the passed value.
+
+### cookieParser.JSONCookies(cookies)
+
+Given an object, this will iterate over the keys and call `JSONCookie` on each
+value, replacing the original value with the parsed value. This returns the
+same object that was passed in.
+
+### cookieParser.signedCookie(str, secret)
+
+Parse a cookie value as a signed cookie. This will return the parsed unsigned
+value if it was a signed cookie and the signature was valid. If the value was
+not signed, the original value is returned. If the value was signed but the
+signature could not be validated, `false` is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+### cookieParser.signedCookies(cookies, secret)
+
+Given an object, this will iterate over the keys and check if any value is a
+signed cookie. If it is a signed cookie and the signature is valid, the key
+will be deleted from the object and added to the new object that is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+## Example
+
+```js
+var express = require('express');
+var cookieParser = require('cookie-parser');
+
+var app = express();
+app.use(cookieParser());
+
+app.get('/', function (req, res) {
+ // Cookies that have not been signed
+ console.log('Cookies: ', req.cookies);
+
+ // Cookies that have been signed
+ console.log('Signed Cookies: ', req.signedCookies);
+});
+
+app.listen(8080);
+
+// curl command that sends an HTTP request with two cookies
+// curl http://127.0.0.1:8080 --cookie "Cho=Kim;Greet=Hello"
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/cookie-parser/master?label=ci
+[ci-url]: https://github.com/expressjs/cookie-parser/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/cookie-parser/master
+[coveralls-url]: https://coveralls.io/r/expressjs/cookie-parser?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/cookie-parser
+[npm-url]: https://npmjs.org/package/cookie-parser
+[npm-version-image]: https://badgen.net/npm/v/cookie-parser
diff --git a/astro/src/content/resources/ko/middleware/cors.md b/astro/src/content/resources/ko/middleware/cors.md
new file mode 100644
index 0000000000..55d70922cb
--- /dev/null
+++ b/astro/src/content/resources/ko/middleware/cors.md
@@ -0,0 +1,261 @@
+---
+title: Express cors middleware
+module: cors
+---
+
+# cors
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+CORS is a [Node.js](https://nodejs.org/en/) package for providing a [Connect](https://github.com/senchalabs/connect)/[Express](https://expressjs.com/) middleware that can be used to enable [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS) with various options.
+
+- [Installation](#installation)
+- [Usage](#usage)
+ - [Simple Usage](#simple-usage-enable-all-cors-requests)
+ - [Enable CORS for a Single Route](#enable-cors-for-a-single-route)
+ - [Configuring CORS](#configuring-cors)
+ - [Configuring CORS w/ Dynamic Origin](#configuring-cors-w-dynamic-origin)
+ - [Enabling CORS Pre-Flight](#enabling-cors-pre-flight)
+ - [Customizing CORS Settings Dynamically per Request](#customizing-cors-settings-dynamically-per-request)
+- [Configuration Options](#configuration-options)
+- [License](#license)
+- [Original Author](#original-author)
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/downloading-and-installing-packages-locally):
+
+```sh
+$ npm install cors
+```
+
+## Usage
+
+### Simple Usage (Enable _All_ CORS Requests)
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.use(cors());
+
+app.get('/products/:id', function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for all origins!' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Enable CORS for a Single Route
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.get('/products/:id', cors(), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for a Single Route' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Configuring CORS
+
+See the [configuration options](#configuration-options) for details.
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+var corsOptions = {
+ origin: 'http://example.com',
+ optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
+};
+
+app.get('/products/:id', cors(corsOptions), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for only example.com.' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Configuring CORS w/ Dynamic Origin
+
+This module supports validating the origin dynamically using a function provided
+to the `origin` option. This function will be passed a string that is the origin
+(or `undefined` if the request has no origin), and a `callback` with the signature
+`callback(error, origin)`.
+
+The `origin` argument to the callback can be any value allowed for the `origin`
+option of the middleware, except a function. See the
+[configuration options](#configuration-options) section for more information on all
+the possible value types.
+
+This function is designed to allow the dynamic loading of allowed origin(s) from
+a backing datasource, like a database.
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+var corsOptions = {
+ origin: function (origin, callback) {
+ // db.loadOrigins is an example call to load
+ // a list of origins from a backing database
+ db.loadOrigins(function (error, origins) {
+ callback(error, origins);
+ });
+ },
+};
+
+app.get('/products/:id', cors(corsOptions), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for an allowed domain.' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Enabling CORS Pre-Flight
+
+Certain CORS requests are considered 'complex' and require an initial
+`OPTIONS` request (called the "pre-flight request"). An example of a
+'complex' CORS request is one that uses an HTTP verb other than
+GET/HEAD/POST (such as DELETE) or that uses custom headers. To enable
+pre-flighting, you must add a new OPTIONS handler for the route you want
+to support:
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.options('/products/:id', cors()); // enable pre-flight request for DELETE request
+app.del('/products/:id', cors(), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for all origins!' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+You can also enable pre-flight across-the-board like so:
+
+```javascript
+app.options('*', cors()); // include before other routes
+```
+
+NOTE: When using this middleware as an application level middleware (for
+example, `app.use(cors())`), pre-flight requests are already handled for all
+routes.
+
+### Customizing CORS Settings Dynamically per Request
+
+For APIs that require different CORS configurations for specific routes or requests, you can dynamically generate CORS options based on the incoming request. The `cors` middleware allows you to achieve this by passing a function instead of static options. This function is called for each incoming request and must use the callback pattern to return the appropriate CORS options.
+
+The function accepts:
+
+1. **`req`**:
+ - The incoming request object.
+
+2. **`callback(error, corsOptions)`**:
+ - A function used to return the computed CORS options.
+ - **Arguments**:
+ - **`error`**: Pass `null` if there’s no error, or an error object to indicate a failure.
+ - **`corsOptions`**: An object specifying the CORS policy for the current request.
+
+Here’s an example that handles both public routes and restricted, credential-sensitive routes:
+
+```javascript
+var dynamicCorsOptions = function (req, callback) {
+ var corsOptions;
+ if (req.path.startsWith('/auth/connect/')) {
+ corsOptions = {
+ origin: 'http://mydomain.com', // Allow only a specific origin
+ credentials: true, // Enable cookies and credentials
+ };
+ } else {
+ corsOptions = { origin: '*' }; // Allow all origins for other routes
+ }
+ callback(null, corsOptions);
+};
+
+app.use(cors(dynamicCorsOptions));
+
+app.get('/auth/connect/twitter', function (req, res) {
+ res.send('CORS dynamically applied for Twitter authentication.');
+});
+
+app.get('/public', function (req, res) {
+ res.send('Public data with open CORS.');
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+## Configuration Options
+
+- `origin`: Configures the **Access-Control-Allow-Origin** CORS header. Possible values:
+ - `Boolean` - set `origin` to `true` to reflect the [request origin](https://datatracker.ietf.org/doc/html/draft-abarth-origin-09), as defined by `req.header('Origin')`, or set it to `false` to disable CORS.
+ - `String` - set `origin` to a specific origin. For example, if you set it to
+ - `"http://example.com"` only requests from "http://example.com" will be allowed.
+ - `"*"` for all domains to be allowed.
+ - `RegExp` - set `origin` to a regular expression pattern which will be used to test the request origin. If it's a match, the request origin will be reflected. For example the pattern `/example\.com$/` will reflect any request that is coming from an origin ending with "example.com".
+ - `Array` - set `origin` to an array of valid origins. Each origin can be a `String` or a `RegExp`. For example `["http://example1.com", /\.example2\.com$/]` will accept any request from "http://example1.com" or from a subdomain of "example2.com".
+ - `Function` - set `origin` to a function implementing some custom logic. The function takes the request origin as the first parameter and a callback (called as `callback(err, origin)`, where `origin` is a non-function value of the `origin` option) as the second.
+- `methods`: Configures the **Access-Control-Allow-Methods** CORS header. Expects a comma-delimited string (ex: 'GET,PUT,POST') or an array (ex: `['GET', 'PUT', 'POST']`).
+- `allowedHeaders`: Configures the **Access-Control-Allow-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Type,Authorization') or an array (ex: `['Content-Type', 'Authorization']`). If not specified, defaults to reflecting the headers specified in the request's **Access-Control-Request-Headers** header.
+- `exposedHeaders`: Configures the **Access-Control-Expose-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Range,X-Content-Range') or an array (ex: `['Content-Range', 'X-Content-Range']`). If not specified, no custom headers are exposed.
+- `credentials`: Configures the **Access-Control-Allow-Credentials** CORS header. Set to `true` to pass the header, otherwise it is omitted.
+- `maxAge`: Configures the **Access-Control-Max-Age** CORS header. Set to an integer to pass the header, otherwise it is omitted.
+- `preflightContinue`: Pass the CORS preflight response to the next handler.
+- `optionsSuccessStatus`: Provides a status code to use for successful `OPTIONS` requests, since some legacy browsers (IE11, various SmartTVs) choke on `204`.
+
+The default configuration is the equivalent of:
+
+```json
+{
+ "origin": "*",
+ "methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
+ "preflightContinue": false,
+ "optionsSuccessStatus": 204
+}
+```
+
+For details on the effect of each CORS header, read [this](https://web.dev/articles/cross-origin-resource-sharing) article.
+
+## License
+
+[MIT License](http://www.opensource.org/licenses/mit-license.php)
+
+## Original Author
+
+[Troy Goode](https://github.com/TroyGoode) ([troygoode@gmail.com](mailto:troygoode@gmail.com))
+
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/cors/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/cors?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/cors.svg
+[downloads-url]: https://npmjs.com/package/cors
+[github-actions-ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/cors/ci.yml?branch=master&label=ci
+[github-actions-ci-url]: https://github.com/expressjs/cors?query=workflow%3Aci
+[npm-image]: https://img.shields.io/npm/v/cors.svg
+[npm-url]: https://npmjs.com/package/cors
diff --git a/astro/src/content/resources/ko/middleware/errorhandler.md b/astro/src/content/resources/ko/middleware/errorhandler.md
new file mode 100644
index 0000000000..20df618320
--- /dev/null
+++ b/astro/src/content/resources/ko/middleware/errorhandler.md
@@ -0,0 +1,133 @@
+---
+title: Express errorhandler middleware
+module: errorhandler
+---
+
+# errorhandler
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Development-only error handler middleware.
+
+This middleware is only intended to be used in a development environment, as
+the _full error stack traces and internal details of any object passed to this
+module_ will be sent back to the client when an error occurs.
+
+When an object is provided to Express as an error, this module will display
+as much about this object as possible, and will do so by using content negotiation
+for the response between HTML, JSON, and plain text.
+
+- When the object is a standard `Error` object, the string provided by the
+ `stack` property will be returned in HTML/text responses.
+- When the object is a non-`Error` object, the result of
+ [util.inspect](https://nodejs.org/api/util.html#util_util_inspect_object_options)
+ will be returned in HTML/text responses.
+- For JSON responses, the result will be an object with all enumerable properties
+ from the object in the response.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install errorhandler
+```
+
+## API
+
+
+
+```js
+var errorhandler = require('errorhandler');
+```
+
+### errorhandler(options)
+
+Create new middleware to handle errors and respond with content negotiation.
+
+#### Options
+
+Error handler accepts these properties in the options object.
+
+##### log
+
+Provide a function to be called with the error and a string representation of
+the error. Can be used to write the error to any desired location, or set to
+`false` to only send the error back in the response. Called as
+`log(err, str, req, res)` where `err` is the `Error` object, `str` is a string
+representation of the error, `req` is the request object and `res` is the
+response object (note, this function is invoked _after_ the response has been
+written).
+
+The default value for this option is `true` unless `process.env.NODE_ENV === 'test'`.
+
+Possible values:
+
+- `true`: Log errors using `console.error(str)`.
+- `false`: Only send the error back in the response.
+- A function: pass the error to a function for handling.
+
+## Examples
+
+### Simple example
+
+Basic example of adding this middleware as the error handler only in development
+with `connect` (`express` also can be used in this example).
+
+```js
+var connect = require('connect');
+var errorhandler = require('errorhandler');
+
+var app = connect();
+
+// assumes NODE_ENV is set by the user
+if (process.env.NODE_ENV === 'development') {
+ // only use in development
+ app.use(errorhandler());
+}
+```
+
+### Custom output location
+
+Sometimes you may want to output the errors to a different location than STDERR
+during development, like a system notification, for example.
+
+
+
+```js
+var connect = require('connect');
+var errorhandler = require('errorhandler');
+var notifier = require('node-notifier');
+
+var app = connect();
+
+// assumes NODE_ENV is set by the user
+if (process.env.NODE_ENV === 'development') {
+ // only use in development
+ app.use(errorhandler({ log: errorNotification }));
+}
+
+function errorNotification(err, str, req) {
+ var title = 'Error in ' + req.method + ' ' + req.url;
+
+ notifier.notify({
+ title: title,
+ message: str,
+ });
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/errorhandler/master
+[coveralls-url]: https://coveralls.io/r/expressjs/errorhandler?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/errorhandler
+[npm-url]: https://npmjs.org/package/errorhandler
+[npm-version-image]: https://badgen.net/npm/v/errorhandler
diff --git a/astro/src/content/resources/ko/middleware/method-override.md b/astro/src/content/resources/ko/middleware/method-override.md
new file mode 100644
index 0000000000..7b97ab855e
--- /dev/null
+++ b/astro/src/content/resources/ko/middleware/method-override.md
@@ -0,0 +1,187 @@
+---
+title: Express method-override middleware
+module: method-override
+---
+
+# method-override
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][travis-image]][travis-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Lets you use HTTP verbs such as PUT or DELETE in places where the client doesn't support it.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install method-override
+```
+
+## API
+
+**NOTE** It is very important that this module is used **before** any module that
+needs to know the method of the request (for example, it _must_ be used prior to
+the `csurf` module).
+
+### methodOverride(getter, options)
+
+Create a new middleware function to override the `req.method` property with a new
+value. This value will be pulled from the provided `getter`.
+
+- `getter` - The getter to use to look up the overridden request method for the request. (default: `X-HTTP-Method-Override`)
+- `options.methods` - The allowed methods the original request must be in to check for a method override value. (default: `['POST']`)
+
+If the found method is supported by node.js core, then `req.method` will be set to
+this value, as if it has originally been that value. The previous `req.method`
+value will be stored in `req.originalMethod`.
+
+#### getter
+
+This is the method of getting the override value from the request. If a function is provided,
+the `req` is passed as the first argument, the `res` as the second argument and the method is
+expected to be returned. If a string is provided, the string is used to look up the method
+with the following rules:
+
+- If the string starts with `X-`, then it is treated as the name of a header and that header
+ is used for the method override. If the request contains the same header multiple times, the
+ first occurrence is used.
+- All other strings are treated as a key in the URL query string.
+
+#### options.methods
+
+This allows the specification of what methods(s) the request _MUST_ be in in order to check for
+the method override value. This defaults to only `POST` methods, which is the only method the
+override should arrive in. More methods may be specified here, but it may introduce security
+issues and cause weird behavior when requests travel through caches. This value is an array
+of methods in upper-case. `null` can be specified to allow all methods.
+
+## Examples
+
+### override using a header
+
+To use a header to override the method, specify the header name
+as a string argument to the `methodOverride` function. To then make
+the call, send a `POST` request to a URL with the overridden method
+as the value of that header. This method of using a header would
+typically be used in conjunction with `XMLHttpRequest` on implementations
+that do not support the method you are trying to use.
+
+```js
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// override with the X-HTTP-Method-Override header in the request
+app.use(methodOverride('X-HTTP-Method-Override'));
+```
+
+Example call with header override using `XMLHttpRequest`:
+
+
+
+```js
+const xhr = new XMLHttpRequest();
+xhr.onload = onload;
+xhr.open('post', '/resource', true);
+xhr.setRequestHeader('X-HTTP-Method-Override', 'DELETE');
+xhr.send();
+
+function onload() {
+ alert('got response: ' + this.responseText);
+}
+```
+
+### override using a query value
+
+To use a query string value to override the method, specify the query
+string key as a string argument to the `methodOverride` function. To
+then make the call, send a `POST` request to a URL with the overridden
+method as the value of that query string key. This method of using a
+query value would typically be used in conjunction with plain HTML
+`
+```
+
+### multiple format support
+
+```js
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// override with different headers; last one takes precedence
+app.use(methodOverride('X-HTTP-Method')); // Microsoft
+app.use(methodOverride('X-HTTP-Method-Override')); // Google/GData
+app.use(methodOverride('X-Method-Override')); // IBM
+```
+
+### custom logic
+
+You can implement any kind of custom logic with a function for the `getter`. The following
+implements the logic for looking in `req.body` that was in `method-override@1`:
+
+```js
+const bodyParser = require('body-parser');
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// NOTE: when using req.body, you must fully parse the request body
+// before you call methodOverride() in your middleware stack,
+// otherwise req.body will not be populated.
+app.use(bodyParser.urlencoded());
+app.use(
+ methodOverride(function (req, res) {
+ if (req.body && typeof req.body === 'object' && '_method' in req.body) {
+ // look in urlencoded POST bodies and delete it
+ const method = req.body._method;
+ delete req.body._method;
+ return method;
+ }
+ })
+);
+```
+
+Example call with query override using HTML `
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/method-override.svg
+[npm-url]: https://npmjs.org/package/method-override
+[travis-image]: https://img.shields.io/travis/expressjs/method-override/master.svg
+[travis-url]: https://travis-ci.org/expressjs/method-override
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/method-override/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/method-override?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/method-override.svg
+[downloads-url]: https://npmjs.org/package/method-override
diff --git a/astro/src/content/resources/ko/middleware/morgan.md b/astro/src/content/resources/ko/middleware/morgan.md
new file mode 100644
index 0000000000..5319d93d57
--- /dev/null
+++ b/astro/src/content/resources/ko/middleware/morgan.md
@@ -0,0 +1,458 @@
+---
+title: Express morgan middleware
+module: morgan
+---
+
+# morgan
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+HTTP request logger middleware for node.js
+
+> Named after [Dexter](http://en.wikipedia.org/wiki/Dexter_Morgan), a show you should not watch until completion.
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install morgan
+```
+
+## API
+
+
+
+```js
+var morgan = require('morgan');
+```
+
+### morgan(format, options)
+
+Create a new morgan logger middleware function using the given `format` and `options`.
+The `format` argument may be a string of a predefined name (see below for the names),
+a string of a format string, or a function that will produce a log entry.
+
+The `format` function will be called with three arguments `tokens`, `req`, and `res`,
+where `tokens` is an object with all defined tokens, `req` is the HTTP request and `res`
+is the HTTP response. The function is expected to return a string that will be the log
+line, or `undefined` / `null` to skip logging.
+
+#### Using a predefined format string
+
+
+
+```js
+morgan('tiny');
+```
+
+#### Using format string of predefined tokens
+
+
+
+```js
+morgan(':method :url :status :res[content-length] - :response-time ms');
+```
+
+#### Using a custom format function
+
+
+
+```js
+morgan(function (tokens, req, res) {
+ return [
+ tokens.method(req, res),
+ tokens.url(req, res),
+ tokens.status(req, res),
+ tokens.res(req, res, 'content-length'),
+ '-',
+ tokens['response-time'](req, res),
+ 'ms',
+ ].join(' ');
+});
+```
+
+#### Options
+
+Morgan accepts these properties in the options object.
+
+##### immediate
+
+Write log line on request instead of response. This means that a requests will
+be logged even if the server crashes, _but data from the response (like the
+response code, content length, etc.) cannot be logged_.
+
+##### skip
+
+Function to determine if logging is skipped, defaults to `false`. This function
+will be called as `skip(req, res)`.
+
+
+
+```js
+// EXAMPLE: only log error responses
+morgan('combined', {
+ skip: function (req, res) {
+ return res.statusCode < 400;
+ },
+});
+```
+
+##### stream
+
+Output stream for writing log lines, defaults to `process.stdout`.
+
+#### Predefined Formats
+
+There are various pre-defined formats provided:
+
+##### combined
+
+Standard Apache combined log output.
+
+```
+:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"
+# will output
+::1 - - [27/Nov/2024:06:21:42 +0000] "GET /combined HTTP/1.1" 200 2 "-" "curl/8.7.1"
+```
+
+##### common
+
+Standard Apache common log output.
+
+```
+:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length]
+# will output
+::1 - - [27/Nov/2024:06:21:46 +0000] "GET /common HTTP/1.1" 200 2
+```
+
+##### dev
+
+Concise output colored by response status for development use. The `:status`
+token will be colored green for success codes, red for server error codes,
+yellow for client error codes, cyan for redirection codes, and uncolored
+for information codes.
+
+```
+:method :url :status :response-time ms - :res[content-length]
+# will output
+GET /dev 200 0.224 ms - 2
+```
+
+##### short
+
+Shorter than default, also including response time.
+
+```
+:remote-addr :remote-user :method :url HTTP/:http-version :status :res[content-length] - :response-time ms
+# will output
+::1 - GET /short HTTP/1.1 200 2 - 0.283 ms
+```
+
+##### tiny
+
+The minimal output.
+
+```
+:method :url :status :res[content-length] - :response-time ms
+# will output
+GET /tiny 200 2 - 0.188 ms
+```
+
+#### Tokens
+
+##### Creating new tokens
+
+To define a token, simply invoke `morgan.token()` with the name and a callback function.
+This callback function is expected to return a string value. The value returned is then
+available as ":type" in this case:
+
+
+
+```js
+morgan.token('type', function (req, res) {
+ return req.headers['content-type'];
+});
+```
+
+Calling `morgan.token()` using the same name as an existing token will overwrite that
+token definition.
+
+The token function is expected to be called with the arguments `req` and `res`, representing
+the HTTP request and HTTP response. Additionally, the token can accept further arguments of
+it's choosing to customize behavior.
+
+##### :date[format]
+
+The current date and time in UTC. The available formats are:
+
+- `clf` for the common log format (`"10/Oct/2000:13:55:36 +0000"`)
+- `iso` for the common ISO 8601 date time format (`2000-10-10T13:55:36.000Z`)
+- `web` for the common RFC 1123 date time format (`Tue, 10 Oct 2000 13:55:36 GMT`)
+
+If no format is given, then the default is `web`.
+
+##### :http-version
+
+The HTTP version of the request.
+
+##### :method
+
+The HTTP method of the request.
+
+##### :pid
+
+The process ID of the Node.js process handling the request.
+
+##### :referrer
+
+The Referrer header of the request. This will use the standard mis-spelled Referer header if exists, otherwise Referrer.
+
+##### :remote-addr
+
+The remote address of the request. This will use `req.ip`, otherwise the standard `req.connection.remoteAddress` value (socket address).
+
+##### :remote-user
+
+The user authenticated as part of Basic auth for the request.
+
+##### :req[header]
+
+The given `header` of the request. If the header is not present, the
+value will be displayed as `"-"` in the log.
+
+##### :res[header]
+
+The given `header` of the response. If the header is not present, the
+value will be displayed as `"-"` in the log.
+
+##### :response-time[digits]
+
+The time between the request coming into `morgan` and when the response
+headers are written, in milliseconds.
+
+The `digits` argument is a number that specifies the number of digits to
+include on the number, defaulting to `3`, which provides microsecond precision.
+
+##### :status
+
+The status code of the response.
+
+If the request/response cycle completes before a response was sent to the
+client (for example, the TCP socket closed prematurely by a client aborting
+the request), then the status will be empty (displayed as `"-"` in the log).
+
+##### :total-time[digits]
+
+The time between the request coming into `morgan` and when the response
+has finished being written out to the connection, in milliseconds.
+
+The `digits` argument is a number that specifies the number of digits to
+include on the number, defaulting to `3`, which provides microsecond precision.
+
+##### :url
+
+The URL of the request. This will use `req.originalUrl` if exists, otherwise `req.url`.
+
+##### :user-agent
+
+The contents of the User-Agent header of the request.
+
+### morgan.compile(format)
+
+Compile a format string into a `format` function for use by `morgan`. A format string
+is a string that represents a single log line and can utilize token syntax.
+Tokens are references by `:token-name`. If tokens accept arguments, they can
+be passed using `[]`, for example: `:token-name[pretty]` would pass the string
+`'pretty'` as an argument to the token `token-name`.
+
+The function returned from `morgan.compile` takes three arguments `tokens`, `req`, and
+`res`, where `tokens` is object with all defined tokens, `req` is the HTTP request and
+`res` is the HTTP response. The function will return a string that will be the log line,
+or `undefined` / `null` to skip logging.
+
+Normally formats are defined using `morgan.format(name, format)`, but for certain
+advanced uses, this compile function is directly available.
+
+## Examples
+
+### express/connect
+
+Sample app that will log all request in the Apache combined format to STDOUT
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+
+var app = express();
+
+app.use(morgan('combined'));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### vanilla http server
+
+Sample app that will log all request in the Apache combined format to STDOUT
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var morgan = require('morgan');
+
+// create "middleware"
+var logger = morgan('combined');
+
+http.createServer(function (req, res) {
+ var done = finalhandler(req, res);
+ logger(req, res, function (err) {
+ if (err) return done(err);
+
+ // respond to request
+ res.setHeader('content-type', 'text/plain');
+ res.end('hello, world!');
+ });
+});
+```
+
+### write logs to a file
+
+#### single file
+
+Sample app that will log all requests in the Apache combined format to the file
+`access.log`.
+
+```js
+var express = require('express');
+var fs = require('fs');
+var morgan = require('morgan');
+var path = require('path');
+
+var app = express();
+
+// create a write stream (in append mode)
+var accessLogStream = fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' });
+
+// setup the logger
+app.use(morgan('combined', { stream: accessLogStream }));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+#### log file rotation
+
+Sample app that will log all requests in the Apache combined format to one log
+file per day in the `log/` directory using the
+[rotating-file-stream module](https://www.npmjs.com/package/rotating-file-stream).
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+var path = require('path');
+var rfs = require('rotating-file-stream'); // version 2.x
+
+var app = express();
+
+// create a rotating write stream
+var accessLogStream = rfs.createStream('access.log', {
+ interval: '1d', // rotate daily
+ path: path.join(__dirname, 'log'),
+});
+
+// setup the logger
+app.use(morgan('combined', { stream: accessLogStream }));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### split / dual logging
+
+The `morgan` middleware can be used as many times as needed, enabling
+combinations like:
+
+- Log entry on request and one on response
+- Log all requests to file, but errors to console
+- ... and more!
+
+Sample app that will log all requests to a file using Apache format, but
+error responses are logged to the console:
+
+```js
+var express = require('express');
+var fs = require('fs');
+var morgan = require('morgan');
+var path = require('path');
+
+var app = express();
+
+// log only 4xx and 5xx responses to console
+app.use(
+ morgan('dev', {
+ skip: function (req, res) {
+ return res.statusCode < 400;
+ },
+ })
+);
+
+// log all requests to access.log
+app.use(
+ morgan('common', {
+ stream: fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' }),
+ })
+);
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### use custom token formats
+
+Sample app that will use custom token formats. This adds an ID to all requests and displays it using the `:id` token.
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+var uuid = require('node-uuid');
+
+morgan.token('id', function getId(req) {
+ return req.id;
+});
+
+var app = express();
+
+app.use(assignId);
+app.use(morgan(':id :method :url :response-time'));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+
+function assignId(req, res, next) {
+ req.id = uuid.v4();
+ next();
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/morgan/master?label=ci
+[ci-url]: https://github.com/expressjs/morgan/actions/workflows/ci.yml
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/morgan/master
+[coveralls-url]: https://coveralls.io/r/expressjs/morgan?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/morgan
+[npm-url]: https://npmjs.org/package/morgan
+[npm-version-image]: https://badgen.net/npm/v/morgan
diff --git a/astro/src/content/resources/ko/middleware/multer.md b/astro/src/content/resources/ko/middleware/multer.md
new file mode 100644
index 0000000000..326786ab3d
--- /dev/null
+++ b/astro/src/content/resources/ko/middleware/multer.md
@@ -0,0 +1,352 @@
+---
+title: Express multer middleware
+module: multer
+---
+
+# Multer [![NPM Version][npm-version-image]][npm-url] [![NPM Downloads][npm-downloads-image]][npm-url] [![Build Status][ci-image]][ci-url] [![Test Coverage][test-image]][test-url] [![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+
+Multer is a node.js middleware for handling `multipart/form-data`, which is primarily used for uploading files. It is written
+on top of [busboy](https://github.com/mscdex/busboy) for maximum efficiency.
+
+**NOTE**: Multer will not process any form which is not multipart (`multipart/form-data`).
+
+## Translations
+
+This README is also available in other languages:
+
+| | |
+| ------------------------------------------------------------------------------ | --------------- |
+| [العربية](https://github.com/expressjs/multer/blob/main/doc/README-ar.md) | Arabic |
+| [简体中文](https://github.com/expressjs/multer/blob/main/doc/README-zh-cn.md) | Chinese |
+| [Français](https://github.com/expressjs/multer/blob/main/doc/README-fr.md) | French |
+| [한국어](https://github.com/expressjs/multer/blob/main/doc/README-ko.md) | Korean |
+| [Português](https://github.com/expressjs/multer/blob/main/doc/README-pt-br.md) | Portuguese (BR) |
+| [Русский язык](https://github.com/expressjs/multer/blob/main/doc/README-ru.md) | Russian |
+| [Español](https://github.com/expressjs/multer/blob/main/doc/README-es.md) | Spanish |
+| [O'zbek tili](https://github.com/expressjs/multer/blob/main/doc/README-uz.md) | Uzbek |
+| [Việt Nam](https://github.com/expressjs/multer/blob/main/doc/README-vi.md) | Vietnamese |
+
+## Installation
+
+```sh
+$ npm install multer
+```
+
+## Usage
+
+Multer adds a `body` object and a `file` or `files` object to the `request` object. The `body` object contains the values of the text fields of the form, the `file` or `files` object contains the files uploaded via the form.
+
+Basic usage example:
+
+Don't forget the `enctype="multipart/form-data"` in your form.
+
+```html
+
+```
+
+```javascript
+const express = require('express');
+const multer = require('multer');
+const upload = multer({ dest: 'uploads/' });
+
+const app = express();
+
+app.post('/profile', upload.single('avatar'), function (req, res, next) {
+ // req.file is the `avatar` file
+ // req.body will hold the text fields, if there were any
+});
+
+app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
+ // req.files is array of `photos` files
+ // req.body will contain the text fields, if there were any
+});
+
+const uploadMiddleware = upload.fields([
+ { name: 'avatar', maxCount: 1 },
+ { name: 'gallery', maxCount: 8 },
+]);
+app.post('/cool-profile', uploadMiddleware, function (req, res, next) {
+ // req.files is an object (String -> Array) where fieldname is the key, and the value is array of files
+ //
+ // e.g.
+ // req.files['avatar'][0] -> File
+ // req.files['gallery'] -> Array
+ //
+ // req.body will contain the text fields, if there were any
+});
+```
+
+In case you need to handle a text-only multipart form, you should use the `.none()` method:
+
+```javascript
+const express = require('express');
+const app = express();
+const multer = require('multer');
+const upload = multer();
+
+app.post('/profile', upload.none(), function (req, res, next) {
+ // req.body contains the text fields
+});
+```
+
+Here's an example on how multer is used in a HTML form. Take special note of the `enctype="multipart/form-data"` and `name="uploaded_file"` fields:
+
+```html
+
+```
+
+Then in your javascript file you would add these lines to access both the file and the body. It is important that you use the `name` field value from the form in your upload function. This tells multer which field on the request it should look for the files in. If these fields aren't the same in the HTML form and on your server, your upload will fail:
+
+```javascript
+const multer = require('multer');
+const upload = multer({ dest: './public/data/uploads/' });
+app.post('/stats', upload.single('uploaded_file'), function (req, res) {
+ // req.file is the name of your file in the form above, here 'uploaded_file'
+ // req.body will hold the text fields, if there were any
+ console.log(req.file, req.body);
+});
+```
+
+## API
+
+### File information
+
+Each file contains the following information:
+
+| Key | Description | Note |
+| -------------- | --------------------------------------------- | --------------- |
+| `fieldname` | Field name specified in the form |
+| `originalname` | Name of the file on the user's computer |
+| `encoding` | Encoding type of the file |
+| `mimetype` | Mime type of the file |
+| `size` | Size of the file in bytes |
+| `destination` | The folder to which the file has been saved | `DiskStorage` |
+| `filename` | The name of the file within the `destination` | `DiskStorage` |
+| `path` | The full path to the uploaded file | `DiskStorage` |
+| `buffer` | A `Buffer` of the entire file | `MemoryStorage` |
+
+### `multer(opts)`
+
+Multer accepts an options object, the most basic of which is the `dest`
+property, which tells Multer where to upload the files. In case you omit the
+options object, the files will be kept in memory and never written to disk.
+
+By default, Multer will rename the files so as to avoid naming conflicts. The
+renaming function can be customized according to your needs.
+
+The following are the options that can be passed to Multer.
+
+| Key | Description |
+| ------------------- | --------------------------------------------------------- |
+| `dest` or `storage` | Where to store the files |
+| `fileFilter` | Function to control which files are accepted |
+| `limits` | Limits of the uploaded data |
+| `preservePath` | Keep the full path of files instead of just the base name |
+
+In an average web app, only `dest` might be required, and configured as shown in
+the following example.
+
+```javascript
+const upload = multer({ dest: 'uploads/' });
+```
+
+If you want more control over your uploads, you'll want to use the `storage`
+option instead of `dest`. Multer ships with storage engines `DiskStorage`
+and `MemoryStorage`; More engines are available from third parties.
+
+#### `.single(fieldname)`
+
+Accept a single file with the name `fieldname`. The single file will be stored
+in `req.file`.
+
+#### `.array(fieldname[, maxCount])`
+
+Accept an array of files, all with the name `fieldname`. Optionally error out if
+more than `maxCount` files are uploaded. The array of files will be stored in
+`req.files`.
+
+#### `.fields(fields)`
+
+Accept a mix of files, specified by `fields`. An object with arrays of files
+will be stored in `req.files`.
+
+`fields` should be an array of objects with `name` and optionally a `maxCount`.
+Example:
+
+```javascript
+[
+ { name: 'avatar', maxCount: 1 },
+ { name: 'gallery', maxCount: 8 },
+];
+```
+
+#### `.none()`
+
+Accept only text fields. If any file upload is made, error with code
+"LIMIT_UNEXPECTED_FILE" will be issued.
+
+#### `.any()`
+
+Accepts all files that comes over the wire. An array of files will be stored in
+`req.files`.
+
+**WARNING:** Make sure that you always handle the files that a user uploads.
+Never add multer as a global middleware since a malicious user could upload
+files to a route that you didn't anticipate. Only use this function on routes
+where you are handling the uploaded files.
+
+### `storage`
+
+#### `DiskStorage`
+
+The disk storage engine gives you full control on storing files to disk.
+
+```javascript
+const storage = multer.diskStorage({
+ destination: function (req, file, cb) {
+ cb(null, '/tmp/my-uploads');
+ },
+ filename: function (req, file, cb) {
+ const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
+ cb(null, file.fieldname + '-' + uniqueSuffix);
+ },
+});
+
+const upload = multer({ storage: storage });
+```
+
+There are two options available, `destination` and `filename`. They are both
+functions that determine where the file should be stored.
+
+`destination` is used to determine within which folder the uploaded files should
+be stored. This can also be given as a `string` (e.g. `'/tmp/uploads'`). If no
+`destination` is given, the operating system's default directory for temporary
+files is used.
+
+**Note:** You are responsible for creating the directory when providing
+`destination` as a function. When passing a string, multer will make sure that
+the directory is created for you.
+
+`filename` is used to determine what the file should be named inside the folder.
+If no `filename` is given, each file will be given a random name that doesn't
+include any file extension.
+
+**Note:** Multer will not append any file extension for you, your function
+should return a filename complete with a file extension.
+
+Each function gets passed both the request (`req`) and some information about
+the file (`file`) to aid with the decision.
+
+Note that `req.body` might not have been fully populated yet. It depends on the
+order that the client transmits fields and files to the server.
+
+For understanding the calling convention used in the callback (needing to pass
+null as the first param), refer to
+[Node.js error handling](https://web.archive.org/web/20220417042018/https://www.joyent.com/node-js/production/design/errors)
+
+#### `MemoryStorage`
+
+The memory storage engine stores the files in memory as `Buffer` objects. It
+doesn't have any options.
+
+```javascript
+const storage = multer.memoryStorage();
+const upload = multer({ storage: storage });
+```
+
+When using memory storage, the file info will contain a field called
+`buffer` that contains the entire file.
+
+**WARNING**: Uploading very large files, or relatively small files in large
+numbers very quickly, can cause your application to run out of memory when
+memory storage is used.
+
+### `limits`
+
+An object specifying the size limits of the following optional properties. Multer passes this object into busboy directly, and the details of the properties can be found on [busboy's page](https://github.com/mscdex/busboy#busboy-methods).
+
+The following integer values are available:
+
+| Key | Description | Default |
+| --------------- | ----------------------------------------------------------------------- | --------- |
+| `fieldNameSize` | Max field name size | 100 bytes |
+| `fieldSize` | Max field value size (in bytes) | 1MB |
+| `fields` | Max number of non-file fields | Infinity |
+| `fileSize` | For multipart forms, the max file size (in bytes) | Infinity |
+| `files` | For multipart forms, the max number of file fields | Infinity |
+| `parts` | For multipart forms, the max number of parts (fields + files) | Infinity |
+| `headerPairs` | For multipart forms, the max number of header key=>value pairs to parse | 2000 |
+
+Specifying the limits can help protect your site against denial of service (DoS) attacks.
+
+### `fileFilter`
+
+Set this to a function to control which files should be uploaded and which
+should be skipped. The function should look like this:
+
+```javascript
+function fileFilter(req, file, cb) {
+ // The function should call `cb` with a boolean
+ // to indicate if the file should be accepted
+
+ // To reject this file pass `false`, like so:
+ cb(null, false);
+
+ // To accept the file pass `true`, like so:
+ cb(null, true);
+
+ // You can always pass an error if something goes wrong:
+ cb(new Error("I don't have a clue!"));
+}
+```
+
+## Error handling
+
+When encountering an error, Multer will delegate the error to Express. You can
+display a nice error page using [the standard express way](http://expressjs.com/guide/error-handling.html).
+
+If you want to catch errors specifically from Multer, you can call the
+middleware function by yourself. Also, if you want to catch only [the Multer errors](https://github.com/expressjs/multer/blob/main/lib/multer-error.js), you can use the `MulterError` class that is attached to the `multer` object itself (e.g. `err instanceof multer.MulterError`).
+
+```javascript
+const multer = require('multer');
+const upload = multer().single('avatar');
+
+app.post('/profile', function (req, res) {
+ upload(req, res, function (err) {
+ if (err instanceof multer.MulterError) {
+ // A Multer error occurred when uploading.
+ } else if (err) {
+ // An unknown error occurred when uploading.
+ }
+
+ // Everything went fine.
+ });
+});
+```
+
+## Custom storage engine
+
+For information on how to build your own storage engine, see [Multer Storage Engine](https://github.com/expressjs/multer/blob/main/StorageEngine.md).
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://github.com/expressjs/multer/actions/workflows/ci.yml/badge.svg
+[ci-url]: https://github.com/expressjs/multer/actions/workflows/ci.yml
+[test-url]: https://coveralls.io/r/expressjs/multer?branch=main
+[test-image]: https://badgen.net/coveralls/c/github/expressjs/multer/main
+[npm-downloads-image]: https://badgen.net/npm/dm/multer
+[npm-url]: https://npmjs.org/package/multer
+[npm-version-image]: https://badgen.net/npm/v/multer
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/multer/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer
diff --git a/astro/src/content/resources/ko/middleware/overview.md b/astro/src/content/resources/ko/middleware/overview.md
new file mode 100755
index 0000000000..46217759e7
--- /dev/null
+++ b/astro/src/content/resources/ko/middleware/overview.md
@@ -0,0 +1,40 @@
+---
+title: Express middleware
+description: Explore a list of Express.js middleware modules maintained by the Express team and the community, including built-in middleware and popular third-party modules.
+module: mw-home
+---
+
+## Express middleware
+
+The Express middleware modules listed here are maintained by the
+[Expressjs team](https://github.com/orgs/expressjs/people).
+
+| Middleware module | Description |
+| ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
+| [body-parser](/en/resources/middleware/body-parser) | Parse HTTP request body. |
+| [compression](/en/resources/middleware/compression) | Compress HTTP responses. |
+| [cookie-parser](/en/resources/middleware/cookie-parser) | Parse cookie header and populate `req.cookies`. See also [cookies](https://github.com/jed/cookies). |
+| [cookie-session](/en/resources/middleware/cookie-session) | Establish cookie-based sessions. |
+| [cors](/en/resources/middleware/cors) | Enable cross-origin resource sharing (CORS) with various options. |
+| [errorhandler](/en/resources/middleware/errorhandler) | Development error-handling/debugging. |
+| [method-override](/en/resources/middleware/method-override) | Override HTTP methods using header. |
+| [morgan](/en/resources/middleware/morgan) | HTTP request logger. |
+| [multer](/en/resources/middleware/multer) | Handle multi-part form data. |
+| [response-time](/en/resources/middleware/response-time) | Record HTTP response time. |
+| [serve-favicon](/en/resources/middleware/serve-favicon) | Serve a favicon. |
+| [serve-index](/en/resources/middleware/serve-index) | Serve directory listing for a given path. |
+| [serve-static](/en/resources/middleware/serve-static) | Serve static files. |
+| [session](/en/resources/middleware/session) | Establish server-based sessions (development only). |
+| [timeout](/en/resources/middleware/timeout) | Set a timeout perioHTTP request processing. |
+| [vhost](/en/resources/middleware/vhost) | Create virtual domains. |
+
+## Additional middleware modules
+
+These are some additional popular middleware modules.
+
+{% include community-caveat.html %}
+
+| Middleware module | Description |
+| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
+| [helmet](https://github.com/helmetjs/helmet) | Helps secure your apps by setting various HTTP headers. |
+| [passport](https://github.com/jaredhanson/passport) | Authentication using "strategies" such as OAuth, OpenID and many others. See [passportjs.org](https://passportjs.org/) for more information. |
diff --git a/astro/src/content/resources/ko/middleware/response-time.md b/astro/src/content/resources/ko/middleware/response-time.md
new file mode 100644
index 0000000000..f911f480f5
--- /dev/null
+++ b/astro/src/content/resources/ko/middleware/response-time.md
@@ -0,0 +1,314 @@
+---
+title: Express response-time middleware
+module: response-time
+---
+
+# compression
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+[![Funding][funding-image]][funding-url]
+
+Node.js compression middleware.
+
+The following compression codings are supported:
+
+- deflate
+- gzip
+- br (brotli)
+
+**Note** Brotli is supported only since Node.js versions v11.7.0 and v10.16.0.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```bash
+$ npm install compression
+```
+
+## API
+
+```js
+var compression = require('compression');
+```
+
+### compression([options])
+
+Returns the compression middleware using the given `options`. The middleware
+will attempt to compress response bodies for all requests that traverse through
+the middleware, based on the given `options`.
+
+This middleware will never compress responses that include a `Cache-Control`
+header with the [`no-transform` directive](https://tools.ietf.org/html/rfc7234#section-5.2.2.4),
+as compressing will transform the body.
+
+#### Options
+
+`compression()` accepts these properties in the options object. In addition to
+those listed below, [zlib](https://nodejs.org/api/zlib.html) options may be
+passed in to the options object or
+[brotli](https://nodejs.org/api/zlib.html#zlib_class_brotlioptions) options.
+
+##### chunkSize
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_CHUNK`, or `16384`.
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### filter
+
+Type: `Function`
+
+A function to decide if the response should be considered for compression.
+This function is called as `filter(req, res)` and is expected to return
+`true` to consider the response for compression, or `false` to not compress
+the response.
+
+The default filter function uses the [compressible](https://www.npmjs.com/package/compressible)
+module to determine if `res.getHeader('Content-Type')` is compressible.
+
+##### level
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_COMPRESSION`, or `-1`
+
+The level of zlib compression to apply to responses. A higher level will result
+in better compression, but will take longer to complete. A lower level will
+result in less compression, but will be much faster.
+
+This is an integer in the range of `0` (no compression) to `9` (maximum
+compression). The special value `-1` can be used to mean the "default
+compression level", which is a default compromise between speed and
+compression (currently equivalent to level 6).
+
+- `-1` Default compression level (also `zlib.constants.Z_DEFAULT_COMPRESSION`).
+- `0` No compression (also `zlib.constants.Z_NO_COMPRESSION`).
+- `1` Fastest compression (also `zlib.constants.Z_BEST_SPEED`).
+- `2`
+- `3`
+- `4`
+- `5`
+- `6` (currently what `zlib.constants.Z_DEFAULT_COMPRESSION` points to).
+- `7`
+- `8`
+- `9` Best compression (also `zlib.constants.Z_BEST_COMPRESSION`).
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### memLevel
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_MEMLEVEL`, or `8`
+
+This specifies how much memory should be allocated for the internal compression
+state and is an integer in the range of `1` (minimum level) and `9` (maximum
+level).
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### brotli
+
+Type: `Object`
+
+This specifies the options for configuring Brotli. See [Node.js documentation](https://nodejs.org/api/zlib.html#class-brotlioptions) for a complete list of available options.
+
+##### strategy
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_STRATEGY`
+
+This is used to tune the compression algorithm. This value only affects the
+compression ratio, not the correctness of the compressed output, even if it
+is not set appropriately.
+
+- `zlib.constants.Z_DEFAULT_STRATEGY` Use for normal data.
+- `zlib.constants.Z_FILTERED` Use for data produced by a filter (or predictor).
+ Filtered data consists mostly of small values with a somewhat random
+ distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect is to force more Huffman coding and less
+ string matching; it is somewhat intermediate between `zlib.constants.Z_DEFAULT_STRATEGY`
+ and `zlib.constants.Z_HUFFMAN_ONLY`.
+- `zlib.constants.Z_FIXED` Use to prevent the use of dynamic Huffman codes, allowing
+ for a simpler decoder for special applications.
+- `zlib.constants.Z_HUFFMAN_ONLY` Use to force Huffman encoding only (no string match).
+- `zlib.constants.Z_RLE` Use to limit match distances to one (run-length encoding).
+ This is designed to be almost as fast as `zlib.constants.Z_HUFFMAN_ONLY`, but give
+ better compression for PNG image data.
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### threshold
+
+Type: `Number` or `String`
+Default: `1kb`
+
+The byte threshold for the response body size before compression is considered
+for the response. This is a number of bytes or any string
+accepted by the [bytes](https://www.npmjs.com/package/bytes) module.
+
+**Note** this is only an advisory setting; if the response size cannot be determined
+at the time the response headers are written, then it is assumed the response is
+_over_ the threshold. To guarantee the response size can be determined, be sure
+set a `Content-Length` response header.
+
+##### windowBits
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_WINDOWBITS`, or `15`
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### enforceEncoding
+
+Type: `String`
+Default: `identity`
+
+This is the default encoding to use when the client does not specify an encoding in the request's [Accept-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) header.
+
+#### .filter
+
+The default `filter` function. This is used to construct a custom filter
+function that is an extension of the default function.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+app.use(compression({ filter: shouldCompress }));
+
+function shouldCompress(req, res) {
+ if (req.headers['x-no-compression']) {
+ // don't compress responses with this request header
+ return false;
+ }
+
+ // fallback to standard filter function
+ return compression.filter(req, res);
+}
+```
+
+### res.flush
+
+This module adds a `res.flush()` method to force the partially-compressed
+response to be flushed to the client.
+
+## Examples
+
+### express
+
+When using this module with express, simply `app.use` the module as
+high as you like. Requests that pass through the middleware will be compressed.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress all responses
+app.use(compression());
+
+// add all routes
+```
+
+### Node.js HTTP server
+
+```js
+var compression = require('compression')({ threshold: 0 });
+var http = require('http');
+
+function createServer(fn) {
+ return http.createServer(function (req, res) {
+ compression(req, res, function (err) {
+ if (err) {
+ res.statusCode = err.status || 500;
+ res.end(err.message);
+ return;
+ }
+
+ fn(req, res);
+ });
+ });
+}
+
+var server = createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello world!');
+});
+
+server.listen(3000, () => {
+ console.log('> Listening at http://localhost:3000');
+});
+```
+
+### Server-Sent Events
+
+Because of the nature of compression this module does not work out of the box
+with server-sent events. To compress content, a window of the output needs to
+be buffered up in order to get good compression. Typically when using server-sent
+events, there are certain block of data that need to reach the client.
+
+You can achieve this by calling `res.flush()` when you need the data written to
+actually make it to the client.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress responses
+app.use(compression());
+
+// server-sent event stream
+app.get('/events', function (req, res) {
+ res.setHeader('Content-Type', 'text/event-stream');
+ res.setHeader('Cache-Control', 'no-cache');
+
+ // send a ping approx every 2 seconds
+ var timer = setInterval(function () {
+ res.write('data: ping\n\n');
+
+ // !!! this is the important part
+ res.flush();
+ }, 2000);
+
+ res.on('close', function () {
+ clearInterval(timer);
+ });
+});
+```
+
+## Contributing
+
+The Express.js project welcomes all constructive contributions. Contributions take many forms,
+from code for bug fixes and enhancements, to additions and fixes to documentation, additional
+tests, triaging incoming pull requests and issues, and more!
+
+See the [Contributing Guide](https://github.com/expressjs/express/blob/master/Contributing.md) for more technical details on contributing.
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://badgen.net/npm/v/compression
+[npm-url]: https://npmjs.org/package/compression
+[downloads-image]: https://badgen.net/npm/dm/compression
+[downloads-url]: https://npmcharts.com/compare/compression?minimal=true
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/compression/master?label=CI
+[github-actions-ci-url]: https://github.com/expressjs/compression/actions?query=workflow%3Aci
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/compression/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/compression
+[funding-url]: https://opencollective.com/express
+[funding-image]: https://badgen.net/badge/icon/sponsor/pink?icon=github&label=Open%20Collective
diff --git a/astro/src/content/resources/ko/middleware/serve-favicon.md b/astro/src/content/resources/ko/middleware/serve-favicon.md
new file mode 100644
index 0000000000..7a77865c6b
--- /dev/null
+++ b/astro/src/content/resources/ko/middleware/serve-favicon.md
@@ -0,0 +1,156 @@
+---
+title: Express serve-favicon middleware
+module: serve-favicon
+---
+
+# serve-index
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Linux Build Status][ci-image]][ci-url]
+[![Windows Build][appveyor-image]][appveyor-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+Serves pages that contain directory listings for a given path.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-index
+```
+
+## API
+
+```js
+var serveIndex = require('serve-index');
+```
+
+### serveIndex(path, options)
+
+Returns middlware that serves an index of the directory in the given `path`.
+
+The `path` is based off the `req.url` value, so a `req.url` of `'/some/dir`
+with a `path` of `'public'` will look at `'public/some/dir'`. If you are using
+something like `express`, you can change the URL "base" with `app.use` (see
+the express example).
+
+#### Options
+
+Serve index accepts these properties in the options object.
+
+##### filter
+
+Apply this filter function to files. Defaults to `false`. The `filter` function
+is called for each file, with the signature `filter(filename, index, files, dir)`
+where `filename` is the name of the file, `index` is the array index, `files` is
+the array of files and `dir` is the absolute path the file is located (and thus,
+the directory the listing is for).
+
+##### hidden
+
+Display hidden (dot) files. Defaults to `false`.
+
+##### icons
+
+Display icons. Defaults to `false`.
+
+##### stylesheet
+
+Optional path to a CSS stylesheet. Defaults to a built-in stylesheet.
+
+##### template
+
+Optional path to an HTML template or a function that will render a HTML
+string. Defaults to a built-in template.
+
+When given a string, the string is used as a file path to load and then the
+following tokens are replaced in templates:
+
+- `{directory}` with the name of the directory.
+- `{files}` with the HTML of an unordered list of file links.
+- `{linked-path}` with the HTML of a link to the directory.
+- `{style}` with the specified stylesheet and embedded images.
+
+When given as a function, the function is called as `template(locals, callback)`
+and it needs to invoke `callback(error, htmlString)`. The following are the
+provided locals:
+
+- `directory` is the directory being displayed (where `/` is the root).
+- `displayIcons` is a Boolean for if icons should be rendered or not.
+- `fileList` is a sorted array of files in the directory. The array contains
+ objects with the following properties:
+ - `name` is the relative name for the file.
+ - `stat` is a `fs.Stats` object for the file.
+- `path` is the full filesystem path to `directory`.
+- `style` is the default stylesheet or the contents of the `stylesheet` option.
+- `viewName` is the view name provided by the `view` option.
+
+##### view
+
+Display mode. `tiles` and `details` are available. Defaults to `tiles`.
+
+## Examples
+
+### Serve directory indexes with vanilla node.js http server
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var serveIndex = require('serve-index');
+var serveStatic = require('serve-static');
+
+// Serve directory indexes for public/ftp folder (with icons)
+var index = serveIndex('public/ftp', { icons: true });
+
+// Serve up public/ftp folder files
+var serve = serveStatic('public/ftp');
+
+// Create server
+var server = http.createServer(function onRequest(req, res) {
+ var done = finalhandler(req, res);
+ serve(req, res, function onNext(err) {
+ if (err) return done(err);
+ index(req, res, done);
+ });
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve directory indexes with express
+
+```js
+var express = require('express');
+var serveIndex = require('serve-index');
+
+var app = express();
+
+// Serve URLs like /ftp/thing as public/ftp/thing
+// The express.static serves the file contents
+// The serveIndex is this module serving the directory
+app.use('/ftp', express.static('public/ftp'), serveIndex('public/ftp', { icons: true }));
+
+// Listen
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE). The [Silk](http://www.famfamfam.com/lab/icons/silk/) icons
+are created by/copyright of [FAMFAMFAM](http://www.famfamfam.com/).
+
+[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/serve-index/master.svg?label=windows
+[appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index
+[ci-image]: https://badgen.net/github/checks/expressjs/serve-index/master?label=ci
+[ci-url]: https://github.com/expressjs/serve-index/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/serve-index/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-index?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/serve-index.svg
+[downloads-url]: https://npmjs.org/package/serve-index
+[npm-image]: https://img.shields.io/npm/v/serve-index.svg
+[npm-url]: https://npmjs.org/package/serve-index
diff --git a/astro/src/content/resources/ko/middleware/serve-index.md b/astro/src/content/resources/ko/middleware/serve-index.md
new file mode 100644
index 0000000000..da03cf94b2
--- /dev/null
+++ b/astro/src/content/resources/ko/middleware/serve-index.md
@@ -0,0 +1,156 @@
+---
+title: Express serve-index middleware
+module: serve-index
+---
+
+# serve-index
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Linux Build Status][ci-image]][ci-url]
+[![Windows Build][appveyor-image]][appveyor-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+Serves pages that contain directory listings for a given path.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-index
+```
+
+## API
+
+```js
+var serveIndex = require('serve-index');
+```
+
+### serveIndex(path, options)
+
+Returns middlware that serves an index of the directory in the given `path`.
+
+The `path` is based off the `req.url` value, so a `req.url` of `'/some/dir`
+with a `path` of `'public'` will look at `'public/some/dir'`. If you are using
+something like `express`, you can change the URL "base" with `app.use` (see
+the express example).
+
+#### Options
+
+Serve index accepts these properties in the options object.
+
+##### filter
+
+Apply this filter function to files. Defaults to `false`. The `filter` function
+is called for each file, with the signature `filter(filename, index, files, dir)`
+where `filename` is the name of the file, `index` is the array index, `files` is
+the array of files and `dir` is the absolute path the file is located (and thus,
+the directory the listing is for).
+
+##### hidden
+
+Display hidden (dot) files. Defaults to `false`.
+
+##### icons
+
+Display icons. Defaults to `false`.
+
+##### stylesheet
+
+Optional path to a CSS stylesheet. Defaults to a built-in stylesheet.
+
+##### template
+
+Optional path to an HTML template or a function that will render a HTML
+string. Defaults to a built-in template.
+
+When given a string, the string is used as a file path to load and then the
+following tokens are replaced in templates:
+
+- `{directory}` with the name of the directory.
+- `{files}` with the HTML of an unordered list of file links.
+- `{linked-path}` with the HTML of a link to the directory.
+- `{style}` with the specified stylesheet and embedded images.
+
+When given as a function, the function is called as `template(locals, callback)`
+and it needs to invoke `callback(error, htmlString)`. The following are the
+provided locals:
+
+- `directory` is the directory being displayed (where `/` is the root).
+- `displayIcons` is a Boolean for if icons should be rendered or not.
+- `fileList` is a sorted array of files in the directory. The array contains
+ objects with the following properties:
+ - `name` is the relative name for the file.
+ - `stat` is a `fs.Stats` object for the file.
+- `path` is the full filesystem path to `directory`.
+- `style` is the default stylesheet or the contents of the `stylesheet` option.
+- `viewName` is the view name provided by the `view` option.
+
+##### view
+
+Display mode. `tiles` and `details` are available. Defaults to `tiles`.
+
+## Examples
+
+### Serve directory indexes with vanilla node.js http server
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var serveIndex = require('serve-index');
+var serveStatic = require('serve-static');
+
+// Serve directory indexes for public/ftp folder (with icons)
+var index = serveIndex('public/ftp', { icons: true });
+
+// Serve up public/ftp folder files
+var serve = serveStatic('public/ftp');
+
+// Create server
+var server = http.createServer(function onRequest(req, res) {
+ var done = finalhandler(req, res);
+ serve(req, res, function onNext(err) {
+ if (err) return done(err);
+ index(req, res, done);
+ });
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve directory indexes with express
+
+```js
+var express = require('express');
+var serveIndex = require('serve-index');
+
+var app = express();
+
+// Serve URLs like /ftp/thing as public/ftp/thing
+// The express.static serves the file contents
+// The serveIndex is this module serving the directory
+app.use('/ftp', express.static('public/ftp'), serveIndex('public/ftp', { icons: true }));
+
+// Listen
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE). The [Silk](http://www.famfamfam.com/lab/icons/silk/) icons
+are created by/copyright of [FAMFAMFAM](http://www.famfamfam.com/).
+
+[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/serve-index/master.svg?label=windows
+[appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index
+[ci-image]: https://badgen.net/github/checks/expressjs/serve-index/master?label=ci
+[ci-url]: https://github.com/expressjs/serve-index/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/serve-index/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-index?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/serve-index.svg
+[downloads-url]: https://npmjs.org/package/serve-index
+[npm-image]: https://img.shields.io/npm/v/serve-index.svg
+[npm-url]: https://npmjs.org/package/serve-index
diff --git a/astro/src/content/resources/ko/middleware/serve-static.md b/astro/src/content/resources/ko/middleware/serve-static.md
new file mode 100644
index 0000000000..b048165d7b
--- /dev/null
+++ b/astro/src/content/resources/ko/middleware/serve-static.md
@@ -0,0 +1,260 @@
+---
+title: Express serve-static middleware
+module: serve-static
+---
+
+# serve-static
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![CI][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-static
+```
+
+## API
+
+```js
+const serveStatic = require('serve-static');
+```
+
+### serveStatic(root, options)
+
+Create a new middleware function to serve files from within a given root
+directory. The file to serve will be determined by combining `req.url`
+with the provided root directory. When a file is not found, instead of
+sending a 404 response, this module will instead call `next()` to move on
+to the next middleware, allowing for stacking and fall-backs.
+
+#### Options
+
+##### acceptRanges
+
+Enable or disable accepting ranged requests, defaults to true.
+Disabling this will not send `Accept-Ranges` and ignore the contents
+of the `Range` request header.
+
+##### cacheControl
+
+Enable or disable setting `Cache-Control` response header, defaults to
+true. Disabling this will ignore the `immutable` and `maxAge` options.
+
+##### dotfiles
+
+Set how "dotfiles" are treated when encountered. A dotfile is a file
+or directory that begins with a dot ("."). Note this check is done on
+the path itself without checking if the path actually exists on the
+disk. If `root` is specified, only the dotfiles above the root are
+checked (i.e. the root itself can be within a dotfile when set
+to "deny").
+
+- `'allow'` No special treatment for dotfiles.
+- `'deny'` Deny a request for a dotfile and 403/`next()`.
+- `'ignore'` Pretend like the dotfile does not exist and 404/`next()`.
+
+The default value is `'ignore'`.
+
+##### etag
+
+Enable or disable etag generation, defaults to true.
+
+##### extensions
+
+Set file extension fallbacks. When set, if a file is not found, the given
+extensions will be added to the file name and search for. The first that
+exists will be served. Example: `['html', 'htm']`.
+
+The default value is `false`.
+
+##### fallthrough
+
+Set the middleware to have client errors fall-through as just unhandled
+requests, otherwise forward a client error. The difference is that client
+errors like a bad request or a request to a non-existent file will cause
+this middleware to simply `next()` to your next middleware when this value
+is `true`. When this value is `false`, these errors (even 404s), will invoke
+`next(err)`.
+
+Typically `true` is desired such that multiple physical directories can be
+mapped to the same web address or for routes to fill in non-existent files.
+
+The value `false` can be used if this middleware is mounted at a path that
+is designed to be strictly a single file system directory, which allows for
+short-circuiting 404s for less overhead. This middleware will also reply to
+all methods.
+
+The default value is `true`.
+
+##### immutable
+
+Enable or disable the `immutable` directive in the `Cache-Control` response
+header, defaults to `false`. If set to `true`, the `maxAge` option should
+also be specified to enable caching. The `immutable` directive will prevent
+supported clients from making conditional requests during the life of the
+`maxAge` option to check if the file has changed.
+
+##### index
+
+By default this module will send "index.html" files in response to a request
+on a directory. To disable this set `false` or to supply a new index pass a
+string or an array in preferred order.
+
+##### lastModified
+
+Enable or disable `Last-Modified` header, defaults to true. Uses the file
+system's last modified value.
+
+##### maxAge
+
+Provide a max-age in milliseconds for http caching, defaults to 0. This
+can also be a string accepted by the [ms](https://www.npmjs.org/package/ms#readme)
+module.
+
+##### redirect
+
+Redirect to trailing "/" when the pathname is a dir. Defaults to `true`.
+
+##### setHeaders
+
+Function to set custom headers on response. Alterations to the headers need to
+occur synchronously. The function is called as `fn(res, path, stat)`, where
+the arguments are:
+
+- `res` the response object
+- `path` the file path that is being sent
+- `stat` the stat object of the file that is being sent
+
+## Examples
+
+### Serve files with vanilla node.js http server
+
+```js
+const finalhandler = require('finalhandler');
+const http = require('http');
+const serveStatic = require('serve-static');
+
+// Serve up public/ftp folder
+const serve = serveStatic('public/ftp', { index: ['index.html', 'index.htm'] });
+
+// Create server
+const server = http.createServer((req, res) => {
+ serve(req, res, finalhandler(req, res));
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve all files as downloads
+
+```js
+const contentDisposition = require('content-disposition');
+const finalhandler = require('finalhandler');
+const http = require('http');
+const serveStatic = require('serve-static');
+
+// Serve up public/ftp folder
+const serve = serveStatic('public/ftp', {
+ index: false,
+ setHeaders: setHeaders,
+});
+
+// Set header to force download
+function setHeaders(res, path) {
+ res.setHeader('Content-Disposition', contentDisposition(path));
+}
+
+// Create server
+const server = http.createServer((req, res) => {
+ serve(req, res, finalhandler(req, res));
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serving using express
+
+#### Simple
+
+This is a simple example of using Express.
+
+```js
+const express = require('express');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(serveStatic('public/ftp', { index: ['default.html', 'default.htm'] }));
+app.listen(3000);
+```
+
+#### Multiple roots
+
+This example shows a simple way to search through multiple directories.
+Files are searched for in `public-optimized/` first, then `public/` second
+as a fallback.
+
+```js
+const express = require('express');
+const path = require('path');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(serveStatic(path.join(__dirname, 'public-optimized')));
+app.use(serveStatic(path.join(__dirname, 'public')));
+app.listen(3000);
+```
+
+#### Different settings for paths
+
+This example shows how to set a different max age depending on the served
+file. In this example, HTML files are not cached, while everything else
+is for 1 day.
+
+```js
+const express = require('express');
+const path = require('path');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(
+ serveStatic(path.join(__dirname, 'public'), {
+ maxAge: '1d',
+ setHeaders: setCustomCacheControl,
+ })
+);
+
+app.listen(3000);
+
+function setCustomCacheControl(res, file) {
+ if (path.extname(file) === '.html') {
+ // Custom Cache-Control for HTML files
+ res.setHeader('Cache-Control', 'public, max-age=0');
+ }
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/serve-static/master
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-static?branch=master
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/serve-static/master?label=linux
+[github-actions-ci-url]: https://github.com/expressjs/serve-static/actions/workflows/ci.yml
+[node-image]: https://badgen.net/npm/node/serve-static
+[node-url]: https://nodejs.org/en/download/
+[npm-downloads-image]: https://badgen.net/npm/dm/serve-static
+[npm-url]: https://npmjs.org/package/serve-static
+[npm-version-image]: https://badgen.net/npm/v/serve-static
diff --git a/astro/src/content/resources/ko/middleware/session.md b/astro/src/content/resources/ko/middleware/session.md
new file mode 100644
index 0000000000..90f3837a42
--- /dev/null
+++ b/astro/src/content/resources/ko/middleware/session.md
@@ -0,0 +1,1046 @@
+---
+title: Express session middleware
+module: session
+---
+
+# express-session
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][node-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install express-session
+```
+
+## API
+
+```js
+var session = require('express-session');
+```
+
+### session(options)
+
+Create a session middleware with the given `options`.
+
+**Note** Session data is _not_ saved in the cookie itself, just the session ID.
+Session data is stored server-side.
+
+**Note** Since version 1.5.0, the [`cookie-parser` middleware](https://www.npmjs.com/package/cookie-parser)
+no longer needs to be used for this module to work. This module now directly reads
+and writes cookies on `req`/`res`. Using `cookie-parser` may result in issues
+if the `secret` is not the same between this module and `cookie-parser`.
+
+**Warning** The default server-side session storage, `MemoryStore`, is _purposely_
+not designed for a production environment. It will leak memory under most
+conditions, does not scale past a single process, and is meant for debugging and
+developing.
+
+For a list of stores, see [compatible session stores](#compatible-session-stores).
+
+#### Options
+
+`express-session` accepts these properties in the options object.
+
+##### cookie
+
+Settings object for the session ID cookie. The default value is
+`{ path: '/', httpOnly: true, secure: false, maxAge: null }`.
+
+The following are options that can be set in this object.
+
+##### cookie.domain
+
+Specifies the value for the `Domain` `Set-Cookie` attribute. By default, no domain
+is set, and most clients will consider the cookie to apply to only the current
+domain.
+
+##### cookie.expires
+
+Specifies the `Date` object to be the value for the `Expires` `Set-Cookie` attribute.
+By default, no expiration is set, and most clients will consider this a
+"non-persistent cookie" and will delete it on a condition like exiting a web browser
+application.
+
+**Note** If both `expires` and `maxAge` are set in the options, then the last one
+defined in the object is what is used.
+
+**Note** The `expires` option should not be set directly; instead only use the `maxAge`
+option.
+
+##### cookie.httpOnly
+
+Specifies the `boolean` value for the `HttpOnly` `Set-Cookie` attribute. When truthy,
+the `HttpOnly` attribute is set, otherwise it is not. By default, the `HttpOnly`
+attribute is set.
+
+**Note** be careful when setting this to `true`, as compliant clients will not allow
+client-side JavaScript to see the cookie in `document.cookie`.
+
+##### cookie.maxAge
+
+Specifies the `number` (in milliseconds) to use when calculating the `Expires`
+`Set-Cookie` attribute. This is done by taking the current server time and adding
+`maxAge` milliseconds to the value to calculate an `Expires` datetime. By default,
+no maximum age is set.
+
+**Note** If both `expires` and `maxAge` are set in the options, then the last one
+defined in the object is what is used.
+
+##### cookie.partitioned
+
+Specifies the `boolean` value for the [`Partitioned` `Set-Cookie`](rfc-cutler-httpbis-partitioned-cookies)
+attribute. When truthy, the `Partitioned` attribute is set, otherwise it is not.
+By default, the `Partitioned` attribute is not set.
+
+**Note** This is an attribute that has not yet been fully standardized, and may
+change in the future. This also means many clients may ignore this attribute until
+they understand it.
+
+More information about can be found in [the proposal](https://github.com/privacycg/CHIPS).
+
+##### cookie.path
+
+Specifies the value for the `Path` `Set-Cookie`. By default, this is set to `'/'`, which
+is the root path of the domain.
+
+##### cookie.priority
+
+Specifies the `string` to be the value for the [`Priority` `Set-Cookie` attribute][rfc-west-cookie-priority-00-4.1].
+
+- `'low'` will set the `Priority` attribute to `Low`.
+- `'medium'` will set the `Priority` attribute to `Medium`, the default priority when not set.
+- `'high'` will set the `Priority` attribute to `High`.
+
+More information about the different priority levels can be found in
+[the specification][rfc-west-cookie-priority-00-4.1].
+
+**Note** This is an attribute that has not yet been fully standardized, and may change in the future.
+This also means many clients may ignore this attribute until they understand it.
+
+##### cookie.sameSite
+
+Specifies the `boolean` or `string` to be the value for the `SameSite` `Set-Cookie` attribute.
+By default, this is `false`.
+
+- `true` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
+- `false` will not set the `SameSite` attribute.
+- `'lax'` will set the `SameSite` attribute to `Lax` for lax same site enforcement.
+- `'none'` will set the `SameSite` attribute to `None` for an explicit cross-site cookie.
+- `'strict'` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
+
+More information about the different enforcement levels can be found in
+[the specification][rfc-6265bis-03-4.1.2.7].
+
+**Note** This is an attribute that has not yet been fully standardized, and may change in
+the future. This also means many clients may ignore this attribute until they understand it.
+
+**Note** There is a [draft spec](https://tools.ietf.org/html/draft-west-cookie-incrementalism-01)
+that requires that the `Secure` attribute be set to `true` when the `SameSite` attribute has been
+set to `'none'`. Some web browsers or other clients may be adopting this specification.
+
+##### cookie.secure
+
+Specifies the `boolean` value for the `Secure` `Set-Cookie` attribute. When truthy,
+the `Secure` attribute is set, otherwise it is not. By default, the `Secure`
+attribute is not set.
+
+**Note** be careful when setting this to `true`, as compliant clients will not send
+the cookie back to the server in the future if the browser does not have an HTTPS
+connection.
+
+Please note that `secure: true` is a **recommended** option. However, it requires
+an https-enabled website, i.e., HTTPS is necessary for secure cookies. If `secure`
+is set, and you access your site over HTTP, the cookie will not be set. If you
+have your node.js behind a proxy and are using `secure: true`, you need to set
+"trust proxy" in express:
+
+```js
+var app = express();
+app.set('trust proxy', 1); // trust first proxy
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ cookie: { secure: true },
+ })
+);
+```
+
+For using secure cookies in production, but allowing for testing in development,
+the following is an example of enabling this setup based on `NODE_ENV` in express:
+
+```js
+var app = express();
+var sess = {
+ secret: 'keyboard cat',
+ cookie: {},
+};
+
+if (app.get('env') === 'production') {
+ app.set('trust proxy', 1); // trust first proxy
+ sess.cookie.secure = true; // serve secure cookies
+}
+
+app.use(session(sess));
+```
+
+The `cookie.secure` option can also be set to the special value `'auto'` to have
+this setting automatically match the determined security of the connection. Be
+careful when using this setting if the site is available both as HTTP and HTTPS,
+as once the cookie is set on HTTPS, it will no longer be visible over HTTP. This
+is useful when the Express `"trust proxy"` setting is properly setup to simplify
+development vs production configuration.
+
+##### genid
+
+Function to call to generate a new session ID. Provide a function that returns
+a string that will be used as a session ID. The function is given `req` as the
+first argument if you want to use some value attached to `req` when generating
+the ID.
+
+The default value is a function which uses the `uid-safe` library to generate IDs.
+
+**NOTE** be careful to generate unique IDs so your sessions do not conflict.
+
+```js
+app.use(
+ session({
+ genid: function (req) {
+ return genuuid(); // use UUIDs for session IDs
+ },
+ secret: 'keyboard cat',
+ })
+);
+```
+
+##### name
+
+The name of the session ID cookie to set in the response (and read from in the
+request).
+
+The default value is `'connect.sid'`.
+
+**Note** if you have multiple apps running on the same hostname (this is just
+the name, i.e. `localhost` or `127.0.0.1`; different schemes and ports do not
+name a different hostname), then you need to separate the session cookies from
+each other. The simplest method is to simply set different `name`s per app.
+
+##### proxy
+
+Trust the reverse proxy when setting secure cookies (via the "X-Forwarded-Proto"
+header).
+
+The default value is `undefined`.
+
+- `true` The "X-Forwarded-Proto" header will be used.
+- `false` All headers are ignored and the connection is considered secure only
+ if there is a direct TLS/SSL connection.
+- `undefined` Uses the "trust proxy" setting from express
+
+##### resave
+
+Forces the session to be saved back to the session store, even if the session
+was never modified during the request. Depending on your store this may be
+necessary, but it can also create race conditions where a client makes two
+parallel requests to your server and changes made to the session in one
+request may get overwritten when the other request ends, even if it made no
+changes (this behavior also depends on what store you're using).
+
+The default value is `true`, but using the default has been deprecated,
+as the default will change in the future. Please research into this setting
+and choose what is appropriate to your use-case. Typically, you'll want
+`false`.
+
+How do I know if this is necessary for my store? The best way to know is to
+check with your store if it implements the `touch` method. If it does, then
+you can safely set `resave: false`. If it does not implement the `touch`
+method and your store sets an expiration date on stored sessions, then you
+likely need `resave: true`.
+
+##### rolling
+
+Force the session identifier cookie to be set on every response. The expiration
+is reset to the original [`maxAge`](#cookiemaxage), resetting the expiration
+countdown.
+
+The default value is `false`.
+
+With this enabled, the session identifier cookie will expire in
+[`maxAge`](#cookiemaxage) since the last response was sent instead of in
+[`maxAge`](#cookiemaxage) since the session was last modified by the server.
+
+This is typically used in conjunction with short, non-session-length
+[`maxAge`](#cookiemaxage) values to provide a quick timeout of the session data
+with reduced potential of it occurring during on going server interactions.
+
+**Note** When this option is set to `true` but the `saveUninitialized` option is
+set to `false`, the cookie will not be set on a response with an uninitialized
+session. This option only modifies the behavior when an existing session was
+loaded for the request.
+
+##### saveUninitialized
+
+Forces a session that is "uninitialized" to be saved to the store. A session is
+uninitialized when it is new but not modified. Choosing `false` is useful for
+implementing login sessions, reducing server storage usage, or complying with
+laws that require permission before setting a cookie. Choosing `false` will also
+help with race conditions where a client makes multiple parallel requests
+without a session.
+
+The default value is `true`, but using the default has been deprecated, as the
+default will change in the future. Please research into this setting and
+choose what is appropriate to your use-case.
+
+**Note** if you are using Session in conjunction with PassportJS, Passport
+will add an empty Passport object to the session for use after a user is
+authenticated, which will be treated as a modification to the session, causing
+it to be saved. _This has been fixed in PassportJS 0.3.0_
+
+##### secret
+
+**Required option**
+
+This is the secret used to sign the session ID cookie. The secret can be any type
+of value that is supported by Node.js `crypto.createHmac` (like a string or a
+`Buffer`). This can be either a single secret, or an array of multiple secrets. If
+an array of secrets is provided, only the first element will be used to sign the
+session ID cookie, while all the elements will be considered when verifying the
+signature in requests. The secret itself should be not easily parsed by a human and
+would best be a random set of characters. A best practice may include:
+
+- The use of environment variables to store the secret, ensuring the secret itself
+ does not exist in your repository.
+- Periodic updates of the secret, while ensuring the previous secret is in the
+ array.
+
+Using a secret that cannot be guessed will reduce the ability to hijack a session to
+only guessing the session ID (as determined by the `genid` option).
+
+Changing the secret value will invalidate all existing sessions. In order to rotate
+the secret without invalidating sessions, provide an array of secrets, with the new
+secret as first element of the array, and including previous secrets as the later
+elements.
+
+**Note** HMAC-256 is used to sign the session ID. For this reason, the secret should
+contain at least 32 bytes of entropy.
+
+##### store
+
+The session store instance, defaults to a new `MemoryStore` instance.
+
+##### unset
+
+Control the result of unsetting `req.session` (through `delete`, setting to `null`,
+etc.).
+
+The default value is `'keep'`.
+
+- `'destroy'` The session will be destroyed (deleted) when the response ends.
+- `'keep'` The session in the store will be kept, but modifications made during
+ the request are ignored and not saved.
+
+### req.session
+
+To store or access session data, simply use the request property `req.session`,
+which is (generally) serialized as JSON by the store, so nested objects
+are typically fine. For example below is a user-specific view counter:
+
+```js
+// Use the session middleware
+app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 } }));
+
+// Access the session as req.session
+app.get('/', function (req, res, next) {
+ if (req.session.views) {
+ req.session.views++;
+ res.setHeader('Content-Type', 'text/html');
+ res.write('views: ' + req.session.views + '
');
+ res.write('expires in: ' + req.session.cookie.maxAge / 1000 + 's
');
+ res.end();
+ } else {
+ req.session.views = 1;
+ res.end('welcome to the session demo. refresh!');
+ }
+});
+```
+
+#### Session.regenerate(callback)
+
+To regenerate the session simply invoke the method. Once complete,
+a new SID and `Session` instance will be initialized at `req.session`
+and the `callback` will be invoked.
+
+```js
+req.session.regenerate(function (err) {
+ // will have a new session here
+});
+```
+
+#### Session.destroy(callback)
+
+Destroys the session and will unset the `req.session` property.
+Once complete, the `callback` will be invoked.
+
+```js
+req.session.destroy(function (err) {
+ // cannot access session here
+});
+```
+
+#### Session.reload(callback)
+
+Reloads the session data from the store and re-populates the
+`req.session` object. Once complete, the `callback` will be invoked.
+
+```js
+req.session.reload(function (err) {
+ // session updated
+});
+```
+
+#### Session.save(callback)
+
+Save the session back to the store, replacing the contents on the store with the
+contents in memory (though a store may do something else--consult the store's
+documentation for exact behavior).
+
+This method is automatically called at the end of the HTTP response if the
+session data has been altered (though this behavior can be altered with various
+options in the middleware constructor). Because of this, typically this method
+does not need to be called.
+
+There are some cases where it is useful to call this method, for example,
+redirects, long-lived requests or in WebSockets.
+
+```js
+req.session.save(function (err) {
+ // session saved
+});
+```
+
+#### Session.touch()
+
+Updates the `.maxAge` property. Typically this is
+not necessary to call, as the session middleware does this for you.
+
+### req.session.id
+
+Each session has a unique ID associated with it. This property is an
+alias of [`req.sessionID`](#reqsessionid-1) and cannot be modified.
+It has been added to make the session ID accessible from the `session`
+object.
+
+### req.session.cookie
+
+Each session has a unique cookie object accompany it. This allows
+you to alter the session cookie per visitor. For example we can
+set `req.session.cookie.expires` to `false` to enable the cookie
+to remain for only the duration of the user-agent.
+
+#### Cookie.maxAge
+
+Alternatively `req.session.cookie.maxAge` will return the time
+remaining in milliseconds, which we may also re-assign a new value
+to adjust the `.expires` property appropriately. The following
+are essentially equivalent
+
+```js
+var hour = 3600000;
+req.session.cookie.expires = new Date(Date.now() + hour);
+req.session.cookie.maxAge = hour;
+```
+
+For example when `maxAge` is set to `60000` (one minute), and 30 seconds
+has elapsed it will return `30000` until the current request has completed,
+at which time `req.session.touch()` is called to reset
+`req.session.cookie.maxAge` to its original value.
+
+```js
+req.session.cookie.maxAge; // => 30000
+```
+
+#### Cookie.originalMaxAge
+
+The `req.session.cookie.originalMaxAge` property returns the original
+`maxAge` (time-to-live), in milliseconds, of the session cookie.
+
+### req.sessionID
+
+To get the ID of the loaded session, access the request property
+`req.sessionID`. This is simply a read-only value set when a session
+is loaded/created.
+
+## Session Store Implementation
+
+Every session store _must_ be an `EventEmitter` and implement specific
+methods. The following methods are the list of **required**, **recommended**,
+and **optional**.
+
+- Required methods are ones that this module will always call on the store.
+- Recommended methods are ones that this module will call on the store if
+ available.
+- Optional methods are ones this module does not call at all, but helps
+ present uniform stores to users.
+
+For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo.
+
+### store.all(callback)
+
+**Optional**
+
+This optional method is used to get all sessions in the store as an array. The
+`callback` should be called as `callback(error, sessions)`.
+
+### store.destroy(sid, callback)
+
+**Required**
+
+This required method is used to destroy/delete a session from the store given
+a session ID (`sid`). The `callback` should be called as `callback(error)` once
+the session is destroyed.
+
+### store.clear(callback)
+
+**Optional**
+
+This optional method is used to delete all sessions from the store. The
+`callback` should be called as `callback(error)` once the store is cleared.
+
+### store.length(callback)
+
+**Optional**
+
+This optional method is used to get the count of all sessions in the store.
+The `callback` should be called as `callback(error, len)`.
+
+### store.get(sid, callback)
+
+**Required**
+
+This required method is used to get a session from the store given a session
+ID (`sid`). The `callback` should be called as `callback(error, session)`.
+
+The `session` argument should be a session if found, otherwise `null` or
+`undefined` if the session was not found (and there was no error). A special
+case is made when `error.code === 'ENOENT'` to act like `callback(null, null)`.
+
+### store.set(sid, session, callback)
+
+**Required**
+
+This required method is used to upsert a session into the store given a
+session ID (`sid`) and session (`session`) object. The callback should be
+called as `callback(error)` once the session has been set in the store.
+
+### store.touch(sid, session, callback)
+
+**Recommended**
+
+This recommended method is used to "touch" a given session given a
+session ID (`sid`) and session (`session`) object. The `callback` should be
+called as `callback(error)` once the session has been touched.
+
+This is primarily used when the store will automatically delete idle sessions
+and this method is used to signal to the store the given session is active,
+potentially resetting the idle timer.
+
+## Compatible Session Stores
+
+The following modules implement a session store that is compatible with this
+module. Please make a PR to add additional modules :)
+
+[![★][aerospike-session-store-image] aerospike-session-store][aerospike-session-store-url] A session store using [Aerospike](http://www.aerospike.com/).
+
+[aerospike-session-store-url]: https://www.npmjs.com/package/aerospike-session-store
+[aerospike-session-store-image]: https://badgen.net/github/stars/aerospike/aerospike-session-store-expressjs?label=%E2%98%85
+
+[![★][better-sqlite3-session-store-image] better-sqlite3-session-store][better-sqlite3-session-store-url] A session store based on [better-sqlite3](https://github.com/JoshuaWise/better-sqlite3).
+
+[better-sqlite3-session-store-url]: https://www.npmjs.com/package/better-sqlite3-session-store
+[better-sqlite3-session-store-image]: https://badgen.net/github/stars/timdaub/better-sqlite3-session-store?label=%E2%98%85
+
+[![★][cassandra-store-image] cassandra-store][cassandra-store-url] An Apache Cassandra-based session store.
+
+[cassandra-store-url]: https://www.npmjs.com/package/cassandra-store
+[cassandra-store-image]: https://badgen.net/github/stars/webcc/cassandra-store?label=%E2%98%85
+
+[![★][cluster-store-image] cluster-store][cluster-store-url] A wrapper for using in-process / embedded
+stores - such as SQLite (via knex), leveldb, files, or memory - with node cluster (desirable for Raspberry Pi 2
+and other multi-core embedded devices).
+
+[cluster-store-url]: https://www.npmjs.com/package/cluster-store
+[cluster-store-image]: https://badgen.net/github/stars/coolaj86/cluster-store?label=%E2%98%85
+
+[![★][connect-arango-image] connect-arango][connect-arango-url] An ArangoDB-based session store.
+
+[connect-arango-url]: https://www.npmjs.com/package/connect-arango
+[connect-arango-image]: https://badgen.net/github/stars/AlexanderArvidsson/connect-arango?label=%E2%98%85
+
+[![★][connect-azuretables-image] connect-azuretables][connect-azuretables-url] An [Azure Table Storage](https://azure.microsoft.com/en-gb/services/storage/tables/)-based session store.
+
+[connect-azuretables-url]: https://www.npmjs.com/package/connect-azuretables
+[connect-azuretables-image]: https://badgen.net/github/stars/mike-goodwin/connect-azuretables?label=%E2%98%85
+
+[![★][connect-cloudant-store-image] connect-cloudant-store][connect-cloudant-store-url] An [IBM Cloudant](https://cloudant.com/)-based session store.
+
+[connect-cloudant-store-url]: https://www.npmjs.com/package/connect-cloudant-store
+[connect-cloudant-store-image]: https://badgen.net/github/stars/adriantanasa/connect-cloudant-store?label=%E2%98%85
+
+[![★][connect-cosmosdb-image] connect-cosmosdb][connect-cosmosdb-url] An Azure [Cosmos DB](https://azure.microsoft.com/en-us/products/cosmos-db/)-based session store.
+
+[connect-cosmosdb-url]: https://www.npmjs.com/package/connect-cosmosdb
+[connect-cosmosdb-image]: https://badgen.net/github/stars/thekillingspree/connect-cosmosdb?label=%E2%98%85
+
+[![★][connect-couchbase-image] connect-couchbase][connect-couchbase-url] A [couchbase](http://www.couchbase.com/)-based session store.
+
+[connect-couchbase-url]: https://www.npmjs.com/package/connect-couchbase
+[connect-couchbase-image]: https://badgen.net/github/stars/christophermina/connect-couchbase?label=%E2%98%85
+
+[![★][connect-datacache-image] connect-datacache][connect-datacache-url] An [IBM Bluemix Data Cache](http://www.ibm.com/cloud-computing/bluemix/)-based session store.
+
+[connect-datacache-url]: https://www.npmjs.com/package/connect-datacache
+[connect-datacache-image]: https://badgen.net/github/stars/adriantanasa/connect-datacache?label=%E2%98%85
+
+[![★][@google-cloud/connect-datastore-image] @google-cloud/connect-datastore][@google-cloud/connect-datastore-url] A [Google Cloud Datastore](https://cloud.google.com/datastore/docs/concepts/overview)-based session store.
+
+[@google-cloud/connect-datastore-url]: https://www.npmjs.com/package/@google-cloud/connect-datastore
+[@google-cloud/connect-datastore-image]: https://badgen.net/github/stars/GoogleCloudPlatform/cloud-datastore-session-node?label=%E2%98%85
+
+[![★][connect-db2-image] connect-db2][connect-db2-url] An IBM DB2-based session store built using [ibm_db](https://www.npmjs.com/package/ibm_db) module.
+
+[connect-db2-url]: https://www.npmjs.com/package/connect-db2
+[connect-db2-image]: https://badgen.net/github/stars/wallali/connect-db2?label=%E2%98%85
+
+[![★][connect-dynamodb-image] connect-dynamodb][connect-dynamodb-url] A DynamoDB-based session store.
+
+[connect-dynamodb-url]: https://www.npmjs.com/package/connect-dynamodb
+[connect-dynamodb-image]: https://badgen.net/github/stars/ca98am79/connect-dynamodb?label=%E2%98%85
+
+[![★][@google-cloud/connect-firestore-image] @google-cloud/connect-firestore][@google-cloud/connect-firestore-url] A [Google Cloud Firestore](https://cloud.google.com/firestore/docs/overview)-based session store.
+
+[@google-cloud/connect-firestore-url]: https://www.npmjs.com/package/@google-cloud/connect-firestore
+[@google-cloud/connect-firestore-image]: https://badgen.net/github/stars/googleapis/nodejs-firestore-session?label=%E2%98%85
+
+[![★][connect-hazelcast-image] connect-hazelcast][connect-hazelcast-url] Hazelcast session store for Connect and Express.
+
+[connect-hazelcast-url]: https://www.npmjs.com/package/connect-hazelcast
+[connect-hazelcast-image]: https://badgen.net/github/stars/huseyinbabal/connect-hazelcast?label=%E2%98%85
+
+[![★][connect-loki-image] connect-loki][connect-loki-url] A Loki.js-based session store.
+
+[connect-loki-url]: https://www.npmjs.com/package/connect-loki
+[connect-loki-image]: https://badgen.net/github/stars/Requarks/connect-loki?label=%E2%98%85
+
+[![★][connect-lowdb-image] connect-lowdb][connect-lowdb-url] A lowdb-based session store.
+
+[connect-lowdb-url]: https://www.npmjs.com/package/connect-lowdb
+[connect-lowdb-image]: https://badgen.net/github/stars/travishorn/connect-lowdb?label=%E2%98%85
+
+[![★][connect-memcached-image] connect-memcached][connect-memcached-url] A memcached-based session store.
+
+[connect-memcached-url]: https://www.npmjs.com/package/connect-memcached
+[connect-memcached-image]: https://badgen.net/github/stars/balor/connect-memcached?label=%E2%98%85
+
+[![★][connect-memjs-image] connect-memjs][connect-memjs-url] A memcached-based session store using
+[memjs](https://www.npmjs.com/package/memjs) as the memcached client.
+
+[connect-memjs-url]: https://www.npmjs.com/package/connect-memjs
+[connect-memjs-image]: https://badgen.net/github/stars/liamdon/connect-memjs?label=%E2%98%85
+
+[![★][connect-ml-image] connect-ml][connect-ml-url] A MarkLogic Server-based session store.
+
+[connect-ml-url]: https://www.npmjs.com/package/connect-ml
+[connect-ml-image]: https://badgen.net/github/stars/bluetorch/connect-ml?label=%E2%98%85
+
+[![★][connect-monetdb-image] connect-monetdb][connect-monetdb-url] A MonetDB-based session store.
+
+[connect-monetdb-url]: https://www.npmjs.com/package/connect-monetdb
+[connect-monetdb-image]: https://badgen.net/github/stars/MonetDB/npm-connect-monetdb?label=%E2%98%85
+
+[![★][connect-mongo-image] connect-mongo][connect-mongo-url] A MongoDB-based session store.
+
+[connect-mongo-url]: https://www.npmjs.com/package/connect-mongo
+[connect-mongo-image]: https://badgen.net/github/stars/kcbanner/connect-mongo?label=%E2%98%85
+
+[![★][connect-mongodb-session-image] connect-mongodb-session][connect-mongodb-session-url] Lightweight MongoDB-based session store built and maintained by MongoDB.
+
+[connect-mongodb-session-url]: https://www.npmjs.com/package/connect-mongodb-session
+[connect-mongodb-session-image]: https://badgen.net/github/stars/mongodb-js/connect-mongodb-session?label=%E2%98%85
+
+[![★][connect-mssql-v2-image] connect-mssql-v2][connect-mssql-v2-url] A Microsoft SQL Server-based session store based on [connect-mssql](https://www.npmjs.com/package/connect-mssql).
+
+[connect-mssql-v2-url]: https://www.npmjs.com/package/connect-mssql-v2
+[connect-mssql-v2-image]: https://badgen.net/github/stars/jluboff/connect-mssql-v2?label=%E2%98%85
+
+[![★][connect-neo4j-image] connect-neo4j][connect-neo4j-url] A [Neo4j](https://neo4j.com)-based session store.
+
+[connect-neo4j-url]: https://www.npmjs.com/package/connect-neo4j
+[connect-neo4j-image]: https://badgen.net/github/stars/MaxAndersson/connect-neo4j?label=%E2%98%85
+
+[![★][connect-ottoman-image] connect-ottoman][connect-ottoman-url] A [couchbase ottoman](http://www.couchbase.com/)-based session store.
+
+[connect-ottoman-url]: https://www.npmjs.com/package/connect-ottoman
+[connect-ottoman-image]: https://badgen.net/github/stars/noiissyboy/connect-ottoman?label=%E2%98%85
+
+[![★][connect-pg-simple-image] connect-pg-simple][connect-pg-simple-url] A PostgreSQL-based session store.
+
+[connect-pg-simple-url]: https://www.npmjs.com/package/connect-pg-simple
+[connect-pg-simple-image]: https://badgen.net/github/stars/voxpelli/node-connect-pg-simple?label=%E2%98%85
+
+[![★][connect-redis-image] connect-redis][connect-redis-url] A Redis-based session store.
+
+[connect-redis-url]: https://www.npmjs.com/package/connect-redis
+[connect-redis-image]: https://badgen.net/github/stars/tj/connect-redis?label=%E2%98%85
+
+[![★][connect-session-firebase-image] connect-session-firebase][connect-session-firebase-url] A session store based on the [Firebase Realtime Database](https://firebase.google.com/docs/database/)
+
+[connect-session-firebase-url]: https://www.npmjs.com/package/connect-session-firebase
+[connect-session-firebase-image]: https://badgen.net/github/stars/benweier/connect-session-firebase?label=%E2%98%85
+
+[![★][connect-session-knex-image] connect-session-knex][connect-session-knex-url] A session store using
+[Knex.js](http://knexjs.org/), which is a SQL query builder for PostgreSQL, MySQL, MariaDB, SQLite3, and Oracle.
+
+[connect-session-knex-url]: https://www.npmjs.com/package/connect-session-knex
+[connect-session-knex-image]: https://badgen.net/github/stars/llambda/connect-session-knex?label=%E2%98%85
+
+[![★][connect-session-sequelize-image] connect-session-sequelize][connect-session-sequelize-url] A session store using
+[Sequelize.js](http://sequelizejs.com/), which is a Node.js / io.js ORM for PostgreSQL, MySQL, SQLite and MSSQL.
+
+[connect-session-sequelize-url]: https://www.npmjs.com/package/connect-session-sequelize
+[connect-session-sequelize-image]: https://badgen.net/github/stars/mweibel/connect-session-sequelize?label=%E2%98%85
+
+[![★][connect-sqlite3-image] connect-sqlite3][connect-sqlite3-url] A [SQLite3](https://github.com/mapbox/node-sqlite3) session store modeled after the TJ's `connect-redis` store.
+
+[connect-sqlite3-url]: https://www.npmjs.com/package/connect-sqlite3
+[connect-sqlite3-image]: https://badgen.net/github/stars/rawberg/connect-sqlite3?label=%E2%98%85
+
+[![★][connect-typeorm-image] connect-typeorm][connect-typeorm-url] A [TypeORM](https://github.com/typeorm/typeorm)-based session store.
+
+[connect-typeorm-url]: https://www.npmjs.com/package/connect-typeorm
+[connect-typeorm-image]: https://badgen.net/github/stars/makepost/connect-typeorm?label=%E2%98%85
+
+[![★][couchdb-expression-image] couchdb-expression][couchdb-expression-url] A [CouchDB](https://couchdb.apache.org/)-based session store.
+
+[couchdb-expression-url]: https://www.npmjs.com/package/couchdb-expression
+[couchdb-expression-image]: https://badgen.net/github/stars/tkshnwesper/couchdb-expression?label=%E2%98%85
+
+[![★][dynamodb-store-image] dynamodb-store][dynamodb-store-url] A DynamoDB-based session store.
+
+[dynamodb-store-url]: https://www.npmjs.com/package/dynamodb-store
+[dynamodb-store-image]: https://badgen.net/github/stars/rafaelrpinto/dynamodb-store?label=%E2%98%85
+
+[![★][dynamodb-store-v3-image] dynamodb-store-v3][dynamodb-store-v3-url] Implementation of a session store using DynamoDB backed by the [AWS SDK for JavaScript v3](https://github.com/aws/aws-sdk-js-v3).
+
+[dynamodb-store-v3-url]: https://www.npmjs.com/package/dynamodb-store-v3
+[dynamodb-store-v3-image]: https://badgen.net/github/stars/FryDay/dynamodb-store-v3?label=%E2%98%85
+
+[![★][express-etcd-image] express-etcd][express-etcd-url] An [etcd](https://github.com/stianeikeland/node-etcd) based session store.
+
+[express-etcd-url]: https://www.npmjs.com/package/express-etcd
+[express-etcd-image]: https://badgen.net/github/stars/gildean/express-etcd?label=%E2%98%85
+
+[![★][express-mysql-session-image] express-mysql-session][express-mysql-session-url] A session store using native
+[MySQL](https://www.mysql.com/) via the [node-mysql](https://github.com/felixge/node-mysql) module.
+
+[express-mysql-session-url]: https://www.npmjs.com/package/express-mysql-session
+[express-mysql-session-image]: https://badgen.net/github/stars/chill117/express-mysql-session?label=%E2%98%85
+
+[![★][express-nedb-session-image] express-nedb-session][express-nedb-session-url] A NeDB-based session store.
+
+[express-nedb-session-url]: https://www.npmjs.com/package/express-nedb-session
+[express-nedb-session-image]: https://badgen.net/github/stars/louischatriot/express-nedb-session?label=%E2%98%85
+
+[![★][express-oracle-session-image] express-oracle-session][express-oracle-session-url] A session store using native
+[oracle](https://www.oracle.com/) via the [node-oracledb](https://www.npmjs.com/package/oracledb) module.
+
+[express-oracle-session-url]: https://www.npmjs.com/package/express-oracle-session
+[express-oracle-session-image]: https://badgen.net/github/stars/slumber86/express-oracle-session?label=%E2%98%85
+
+[![★][express-session-cache-manager-image] express-session-cache-manager][express-session-cache-manager-url]
+A store that implements [cache-manager](https://www.npmjs.com/package/cache-manager), which supports
+a [variety of storage types](https://www.npmjs.com/package/cache-manager#store-engines).
+
+[express-session-cache-manager-url]: https://www.npmjs.com/package/express-session-cache-manager
+[express-session-cache-manager-image]: https://badgen.net/github/stars/theogravity/express-session-cache-manager?label=%E2%98%85
+
+[![★][express-session-etcd3-image] express-session-etcd3][express-session-etcd3-url] An [etcd3](https://github.com/mixer/etcd3) based session store.
+
+[express-session-etcd3-url]: https://www.npmjs.com/package/express-session-etcd3
+[express-session-etcd3-image]: https://badgen.net/github/stars/willgm/express-session-etcd3?label=%E2%98%85
+
+[![★][express-session-level-image] express-session-level][express-session-level-url] A [LevelDB](https://github.com/Level/levelup) based session store.
+
+[express-session-level-url]: https://www.npmjs.com/package/express-session-level
+[express-session-level-image]: https://badgen.net/github/stars/tgohn/express-session-level?label=%E2%98%85
+
+[![★][express-session-rsdb-image] express-session-rsdb][express-session-rsdb-url] Session store based on Rocket-Store: A very simple, super fast and yet powerful, flat file database.
+
+[express-session-rsdb-url]: https://www.npmjs.com/package/express-session-rsdb
+[express-session-rsdb-image]: https://badgen.net/github/stars/paragi/express-session-rsdb?label=%E2%98%85
+
+[![★][express-sessions-image] express-sessions][express-sessions-url] A session store supporting both MongoDB and Redis.
+
+[express-sessions-url]: https://www.npmjs.com/package/express-sessions
+[express-sessions-image]: https://badgen.net/github/stars/konteck/express-sessions?label=%E2%98%85
+
+[![★][firestore-store-image] firestore-store][firestore-store-url] A [Firestore](https://github.com/hendrysadrak/firestore-store)-based session store.
+
+[firestore-store-url]: https://www.npmjs.com/package/firestore-store
+[firestore-store-image]: https://badgen.net/github/stars/hendrysadrak/firestore-store?label=%E2%98%85
+
+[![★][fortune-session-image] fortune-session][fortune-session-url] A [Fortune.js](https://github.com/fortunejs/fortune)
+based session store. Supports all backends supported by Fortune (MongoDB, Redis, Postgres, NeDB).
+
+[fortune-session-url]: https://www.npmjs.com/package/fortune-session
+[fortune-session-image]: https://badgen.net/github/stars/aliceklipper/fortune-session?label=%E2%98%85
+
+[![★][hazelcast-store-image] hazelcast-store][hazelcast-store-url] A Hazelcast-based session store built on the [Hazelcast Node Client](https://www.npmjs.com/package/hazelcast-client).
+
+[hazelcast-store-url]: https://www.npmjs.com/package/hazelcast-store
+[hazelcast-store-image]: https://badgen.net/github/stars/jackspaniel/hazelcast-store?label=%E2%98%85
+
+[![★][level-session-store-image] level-session-store][level-session-store-url] A LevelDB-based session store.
+
+[level-session-store-url]: https://www.npmjs.com/package/level-session-store
+[level-session-store-image]: https://badgen.net/github/stars/toddself/level-session-store?label=%E2%98%85
+
+[![★][lowdb-session-store-image] lowdb-session-store][lowdb-session-store-url] A [lowdb](https://www.npmjs.com/package/lowdb)-based session store.
+
+[lowdb-session-store-url]: https://www.npmjs.com/package/lowdb-session-store
+[lowdb-session-store-image]: https://badgen.net/github/stars/fhellwig/lowdb-session-store?label=%E2%98%85
+
+[![★][medea-session-store-image] medea-session-store][medea-session-store-url] A Medea-based session store.
+
+[medea-session-store-url]: https://www.npmjs.com/package/medea-session-store
+[medea-session-store-image]: https://badgen.net/github/stars/BenjaminVadant/medea-session-store?label=%E2%98%85
+
+[![★][memorystore-image] memorystore][memorystore-url] A memory session store made for production.
+
+[memorystore-url]: https://www.npmjs.com/package/memorystore
+[memorystore-image]: https://badgen.net/github/stars/roccomuso/memorystore?label=%E2%98%85
+
+[![★][mssql-session-store-image] mssql-session-store][mssql-session-store-url] A SQL Server-based session store.
+
+[mssql-session-store-url]: https://www.npmjs.com/package/mssql-session-store
+[mssql-session-store-image]: https://badgen.net/github/stars/jwathen/mssql-session-store?label=%E2%98%85
+
+[![★][nedb-session-store-image] nedb-session-store][nedb-session-store-url] An alternate NeDB-based (either in-memory or file-persisted) session store.
+
+[nedb-session-store-url]: https://www.npmjs.com/package/nedb-session-store
+[nedb-session-store-image]: https://badgen.net/github/stars/JamesMGreene/nedb-session-store?label=%E2%98%85
+
+[![★][@quixo3/prisma-session-store-image] @quixo3/prisma-session-store][@quixo3/prisma-session-store-url] A session store for the [Prisma Framework](https://www.prisma.io).
+
+[@quixo3/prisma-session-store-url]: https://www.npmjs.com/package/@quixo3/prisma-session-store
+[@quixo3/prisma-session-store-image]: https://badgen.net/github/stars/kleydon/prisma-session-store?label=%E2%98%85
+
+[![★][restsession-image] restsession][restsession-url] Store sessions utilizing a RESTful API
+
+[restsession-url]: https://www.npmjs.com/package/restsession
+[restsession-image]: https://badgen.net/github/stars/jankal/restsession?label=%E2%98%85
+
+[![★][sequelstore-connect-image] sequelstore-connect][sequelstore-connect-url] A session store using [Sequelize.js](http://sequelizejs.com/).
+
+[sequelstore-connect-url]: https://www.npmjs.com/package/sequelstore-connect
+[sequelstore-connect-image]: https://badgen.net/github/stars/MattMcFarland/sequelstore-connect?label=%E2%98%85
+
+[![★][session-file-store-image] session-file-store][session-file-store-url] A file system-based session store.
+
+[session-file-store-url]: https://www.npmjs.com/package/session-file-store
+[session-file-store-image]: https://badgen.net/github/stars/valery-barysok/session-file-store?label=%E2%98%85
+
+[![★][session-pouchdb-store-image] session-pouchdb-store][session-pouchdb-store-url] Session store for PouchDB / CouchDB. Accepts embedded, custom, or remote PouchDB instance and realtime synchronization.
+
+[session-pouchdb-store-url]: https://www.npmjs.com/package/session-pouchdb-store
+[session-pouchdb-store-image]: https://badgen.net/github/stars/solzimer/session-pouchdb-store?label=%E2%98%85
+
+[![★][@cyclic.sh/session-store-image] @cyclic.sh/session-store][@cyclic.sh/session-store-url] A DynamoDB-based session store for [Cyclic.sh](https://www.cyclic.sh/) apps.
+
+[@cyclic.sh/session-store-url]: https://www.npmjs.com/package/@cyclic.sh/session-store
+[@cyclic.sh/session-store-image]: https://badgen.net/github/stars/cyclic-software/session-store?label=%E2%98%85
+
+[![★][@databunker/session-store-image] @databunker/session-store][@databunker/session-store-url] A [Databunker](https://databunker.org/)-based encrypted session store.
+
+[@databunker/session-store-url]: https://www.npmjs.com/package/@databunker/session-store
+[@databunker/session-store-image]: https://badgen.net/github/stars/securitybunker/databunker-session-store?label=%E2%98%85
+
+[![★][sessionstore-image] sessionstore][sessionstore-url] A session store that works with various databases.
+
+[sessionstore-url]: https://www.npmjs.com/package/sessionstore
+[sessionstore-image]: https://badgen.net/github/stars/adrai/sessionstore?label=%E2%98%85
+
+[![★][tch-nedb-session-image] tch-nedb-session][tch-nedb-session-url] A file system session store based on NeDB.
+
+[tch-nedb-session-url]: https://www.npmjs.com/package/tch-nedb-session
+[tch-nedb-session-image]: https://badgen.net/github/stars/tomaschyly/NeDBSession?label=%E2%98%85
+
+## Examples
+
+### View counter
+
+A simple example using `express-session` to store page views for a user.
+
+```js
+var express = require('express');
+var parseurl = require('parseurl');
+var session = require('express-session');
+
+var app = express();
+
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ })
+);
+
+app.use(function (req, res, next) {
+ if (!req.session.views) {
+ req.session.views = {};
+ }
+
+ // get the url pathname
+ var pathname = parseurl(req).pathname;
+
+ // count the views
+ req.session.views[pathname] = (req.session.views[pathname] || 0) + 1;
+
+ next();
+});
+
+app.get('/foo', function (req, res, next) {
+ res.send('you viewed this page ' + req.session.views['/foo'] + ' times');
+});
+
+app.get('/bar', function (req, res, next) {
+ res.send('you viewed this page ' + req.session.views['/bar'] + ' times');
+});
+
+app.listen(3000);
+```
+
+### User login
+
+A simple example using `express-session` to keep a user log in session.
+
+```js
+var escapeHtml = require('escape-html');
+var express = require('express');
+var session = require('express-session');
+
+var app = express();
+
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ })
+);
+
+// middleware to test if authenticated
+function isAuthenticated(req, res, next) {
+ if (req.session.user) next();
+ else next('route');
+}
+
+app.get('/', isAuthenticated, function (req, res) {
+ // this is only called when there is an authentication user due to isAuthenticated
+ res.send('hello, ' + escapeHtml(req.session.user) + '!' + ' Logout ');
+});
+
+app.get('/', function (req, res) {
+ res.send(
+ ''
+ );
+});
+
+app.post('/login', express.urlencoded({ extended: false }), function (req, res) {
+ // login logic to validate req.body.user and req.body.pass
+ // would be implemented here. for this example any combo works
+
+ // regenerate the session, which is good practice to help
+ // guard against forms of session fixation
+ req.session.regenerate(function (err) {
+ if (err) next(err);
+
+ // store user information in session, typically a user id
+ req.session.user = req.body.user;
+
+ // save the session before redirection to ensure page
+ // load does not happen before session is saved
+ req.session.save(function (err) {
+ if (err) return next(err);
+ res.redirect('/');
+ });
+ });
+});
+
+app.get('/logout', function (req, res, next) {
+ // logout logic
+
+ // clear the user from the session object and save.
+ // this will ensure that re-using the old session id
+ // does not have a logged in user
+ req.session.user = null;
+ req.session.save(function (err) {
+ if (err) next(err);
+
+ // regenerate the session, which is good practice to help
+ // guard against forms of session fixation
+ req.session.regenerate(function (err) {
+ if (err) next(err);
+ res.redirect('/');
+ });
+ });
+});
+
+app.listen(3000);
+```
+
+## Debugging
+
+This module uses the [debug](https://www.npmjs.com/package/debug) module
+internally to log information about session operations.
+
+To see all the internal logs, set the `DEBUG` environment variable to
+`express-session` when launching your app (`npm start`, in this example):
+
+```sh
+$ DEBUG=express-session npm start
+```
+
+On Windows, use the corresponding command;
+
+```sh
+> set DEBUG=express-session & npm start
+```
+
+## License
+
+[MIT](LICENSE)
+
+[rfc-6265bis-03-4.1.2.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7
+[rfc-cutler-httpbis-partitioned-cookies]: https://tools.ietf.org/html/draft-cutler-httpbis-partitioned-cookies/
+[rfc-west-cookie-priority-00-4.1]: https://tools.ietf.org/html/draft-west-cookie-priority-00#section-4.1
+[ci-image]: https://badgen.net/github/checks/expressjs/session/master?label=ci
+[ci-url]: https://github.com/expressjs/session/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/session/master
+[coveralls-url]: https://coveralls.io/r/expressjs/session?branch=master
+[node-url]: https://nodejs.org/en/download
+[npm-downloads-image]: https://badgen.net/npm/dm/express-session
+[npm-url]: https://npmjs.org/package/express-session
+[npm-version-image]: https://badgen.net/npm/v/express-session
diff --git a/astro/src/content/resources/ko/middleware/timeout.md b/astro/src/content/resources/ko/middleware/timeout.md
new file mode 100644
index 0000000000..f6057aedfd
--- /dev/null
+++ b/astro/src/content/resources/ko/middleware/timeout.md
@@ -0,0 +1,176 @@
+---
+title: Express timeout middleware
+module: timeout
+---
+
+# connect-timeout
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][travis-image]][travis-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Times out a request in the Connect/Express application framework.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install connect-timeout
+```
+
+## API
+
+**NOTE** This module is not recommend as a "top-level" middleware (i.e.
+`app.use(timeout('5s'))`) unless you take precautions to halt your own
+middleware processing. See [as top-level middleware](#as-top-level-middleware)
+for how to use as a top-level middleware.
+
+While the library will emit a 'timeout' event when requests exceed the given
+timeout, node will continue processing the slow request until it terminates.
+Slow requests will continue to use CPU and memory, even if you are returning
+a HTTP response in the timeout callback. For better control over CPU/memory,
+you may need to find the events that are taking a long time (3rd party HTTP
+requests, disk I/O, database calls) and find a way to cancel them, and/or
+close the attached sockets.
+
+### timeout(time, [options])
+
+Returns middleware that times out in `time` milliseconds. `time` can also
+be a string accepted by the [ms](https://www.npmjs.org/package/ms#readme)
+module. On timeout, `req` will emit `"timeout"`.
+
+#### Options
+
+The `timeout` function takes an optional `options` object that may contain
+any of the following keys:
+
+##### respond
+
+Controls if this module will "respond" in the form of forwarding an error.
+If `true`, the timeout error is passed to `next()` so that you may customize
+the response behavior. This error has a `.timeout` property as well as
+`.status == 503`. This defaults to `true`.
+
+### req.clearTimeout()
+
+Clears the timeout on the request. The timeout is completely removed and
+will not fire for this request in the future.
+
+### req.timedout
+
+`true` if timeout fired; `false` otherwise.
+
+## Examples
+
+### as top-level middleware
+
+Because of the way middleware processing works, once this module
+passes the request to the next middleware (which it has to do in order
+for you to do work), it can no longer stop the flow, so you must take
+care to check if the request has timedout before you continue to act
+on the request.
+
+```javascript
+var bodyParser = require('body-parser');
+var cookieParser = require('cookie-parser');
+var express = require('express');
+var timeout = require('connect-timeout');
+
+// example of using this top-level; note the use of haltOnTimedout
+// after every middleware; it will stop the request flow on a timeout
+var app = express();
+app.use(timeout('5s'));
+app.use(bodyParser());
+app.use(haltOnTimedout);
+app.use(cookieParser());
+app.use(haltOnTimedout);
+
+// Add your routes here, etc.
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+app.listen(3000);
+```
+
+### express 3.x
+
+```javascript
+var express = require('express');
+var bodyParser = require('body-parser');
+var timeout = require('connect-timeout');
+
+var app = express();
+app.post('/save', timeout('5s'), bodyParser.json(), haltOnTimedout, function (req, res, next) {
+ savePost(req.body, function (err, id) {
+ if (err) return next(err);
+ if (req.timedout) return;
+ res.send('saved as id ' + id);
+ });
+});
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+function savePost(post, cb) {
+ setTimeout(
+ function () {
+ cb(null, (Math.random() * 40000) >>> 0);
+ },
+ (Math.random() * 7000) >>> 0
+ );
+}
+
+app.listen(3000);
+```
+
+### connect
+
+```javascript
+var bodyParser = require('body-parser');
+var connect = require('connect');
+var timeout = require('connect-timeout');
+
+var app = connect();
+app.use('/save', timeout('5s'), bodyParser.json(), haltOnTimedout, function (req, res, next) {
+ savePost(req.body, function (err, id) {
+ if (err) return next(err);
+ if (req.timedout) return;
+ res.send('saved as id ' + id);
+ });
+});
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+function savePost(post, cb) {
+ setTimeout(
+ function () {
+ cb(null, (Math.random() * 40000) >>> 0);
+ },
+ (Math.random() * 7000) >>> 0
+ );
+}
+
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/connect-timeout.svg
+[npm-url]: https://npmjs.org/package/connect-timeout
+[travis-image]: https://img.shields.io/travis/expressjs/timeout/master.svg
+[travis-url]: https://travis-ci.org/expressjs/timeout
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/timeout/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/timeout?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/connect-timeout.svg
+[downloads-url]: https://npmjs.org/package/connect-timeout
diff --git a/astro/src/content/resources/ko/middleware/vhost.md b/astro/src/content/resources/ko/middleware/vhost.md
new file mode 100644
index 0000000000..72f49d7f93
--- /dev/null
+++ b/astro/src/content/resources/ko/middleware/vhost.md
@@ -0,0 +1,174 @@
+---
+title: Express vhost middleware
+module: vhost
+---
+
+# vhost
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Install
+
+```sh
+$ npm install vhost
+```
+
+## API
+
+```js
+var vhost = require('vhost');
+```
+
+### vhost(hostname, handle)
+
+Create a new middleware function to hand off request to `handle` when the incoming
+host for the request matches `hostname`. The function is called as
+`handle(req, res, next)`, like a standard middleware.
+
+`hostname` can be a string or a RegExp object. When `hostname` is a string it can
+contain `*` to match 1 or more characters in that section of the hostname. When
+`hostname` is a RegExp, it will be forced to case-insensitive (since hostnames are)
+and will be forced to match based on the start and end of the hostname.
+
+When host is matched and the request is sent down to a vhost handler, the `req.vhost`
+property will be populated with an object. This object will have numeric properties
+corresponding to each wildcard (or capture group if RegExp object provided) and the
+`hostname` that was matched.
+
+```js
+var connect = require('connect');
+var vhost = require('vhost');
+var app = connect();
+
+app.use(
+ vhost('*.*.example.com', function handle(req, res, next) {
+ // for match of "foo.bar.example.com:8080" against "*.*.example.com":
+ console.dir(req.vhost.host); // => 'foo.bar.example.com:8080'
+ console.dir(req.vhost.hostname); // => 'foo.bar.example.com'
+ console.dir(req.vhost.length); // => 2
+ console.dir(req.vhost[0]); // => 'foo'
+ console.dir(req.vhost[1]); // => 'bar'
+ })
+);
+```
+
+## Examples
+
+### using with connect for static serving
+
+```js
+var connect = require('connect');
+var serveStatic = require('serve-static');
+var vhost = require('vhost');
+
+var mailapp = connect();
+
+// add middlewares to mailapp for mail.example.com
+
+// create app to serve static files on subdomain
+var staticapp = connect();
+staticapp.use(serveStatic('public'));
+
+// create main app
+var app = connect();
+
+// add vhost routing to main app for mail
+app.use(vhost('mail.example.com', mailapp));
+
+// route static assets for "assets-*" subdomain to get
+// around max host connections limit on browsers
+app.use(vhost('assets-*.example.com', staticapp));
+
+// add middlewares and main usage to app
+
+app.listen(3000);
+```
+
+### using with connect for user subdomains
+
+```js
+var connect = require('connect');
+var serveStatic = require('serve-static');
+var vhost = require('vhost');
+
+var mainapp = connect();
+
+// add middlewares to mainapp for the main web site
+
+// create app that will server user content from public/{username}/
+var userapp = connect();
+
+userapp.use(function (req, res, next) {
+ var username = req.vhost[0]; // username is the "*"
+
+ // pretend request was for /{username}/* for file serving
+ req.originalUrl = req.url;
+ req.url = '/' + username + req.url;
+
+ next();
+});
+userapp.use(serveStatic('public'));
+
+// create main app
+var app = connect();
+
+// add vhost routing for main app
+app.use(vhost('userpages.local', mainapp));
+app.use(vhost('www.userpages.local', mainapp));
+
+// listen on all subdomains for user pages
+app.use(vhost('*.userpages.local', userapp));
+
+app.listen(3000);
+```
+
+### using with any generic request handler
+
+```js
+var connect = require('connect');
+var http = require('http');
+var vhost = require('vhost');
+
+// create main app
+var app = connect();
+
+app.use(
+ vhost('mail.example.com', function (req, res) {
+ // handle req + res belonging to mail.example.com
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello from mail!');
+ })
+);
+
+// an external api server in any framework
+var httpServer = http.createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello from the api!');
+});
+
+app.use(
+ vhost('api.example.com', function (req, res) {
+ // handle req + res belonging to api.example.com
+ // pass the request to a standard Node.js HTTP server
+ httpServer.emit('request', req, res);
+ })
+);
+
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/vhost.svg
+[npm-url]: https://npmjs.org/package/vhost
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/vhost/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/vhost
+[downloads-image]: https://img.shields.io/npm/dm/vhost.svg
+[downloads-url]: https://npmjs.org/package/vhost
+[github-actions-ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/vhost/ci.yml?branch=master&label=ci
+[github-actions-ci-url]: https://github.com/expressjs/vhost/actions/workflows/ci.yml
diff --git a/astro/src/content/resources/ko/utils.md b/astro/src/content/resources/ko/utils.md
new file mode 100644
index 0000000000..546b2f09b4
--- /dev/null
+++ b/astro/src/content/resources/ko/utils.md
@@ -0,0 +1,22 @@
+---
+title: Express utilities
+description: Discover utility modules related to Express.js and Node.js, including tools for cookies, CSRF protection, URL parsing, routing, and more to enhance your applications.
+---
+
+## Express utility functions
+
+The [pillarjs](https://github.com/pillarjs) GitHub organization contains a number of modules
+for utility functions that may be generally useful.
+
+| Utility modules | Description |
+| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| [cookies](https://www.npmjs.com/package/cookies) | Get and set HTTP(S) cookies that can be signed to prevent tampering, using Keygrip. Can be used with the Node.js HTTP library or as Express middleware. |
+| [csrf](https://www.npmjs.com/package/csrf) | Contains the logic behind CSRF token creation and verification. Use this module to create custom CSRF middleware. |
+| [finalhandler](https://www.npmjs.com/package/finalhandler) | Function to invoke as the final step to respond to HTTP request. |
+| [parseurl](https://www.npmjs.com/package/parseurl) | Parse a URL with caching. |
+| [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) | Turn an Express-style path string such as ``/user/:name` into a regular expression. |
+| [resolve-path](https://www.npmjs.com/package/resolve-path) | Resolves a relative path against a root path with validation. |
+| [router](https://www.npmjs.com/package/router) | Simple middleware-style router. |
+| [send](https://www.npmjs.com/package/send) | Library for streaming files as a HTTP response, with support for partial responses (ranges), conditional-GET negotiation, and granular events. |
+
+For additional low-level HTTP-related modules, see [jshttp](https://github.com/jshttp).
diff --git a/astro/src/content/resources/pt-br/community.md b/astro/src/content/resources/pt-br/community.md
new file mode 100755
index 0000000000..e40d97e421
--- /dev/null
+++ b/astro/src/content/resources/pt-br/community.md
@@ -0,0 +1,70 @@
+---
+title: Express community
+description: Connect with the Express.js community, learn about the technical committee, find resources, explore community-contributed modules, and get involved in discussions.
+---
+
+# Community
+
+## Technical committee
+
+The Express technical committee meets online every two weeks (as needed) to discuss development and maintenance of Express,
+and other issues relevant to the Express project. Each meeting is typically announced in an
+[expressjs/discussions issue](https://github.com/expressjs/discussions/issues) with a link to join or view the meeting, which is
+open to all observers.
+
+The meetings are recorded; for a list of the recordings, see the [Express.js YouTube channel](https://www.youtube.com/channel/UCYjxjAeH6TRik9Iwy5nXw7g).
+
+Members of the Express technical committee are:
+
+**Active:**
+
+- [@blakeembrey](https://github.com/blakeembrey) - Blake Embrey
+- [@crandmck](https://github.com/crandmck) - Rand McKinney
+- [@LinusU](https://github.com/LinusU) - Linus Unnebäck
+- [@ulisesgascon](https://github.com/ulisesGascon) - Ulises Gascón
+- [@sheplu](https://github.com/sheplu) - Jean Burellier
+- [@wesleytodd](https://github.com/wesleytodd) - Wes Todd
+- [@jonchurch](https://github.com/jonchurch) - Jon Church
+- [@ctcpip](https://github.com/ctcpip/) - Chris de Almeida
+
+**Inactive:**
+
+- [@dougwilson](https://github.com/dougwilson) - Douglas Wilson
+- [@hacksparrow](https://github.com/hacksparrow) - Hage Yaapa
+- [@jonathanong](https://github.com/jonathanong) - jongleberry
+- [@niftylettuce](https://github.com/niftylettuce) - niftylettuce
+- [@troygoode](https://github.com/troygoode) - Troy Goode
+
+## Express is made of many modules
+
+Our vibrant community has created a large variety of extensions,
+[middleware modules](/en/resources/middleware) and higher-level frameworks.
+
+Additionally, the Express community maintains modules in these two GitHub orgs:
+
+- [jshttp](https://github.com/jshttp) modules providing useful utility functions; see [Utility modules](/en/resources/utils).
+- [pillarjs](https://github.com/pillarjs): low-level modules that Express uses internally.
+
+To keep up with what is going on in the whole community, check out the [ExpressJS StatusBoard](https://expressjs.github.io/statusboard/).
+
+## Issues
+
+If you've come across what you think is a bug, or just want to make
+a feature request open a ticket in the [issue queue](https://github.com/expressjs/express/issues).
+
+## Examples
+
+View dozens of Express application [examples](https://github.com/expressjs/express/tree/master/examples)
+in the repository covering everything from API design and authentication to template engine integration.
+
+## Github Discussions
+
+The [GitHub Discussions](https://github.com/expressjs/discussions) section is an excellent space to engage in conversations about the development and maintenance of Express, as well as to share ideas and discuss topics related to its usage.
+
+# Branding of Express.js
+
+## Express.js Logo
+
+Express is a project of the OpenJS Foundation. Please review the [trademark policy](https://trademark-policy.openjsf.org/) for information about permissible use of Express.js logos and marks.
+
+
diff --git a/astro/src/content/resources/pt-br/contributing.md b/astro/src/content/resources/pt-br/contributing.md
new file mode 100644
index 0000000000..82c6b8fed7
--- /dev/null
+++ b/astro/src/content/resources/pt-br/contributing.md
@@ -0,0 +1,482 @@
+---
+title: Contributing to Express
+description: Find out how to contribute to Express.js, including guidelines for reporting issues, submitting pull requests, becoming a collaborator, and understanding security policies.
+---
+
+# Contributing to Express
+
+### Looking to contribute to Expressjs.com? Click [here](#expressjs-website-contributing).
+
+Express and the other projects in the [expressjs organization on GitHub](https://github.com/expressjs) are projects of the [OpenJs Foundation](https://openjsf.org/).
+These projects are governed under the general policies and guidelines of the Node.js Foundation along with the additional guidelines below.
+
+- [Technical committee](#technical-committee)
+- [Community contributing guide](#community-contributing-guide)
+- [Collaborator's guide](#collaborators-guide)
+- [Security policies and procedures](#security-policies-and-procedures)
+
+## Technical committee
+
+The Express technical committee consists of active project members, and guides development and maintenance of the Express project. For more information, see [Express Community - Technical committee](/en/resources/community/#technical-committee).
+
+## Community contributing guide
+
+
+
+The goal of this document is to create a contribution process that:
+
+- Encourages new contributions.
+- Encourages contributors to remain involved.
+- Avoids unnecessary processes and bureaucracy whenever possible.
+- Creates a transparent decision making process that makes it clear how
+ contributors can be involved in decision making.
+
+### Vocabulary
+
+- A **Contributor** is any individual creating or commenting on an issue or pull request.
+- A **Committer** is a subset of contributors who have been given write access to the repository.
+- A **Project Captain** is the lead maintainer of a repository.
+- A **TC (Technical Committee)** is a group of committers representing the required technical
+ expertise to resolve rare disputes.
+- A **Triager** is a subset of contributors who have been given triage access to the repository.
+
+### Logging Issues
+
+Log an issue for any question or problem you might have. When in doubt, log an issue, and
+any additional policies about what to include will be provided in the responses. The only
+exception is security disclosures which should be sent privately.
+
+Committers may direct you to another repository, ask for additional clarifications, and
+add appropriate metadata before the issue is addressed.
+
+Please be courteous and respectful. Every participant is expected to follow the
+project's Code of Conduct.
+
+### Contributions
+
+Any change to resources in this repository must be through pull requests. This applies to all changes
+to documentation, code, binary files, etc. Even long term committers and TC members must use
+pull requests.
+
+No pull request can be merged without being reviewed.
+
+For non-trivial contributions, pull requests should sit for at least 36 hours to ensure that
+contributors in other timezones have time to review. Consideration should also be given to
+weekends and other holiday periods to ensure active committers all have reasonable time to
+become involved in the discussion and review process if they wish.
+
+The default for each contribution is that it is accepted once no committer has an objection.
+During a review, committers may also request that a specific contributor who is most versed in a
+particular area gives a "LGTM" before the PR can be merged. There is no additional "sign off"
+process for contributions to land. Once all issues brought by committers are addressed it can
+be landed by any committer.
+
+In the case of an objection being raised in a pull request by another committer, all involved
+committers should seek to arrive at a consensus by way of addressing concerns being expressed
+by discussion, compromise on the proposed change, or withdrawal of the proposed change.
+
+If a contribution is controversial and committers cannot agree about how to get it to land
+or if it should land then it should be escalated to the TC. TC members should regularly
+discuss pending contributions in order to find a resolution. It is expected that only a
+small minority of issues be brought to the TC for resolution and that discussion and
+compromise among committers be the default resolution mechanism.
+
+### Becoming a Triager
+
+Anyone can become a triager! Read more about the process of being a triager in
+[the triage process document](https://github.com/expressjs/discussions/blob/master/Triager-Guide.md).
+
+Currently, any existing [organization member](https://github.com/orgs/expressjs/people) can nominate
+a new triager. If you are interested in becoming a triager, our best advice is to actively participate
+in the community by helping triaging issues and pull requests. As well we recommend
+to engage in other community activities like attending the TC meetings, and participating in the Slack
+discussions. If you feel ready and have been helping triage some issues, reach out to an active member of the organization to ask if they'd
+be willing to support you. If they agree, they can create a pull request to formalize your nomination. In the case of an objection to the nomination, the triage team is responsible for working with the individuals involved and finding a resolution.
+
+You can also reach out to any of the [organization members](https://github.com/orgs/expressjs/people)
+if you have questions or need guidance.
+
+### Becoming a Committer
+
+All contributors who have landed significant and valuable contributions should be onboarded in a timely manner,
+and added as a committer, and be given write access to the repository.
+
+Committers are expected to follow this policy and continue to send pull requests, go through
+proper review, and have other committers merge their pull requests.
+
+### TC Process
+
+The TC uses a "consensus seeking" process for issues that are escalated to the TC.
+The group tries to find a resolution that has no open objections among TC members.
+If a consensus cannot be reached that has no objections then a majority wins vote
+is called. It is also expected that the majority of decisions made by the TC are via
+a consensus seeking process and that voting is only used as a last-resort.
+
+Resolution may involve returning the issue to project captains with suggestions on
+how to move forward towards a consensus. It is not expected that a meeting of the TC
+will resolve all issues on its agenda during that meeting and may prefer to continue
+the discussion happening among the project captains.
+
+Members can be added to the TC at any time. Any TC member can nominate another committer
+to the TC and the TC uses its standard consensus seeking process to evaluate whether or
+not to add this new member. The TC will consist of a minimum of 3 active members and a
+maximum of 10. If the TC should drop below 5 members the active TC members should nominate
+someone new. If a TC member is stepping down, they are encouraged (but not required) to
+nominate someone to take their place.
+
+TC members will be added as admin's on the Github orgs, npm orgs, and other resources as
+necessary to be effective in the role.
+
+To remain "active" a TC member should have participation within the last 12 months and miss
+no more than six consecutive TC meetings. Our goal is to increase participation, not punish
+people for any lack of participation, this guideline should be only be used as such
+(replace an inactive member with a new active one, for example). Members who do not meet this
+are expected to step down. If A TC member does not step down, an issue can be opened in the
+discussions repo to move them to inactive status. TC members who step down or are removed due
+to inactivity will be moved into inactive status.
+
+Inactive status members can become active members by self nomination if the TC is not already
+larger than the maximum of 10. They will also be given preference if, while at max size, an
+active member steps down.
+
+### Project Captains
+
+The Express TC can designate captains for individual projects/repos in the
+organizations. These captains are responsible for being the primary
+day-to-day maintainers of the repo on a technical and community front.
+Repo captains are empowered with repo ownership and package publication rights.
+When there are conflicts, especially on topics that effect the Express project
+at large, captains are responsible to raise it up to the TC and drive
+those conflicts to resolution. Captains are also responsible for making sure
+community members follow the community guidelines, maintaining the repo
+and the published package, as well as in providing user support.
+
+Like TC members, Repo captains are a subset of committers.
+
+To become a captain for a project the candidate is expected to participate in that
+project for at least 6 months as a committer prior to the request. They should have
+helped with code contributions as well as triaging issues. They are also required to
+have 2FA enabled on both their GitHub and npm accounts.
+
+Any TC member or an existing captain on the **same** repo can nominate another committer
+to the captain role. To do so, they should submit a PR to this document, updating the
+**Active Project Captains** section (while maintaining the sort order) with the project
+name, the nominee's GitHub handle, and their npm username (if different).
+
+- Repos can have as many captains as make sense for the scope of work.
+- A TC member or an existing repo captain **on the same project** can nominate a new captain.
+ Repo captains from other projects should not nominate captains for a different project.
+
+The PR will require at least 2 approvals from TC members and 2 weeks hold time to allow
+for comment and/or dissent. When the PR is merged, a TC member will add them to the
+proper GitHub/npm groups.
+
+#### Active Projects and Captains
+
+The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members)
+
+#### Current Initiative Captains
+
+The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains)
+
+### Inactivity and Emeritus Policy for Any Role
+
+To support the health and continuity of the project, all individuals holding a role within the community (such as Triager, Committer, WG member, Project Captain, or TC member) are encouraged to maintain active participation.
+
+Inactivity is defined as the absence of meaningful involvement in the project—such as contributions, code reviews, triage, meeting attendance, or discussion participation—for a continuous period of 6 months.
+
+#### Exceptions
+
+Anyone may request a temporary leave from active participation due to personal or professional reasons. In such cases, the individual should inform the relevant team or the Technical Committee (TC). During this time, the inactivity policy is paused, and the individual will not be flagged as inactive.
+
+#### Inactivity Process
+
+- If someone is deemed inactive, the individual may be transitioned to an emeritus role that reflects their past contributions. A best effort will be made to inform them that this has occurred. They may request to be reinstated when they are ready to be active again.
+- The emeritus status helps preserve a clear record of contributors who have meaningfully shaped the project over time.
+
+#### Accountability
+
+- The Technical Committee (TC) and the respective captains of each package/team are responsible for assessing activity levels and enacting this policy fairly and transparently, in coordination with other relevant teams.
+- In case of disagreement, the situation can be discussed and resolved by consensus within the TC or appropriate team.
+
+### Developer's Certificate of Origin 1.1
+
+```text
+By making a contribution to this project, I certify that:
+
+ (a) The contribution was created in whole or in part by me and I
+ have the right to submit it under the open source license
+ indicated in the file; or
+
+ (b) The contribution is based upon previous work that, to the best
+ of my knowledge, is covered under an appropriate open source
+ license and I have the right under that license to submit that
+ work with modifications, whether created in whole or in part
+ by me, under the same open source license (unless I am
+ permitted to submit under a different license), as indicated
+ in the file; or
+
+ (c) The contribution was provided directly to me by some other
+ person who certified (a), (b) or (c) and I have not modified
+ it.
+
+ (d) I understand and agree that this project and the contribution
+ are public and that a record of the contribution (including all
+ personal information I submit with it, including my sign-off) is
+ maintained indefinitely and may be redistributed consistent with
+ this project or the open source license(s) involved.
+```
+
+## Collaborator's guide
+
+
+
+### Website Issues
+
+Open issues for the expressjs.com website in https://github.com/expressjs/expressjs.com.
+
+For issues in other Express managed repos (everything in `expressjs`, `pillarjs` or `jshttp` other than `expressjs/express`), be sure to check their contributing guide and open issues and PRs in the appropriate repository.
+
+### PRs and Code contributions
+
+- Tests must pass.
+- Follow the [JavaScript Standard Style](https://standardjs.com/) and `npm run lint`.
+- If you fix a bug, add a test.
+
+### Branches
+
+Use the `master` branch for bug fixes or minor work that is intended for the
+current release stream.
+
+Use the correspondingly named branch, e.g. `6.x`, for anything intended for
+a future release of Express.
+
+### Steps for contributing
+
+1. Create an issue for the
+ bug you want to fix or the feature that you want to add.
+2. Create your own fork on GitHub, then
+ checkout your fork.
+3. Write your code in your local copy. It's good practice to create a branch for
+ each new issue you work on, although not compulsory.
+4. To run the test suite, first install the dependencies by running `npm install`,
+ then run `npm test`.
+5. Ensure your code is linted by running `npm run lint` -- fix any issue you
+ see listed.
+6. If the tests pass, you can commit your changes to your fork and then create
+ a pull request from there. Make sure to reference your issue from the pull
+ request comments by including the issue number e.g. `#123`.
+
+### Issues which are questions
+
+We will typically close any vague issues or questions that are specific to some
+app you are writing. Please double check the docs and other references before
+being trigger happy with posting a question issue.
+
+Things that will help get your question issue looked at:
+
+- Full and runnable JS code.
+- Clear description of the problem or unexpected behavior.
+- Clear description of the expected result.
+- Steps you have taken to debug it yourself.
+
+If you post a question and do not outline the above items or make it easy for
+us to understand and reproduce your issue, it will be closed.
+
+If your question meets all of the above requirements but you do not believe it needs to be looked at
+by the maintainers
+(for example, if you are just looking for community input) please open it as a discussion topic instead
+of an issue. If you
+are unsure and open an issue, we may move it to discussions if we triage them and decide they do
+not need high
+visibility or maintainer input.
+
+## Security Policies and Procedures
+
+
+
+This document outlines security procedures and general policies for the Express
+project.
+
+- [Reporting a Bug](#reporting-a-bug)
+- [Disclosure Policy](#disclosure-policy)
+- [Comments on this Policy](#comments-on-this-policy)
+
+### Reporting a Bug
+
+The Express team and community take all security bugs in Express seriously.
+Thank you for improving the security of Express. We appreciate your efforts and
+responsible disclosure and will make every effort to acknowledge your
+contributions.
+
+Report security bugs by emailing `express-security@lists.openjsf.org`.
+
+To ensure the timely response to your report, please ensure that the entirety
+of the report is contained within the email body and not solely behind a web
+link or an attachment.
+
+The lead maintainer will acknowledge your email within 48 hours, and will send a
+more detailed response within 48 hours indicating the next steps in handling
+your report. After the initial reply to your report, the security team will
+endeavor to keep you informed of the progress towards a fix and full
+announcement, and may ask for additional information or guidance.
+
+Report security bugs in third-party modules to the person or team maintaining
+the module.
+
+### Pre-release Versions
+
+Alpha and Beta releases are unstable and **not suitable for production use**.
+Vulnerabilities found in pre-releases should be reported according to the [Reporting a Bug](#reporting-a-bug) section.
+Due to the unstable nature of the branch it is not guaranteed that any fixes will be released in the next pre-release.
+
+### Disclosure Policy
+
+When the security team receives a security bug report, they will assign it to a
+primary handler. This person will coordinate the fix and release process,
+involving the following steps:
+
+- Confirm the problem and determine the affected versions.
+- Audit code to find any potential similar problems.
+- Prepare fixes for all releases still under maintenance. These fixes will be
+ released as fast as possible to npm.
+
+### The Express Threat Model
+
+We are currently working on a new version of the security model, the most updated version can be found [here](https://github.com/expressjs/security-wg/blob/main/docs/ThreatModel.md)
+
+### Comments on this Policy
+
+If you have suggestions on how this process could be improved please submit a
+pull request.
+
+---
+
+# Contributing to Expressjs.com {#expressjs-website-contributing}
+
+
+
+### The Official Documentation of the Express.js Framework
+
+This is the contribution documentation for the [expressjs.com](https://github.com/expressjs/expressjs.com) website.
+
+#### Need some ideas? These are some typical issues.
+
+1. **Website issues**: If you see anything on the site that could use a tune-up, think about how to fix it.
+ - Display or screen sizing problems
+ - Mobile responsiveness issues
+ - Missing or broken accessibility features
+ - Website outages
+ - Broken links
+ - Page structure or user interface enhancements
+
+2. **Content Issues**: Fix anything related to site content or typos.
+ - Spelling errors
+ - Incorrect/outdated Express.js documentation
+ - Missing content
+
+3. **Translation Issues**: Fix any translation errors or contribute new content.
+ - Fix spelling errors
+ - Fix incorrect/poorly translated words
+ - Check out the [Contributing translations](#contributing-translations) section below for a contributing guide.
+
+#### Want to work on a backlog issue?
+
+We often have bugs or enhancements that need work. You can find these under our repo's [Issues tab](https://github.com/expressjs/expressjs.com/issues). Check out the tags to find something that's a good match for you.
+
+#### Have an idea? Found a bug?
+
+If you've found a bug or a typo, or if you have an idea for an enhancement, you can:
+
+- Submit a [new issue](https://github.com/expressjs/expressjs.com/issues/new/choose) on our repo. Do this for larger proposals, or if you'd like to discuss or get feedback first.
+
+- Make a [GitHub pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). If you have already done work, and it's ready to go, feel free to send it our way.
+
+## Getting Started
+
+The steps below will guide you through the Expressjs.com contribution process.
+
+#### Step 1: (OPTIONAL) Open a New Issue
+
+So you've found a problem that you want to fix, or have a site enhancement you want to make.
+
+1. If you want to get feedback or discuss, open a discussion [issue](https://github.com/expressjs/expressjs.com/issues/new/choose) prior to starting work. This is not required, but encouraged for larger proposals.
+ - While we highly encourage this step, it is only for submissions proposing significant change. It helps us to clarify and focus the work, and ensure it aligns with overall project priorities.
+ - For submissions proposing minor improvements or corrections, this is not needed. You can skip this step.
+ - When opening an issue please give it a title and fill in the description section. The more details you provide, the more feedback we can give.
+
+2. After receiving your issue the Express.js documentation team will respond with feedback. We read every submission and always try to respond quickly with feedback.
+ - For submissions proposing significant change, we encourage you to follow the review process before starting work.
+
+#### Step 2: Get the Application Code Base
+
+Clone the repo and get the code:
+
+```sh
+git clone https://github.com/expressjs/expressjs.com.git
+```
+
+After you've got the code you're ready to start making your changes!
+
+But just in case you need a little extra explanation, this section below outlines the main sections of the code base, where most changes are likely to be made.
+
+**Markdown Page Files**:
+
+- These files render to html and make up the individual pages of the site. Most of the site's documentation text content is written in `md` files.
+- Change these to make changes to individual pages' content/text or markup.
+- Each language has its own complete set of pages, located under their respective language directories - all the Spanish markdown content is found in the `es` directory, for example.
+
+**Includes Partials and Layout Templates**
+
+- `_includes` are partials that are imported and reused across multiple pages.
+ - These are used to import text content for reuse across pages, such as the API documentation, e.g., `_includes > api > en > 5x`, which is included in every language.
+ - These are used to include the page components that make up site-wide user interface and periphery structure, e.g., Header, Footer, etc.
+- `_layouts` are the templates used to wrap the site's individual pages.
+ - These are used to display the structure of the site's periphery, such as the header and footer, and for injecting and displaying individual markdown pages inside the `content` tag.
+
+**Blog Markdown Files**
+
+- These files make up the individual blog posts. If you want to contribute a blog post please
+ follow the specific instructions for [How to write a blog post.](https://expressjs.com/en/blog/write-post)
+- Located under the `_posts` directory.
+
+**CSS or Javascript**
+
+- All css and js files are kept in `css` and `js` folders on the project root.
+
+The Express.js website is built using [Jekyll](https://jekyllrb.com/) and is hosted on [GitHub Pages](https://pages.github.com/).
+
+#### Step 3: Running the Application
+
+Now you'll need a way to see your changes, which means you'll need a running version of the application. You have two options.
+
+1. **Run Locally**: This gets the local version of the application up and running on your machine. Follow our [Local Setup Guide](https://github.com/expressjs/expressjs.com?tab=readme-ov-file#build-the-website-locally) to use this option.
+ - This is the recommended option for moderate to complex work.
+
+2. **Run using Deploy Preview**: Use this option if you don't want to bother with a local installation. Part of our continuous integration pipeline includes [Netlify Deploy Preview](https://docs.netlify.com/deploy/deploy-types/deploy-previews/).
+ 1. To use this you'll need to get your changes online - after you've made your first commit on your feature branch, make a _draft_ pull request.
+ 2. After the build steps are complete, you'll have access to a **Deploy Preview** tab that will run your changes on the web, rebuilding after each commit is pushed.
+ 3. After you are completely done your work, and it's ready for review, remove the draft status on your pull request and submit your work.
+
+## Contributing translations
+
+We use Crowdin to manage our translations in multiple languages and achieve automatic translation with artificial intelligence. Since these translations can be inefficient in some cases, we need help from the community to provide accurate and helpful translations.
+
+The documentation is translated into these languages:
+
+- Chinese Simplified (`zh-cn`)
+- Chinese Traditional (`zh-tw`)
+- English (`en`)
+- French (`fr`)
+- German (`de`)
+- Italian (`it`)
+- Japanese (`ja`)
+- Korean (`ko`)
+- Brazilian Portuguese (`pt-br`)
+- Spanish (`es`)
+
+### How to translate
+
+1. Request to join the Express.js Website project on [Crowdin](https://express.crowdin.com/website)
+2. [Select the language you want to translate](https://support.crowdin.com/for-translators/#starting-translation)
+3. [Start translating](https://support.crowdin.com/online-editor/)
diff --git a/astro/src/content/resources/pt-br/glossary.md b/astro/src/content/resources/pt-br/glossary.md
new file mode 100755
index 0000000000..8b45bf01eb
--- /dev/null
+++ b/astro/src/content/resources/pt-br/glossary.md
@@ -0,0 +1,62 @@
+---
+title: Express glossary
+description: A comprehensive glossary of terms related to Express.js, Node.js, middleware, routing, and other key concepts to help you understand and use Express effectively.
+---
+
+# Glossary
+
+### application
+
+In general, one or more programs that are designed to carry out operations for a specific purpose. In the context of Express, a program that uses the Express API running on the Node.js platform. Might also refer to an [app object](/en/api#express).
+
+### API
+
+Application programming interface. Spell out the abbreviation when it is first used.
+
+### Express
+
+A fast, un-opinionated, minimalist web framework for Node.js applications. In general, "Express" is preferred to "Express.js," though the latter is acceptable.
+
+### libuv
+
+A multi-platform support library which focuses on asynchronous I/O, primarily developed for use by Node.js.
+
+### middleware
+
+A function that is invoked by the Express routing layer before the final request handler, and thus sits in the middle between a raw request and the final intended route. A few fine points of terminology around middleware:
+
+- `var foo = require('middleware')` is called _requiring_ or _using_ a Node.js module. Then the statement `var mw = foo()` typically returns the middleware.
+- `app.use(mw)` is called _adding the middleware to the global processing stack_.
+- `app.get('/foo', mw, function (req, res) { ... })` is called _adding the middleware to the "GET /foo" processing stack_.
+
+### Node.js
+
+A software platform that is used to build scalable network applications. Node.js uses JavaScript as its scripting language, and achieves high throughput via non-blocking I/O and a single-threaded event loop. See [nodejs.org](https://nodejs.org/en/). **Usage note**: Initially, "Node.js," thereafter "Node".
+
+### open-source, open source
+
+When used as an adjective, hyphenate; for example: "This is open-source software." See [Open-source software on Wikipedia](http://en.wikipedia.org/wiki/Open-source_software).
+
+{% capture english-rules %}
+
+Although it is common not to hyphenate this term, we are using the standard English rules for hyphenating a compound adjective.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=english-rules %}
+
+### request
+
+An HTTP request. A client submits an HTTP request message to a server, which returns a response. The request must use one of several [request methods](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods) such as GET, POST, and so on.
+
+### response
+
+An HTTP response. A server returns an HTTP response message to the client. The response contains completion status information about the request and might also contain requested content in its message body.
+
+### route
+
+Part of a URL that identifies a resource. For example, in `http://foo.com/products/id`, "/products/id" is the route.
+
+### router
+
+See [router](/en/api#router) in the API reference.
diff --git a/astro/src/content/resources/pt-br/middleware/body-parser.md b/astro/src/content/resources/pt-br/middleware/body-parser.md
new file mode 100644
index 0000000000..e82649a95c
--- /dev/null
+++ b/astro/src/content/resources/pt-br/middleware/body-parser.md
@@ -0,0 +1,498 @@
+---
+title: Express body-parser middleware
+module: body-parser
+---
+
+# body-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+
+Node.js body parsing middleware.
+
+Parse incoming request bodies in a middleware before your handlers, available
+under the `req.body` property.
+
+**Note** As `req.body`'s shape is based on user-controlled input, all
+properties and values in this object are untrusted and should be validated
+before trusting. For example, `req.body.foo.toString()` may fail in multiple
+ways, for example the `foo` property may not be there or may not be a string,
+and `toString` may not be a function and instead a string or other user input.
+
+[Learn about the anatomy of an HTTP transaction in Node.js](https://nodejs.org/en/learn/http/anatomy-of-an-http-transaction).
+
+_This does not handle multipart bodies_, due to their complex and typically
+large nature. For multipart bodies, you may be interested in the following
+modules:
+
+- [busboy](https://www.npmjs.com/package/busboy#readme) and
+ [connect-busboy](https://www.npmjs.com/package/connect-busboy#readme)
+- [multiparty](https://www.npmjs.com/package/multiparty#readme) and
+ [connect-multiparty](https://www.npmjs.com/package/connect-multiparty#readme)
+- [formidable](https://www.npmjs.com/package/formidable#readme)
+- [multer](https://www.npmjs.com/package/multer#readme)
+
+This module provides the following parsers:
+
+- [JSON body parser](#bodyparserjsonoptions)
+- [Raw body parser](#bodyparserrawoptions)
+- [Text body parser](#bodyparsertextoptions)
+- [URL-encoded form body parser](#bodyparserurlencodedoptions)
+
+Other body parsers you might be interested in:
+
+- [body](https://www.npmjs.com/package/body#readme)
+- [co-body](https://www.npmjs.com/package/co-body#readme)
+
+## Installation
+
+```sh
+$ npm install body-parser
+```
+
+## API
+
+```js
+const bodyParser = require('body-parser');
+```
+
+The `bodyParser` object exposes various factories to create middlewares. All
+middlewares will populate the `req.body` property with the parsed body when
+the `Content-Type` request header matches the `type` option.
+
+The various errors returned by this module are described in the
+[errors section](#errors).
+
+### bodyParser.json([options])
+
+Returns middleware that only parses `json` and only looks at requests where
+the `Content-Type` header matches the `type` option. This parser accepts any
+Unicode encoding of the body and supports automatic inflation of `gzip`,
+`br` (brotli) and `deflate` encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`).
+
+#### Options
+
+The `json` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### defaultCharset
+
+Specify the default character set for the json content if the charset is not
+specified in the `Content-Type` header of the request. Defaults to `utf-8`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### reviver
+
+The `reviver` option is passed directly to `JSON.parse` as the second
+argument. You can find more information on this argument
+[in the MDN documentation about JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Example.3A_Using_the_reviver_parameter).
+
+##### strict
+
+When set to `true`, will only accept arrays and objects; when `false` will
+accept anything `JSON.parse` accepts. Defaults to `true`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not a
+function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `json`), a mime type (like `application/json`), or
+a mime type with a wildcard (like `*/*` or `*/json`). If a function, the `type`
+option is called as `fn(req)` and the request is parsed if it returns a truthy
+value. Defaults to `application/json`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.raw([options])
+
+Returns middleware that parses all bodies as a `Buffer` and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser supports automatic inflation of `gzip`, `br` (brotli) and `deflate`
+encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This will be a `Buffer` object
+of the body.
+
+#### Options
+
+The `raw` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function.
+If not a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this
+can be an extension name (like `bin`), a mime type (like
+`application/octet-stream`), or a mime type with a wildcard (like `*/*` or
+`application/*`). If a function, the `type` option is called as `fn(req)`
+and the request is parsed if it returns a truthy value. Defaults to
+`application/octet-stream`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.text([options])
+
+Returns middleware that parses all bodies as a string and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser supports automatic inflation of `gzip`, `br` (brotli) and `deflate`
+encodings.
+
+A new `body` string containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This will be a string of the
+body.
+
+#### Options
+
+The `text` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### defaultCharset
+
+Specify the default character set for the text content if the charset is not
+specified in the `Content-Type` header of the request. Defaults to `utf-8`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not
+a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `txt`), a mime type (like `text/plain`), or a mime
+type with a wildcard (like `*/*` or `text/*`). If a function, the `type`
+option is called as `fn(req)` and the request is parsed if it returns a
+truthy value. Defaults to `text/plain`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.urlencoded([options])
+
+Returns middleware that only parses `urlencoded` bodies and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser accepts only UTF-8 encoding of the body and supports automatic
+inflation of `gzip`, `br` (brotli) and `deflate` encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This object will contain
+key-value pairs, where the value can be a string or array (when `extended` is
+`false`), or any type (when `extended` is `true`).
+
+#### Options
+
+The `urlencoded` function takes an optional `options` object that may contain
+any of the following keys:
+
+##### extended
+
+The "extended" syntax allows for rich objects and arrays to be encoded into the
+URL-encoded format, allowing for a JSON-like experience with URL-encoded. For
+more information, please [see the qs
+library](https://www.npmjs.com/package/qs#readme).
+
+Defaults to `false`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### parameterLimit
+
+The `parameterLimit` option controls the maximum number of parameters that
+are allowed in the URL-encoded data. If a request contains more parameters
+than this value, a 413 will be returned to the client. Defaults to `1000`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not
+a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `urlencoded`), a mime type (like
+`application/x-www-form-urlencoded`), or a mime type with a wildcard (like
+`*/x-www-form-urlencoded`). If a function, the `type` option is called as
+`fn(req)` and the request is parsed if it returns a truthy value. Defaults
+to `application/x-www-form-urlencoded`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+##### defaultCharset
+
+The default charset to parse as, if not specified in content-type. Must be
+either `utf-8` or `iso-8859-1`. Defaults to `utf-8`.
+
+##### charsetSentinel
+
+Whether to let the value of the `utf8` parameter take precedence as the charset
+selector. It requires the form to contain a parameter named `utf8` with a value
+of `✓`. Defaults to `false`.
+
+##### interpretNumericEntities
+
+Whether to decode numeric entities such as `☺` when parsing an iso-8859-1
+form. Defaults to `false`.
+
+##### depth
+
+The `depth` option is used to configure the maximum depth of the `qs` library when `extended` is `true`. This allows you to limit the amount of keys that are parsed and can be useful to prevent certain types of abuse. Defaults to `32`. It is recommended to keep this value as low as possible.
+
+## Errors
+
+The middlewares provided by this module create errors using the
+[`http-errors` module](https://www.npmjs.com/package/http-errors). The errors
+will typically have a `status`/`statusCode` property that contains the suggested
+HTTP response code, an `expose` property to determine if the `message` property
+should be displayed to the client, a `type` property to determine the type of
+error without matching against the `message`, and a `body` property containing
+the read body, if available.
+
+The following are the common errors created, though any error can come through
+for various reasons.
+
+### content encoding unsupported
+
+This error will occur when the request had a `Content-Encoding` header that
+contained an encoding but the "inflation" option was set to `false`. The
+`status` property is set to `415`, the `type` property is set to
+`'encoding.unsupported'`, and the `charset` property will be set to the
+encoding that is unsupported.
+
+### entity parse failed
+
+This error will occur when the request contained an entity that could not be
+parsed by the middleware. The `status` property is set to `400`, the `type`
+property is set to `'entity.parse.failed'`, and the `body` property is set to
+the entity value that failed parsing.
+
+### entity verify failed
+
+This error will occur when the request contained an entity that could not be
+failed verification by the defined `verify` option. The `status` property is
+set to `403`, the `type` property is set to `'entity.verify.failed'`, and the
+`body` property is set to the entity value that failed verification.
+
+### request aborted
+
+This error will occur when the request is aborted by the client before reading
+the body has finished. The `received` property will be set to the number of
+bytes received before the request was aborted and the `expected` property is
+set to the number of expected bytes. The `status` property is set to `400`
+and `type` property is set to `'request.aborted'`.
+
+### request entity too large
+
+This error will occur when the request body's size is larger than the "limit"
+option. The `limit` property will be set to the byte limit and the `length`
+property will be set to the request body's length. The `status` property is
+set to `413` and the `type` property is set to `'entity.too.large'`.
+
+### request size did not match content length
+
+This error will occur when the request's length did not match the length from
+the `Content-Length` header. This typically occurs when the request is malformed,
+typically when the `Content-Length` header was calculated based on characters
+instead of bytes. The `status` property is set to `400` and the `type` property
+is set to `'request.size.invalid'`.
+
+### stream encoding should not be set
+
+This error will occur when something called the `req.setEncoding` method prior
+to this middleware. This module operates directly on bytes only and you cannot
+call `req.setEncoding` when using this module. The `status` property is set to
+`500` and the `type` property is set to `'stream.encoding.set'`.
+
+### stream is not readable
+
+This error will occur when the request is no longer readable when this middleware
+attempts to read it. This typically means something other than a middleware from
+this module read the request body already and the middleware was also configured to
+read the same request. The `status` property is set to `500` and the `type`
+property is set to `'stream.not.readable'`.
+
+### too many parameters
+
+This error will occur when the content of the request exceeds the configured
+`parameterLimit` for the `urlencoded` parser. The `status` property is set to
+`413` and the `type` property is set to `'parameters.too.many'`.
+
+### unsupported charset "BOGUS"
+
+This error will occur when the request had a charset parameter in the
+`Content-Type` header, but the `iconv-lite` module does not support it OR the
+parser does not support it. The charset is contained in the message as well
+as in the `charset` property. The `status` property is set to `415`, the
+`type` property is set to `'charset.unsupported'`, and the `charset` property
+is set to the charset that is unsupported.
+
+### unsupported content encoding "bogus"
+
+This error will occur when the request had a `Content-Encoding` header that
+contained an unsupported encoding. The encoding is contained in the message
+as well as in the `encoding` property. The `status` property is set to `415`,
+the `type` property is set to `'encoding.unsupported'`, and the `encoding`
+property is set to the encoding that is unsupported.
+
+### The input exceeded the depth
+
+This error occurs when using `bodyParser.urlencoded` with the `extended` property set to `true` and the input exceeds the configured `depth` option. The `status` property is set to `400`. It is recommended to review the `depth` option and evaluate if it requires a higher value. When the `depth` option is set to `32` (default value), the error will not be thrown.
+
+## Examples
+
+### Express/Connect top-level generic
+
+This example demonstrates adding a generic JSON and URL-encoded parser as a
+top-level middleware, which will parse the bodies of all incoming requests.
+This is the simplest setup.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// parse application/x-www-form-urlencoded
+app.use(bodyParser.urlencoded());
+
+// parse application/json
+app.use(bodyParser.json());
+
+app.use(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.write('you posted:\n');
+ res.end(String(JSON.stringify(req.body, null, 2)));
+});
+```
+
+### Express route-specific
+
+This example demonstrates adding body parsers specifically to the routes that
+need them. In general, this is the most recommended way to use body-parser with
+Express.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// create application/json parser
+const jsonParser = bodyParser.json();
+
+// create application/x-www-form-urlencoded parser
+const urlencodedParser = bodyParser.urlencoded();
+
+// POST /login gets urlencoded bodies
+app.post('/login', urlencodedParser, function (req, res) {
+ if (!req.body || !req.body.username) res.sendStatus(400);
+ res.send('welcome, ' + req.body.username);
+});
+
+// POST /api/users gets JSON bodies
+app.post('/api/users', jsonParser, function (req, res) {
+ if (!req.body) res.sendStatus(400);
+ // create user in req.body
+});
+```
+
+### Change accepted type for parsers
+
+All the parsers accept a `type` option which allows you to change the
+`Content-Type` that the middleware will parse.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// parse various different custom JSON types as JSON
+app.use(bodyParser.json({ type: 'application/*+json' }));
+
+// parse some custom thing into a Buffer
+app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }));
+
+// parse an HTML body into a string
+app.use(bodyParser.text({ type: 'text/html' }));
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/body-parser/ci.yml?branch=master&label=ci
+[ci-url]: https://github.com/expressjs/body-parser/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coverallsCoverage/github/expressjs/body-parser?branch=master
+[coveralls-url]: https://coveralls.io/r/expressjs/body-parser?branch=master
+[npm-downloads-image]: https://img.shields.io/npm/dm/body-parser
+[npm-url]: https://npmjs.com/package/body-parser
+[npm-version-image]: https://img.shields.io/npm/v/body-parser
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/body-parser/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/body-parser
diff --git a/astro/src/content/resources/pt-br/middleware/compression.md b/astro/src/content/resources/pt-br/middleware/compression.md
new file mode 100644
index 0000000000..6ac63fcb7a
--- /dev/null
+++ b/astro/src/content/resources/pt-br/middleware/compression.md
@@ -0,0 +1,314 @@
+---
+title: Express compression middleware
+module: compression
+---
+
+# compression
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+[![Funding][funding-image]][funding-url]
+
+Node.js compression middleware.
+
+The following compression codings are supported:
+
+- deflate
+- gzip
+- br (brotli)
+
+**Note** Brotli is supported only since Node.js versions v11.7.0 and v10.16.0.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```bash
+$ npm install compression
+```
+
+## API
+
+```js
+var compression = require('compression');
+```
+
+### compression([options])
+
+Returns the compression middleware using the given `options`. The middleware
+will attempt to compress response bodies for all requests that traverse through
+the middleware, based on the given `options`.
+
+This middleware will never compress responses that include a `Cache-Control`
+header with the [`no-transform` directive](https://tools.ietf.org/html/rfc7234#section-5.2.2.4),
+as compressing will transform the body.
+
+#### Options
+
+`compression()` accepts these properties in the options object. In addition to
+those listed below, [zlib](https://nodejs.org/api/zlib.html) options may be
+passed in to the options object or
+[brotli](https://nodejs.org/api/zlib.html#zlib_class_brotlioptions) options.
+
+##### chunkSize
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_CHUNK`, or `16384`.
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### filter
+
+Type: `Function`
+
+A function to decide if the response should be considered for compression.
+This function is called as `filter(req, res)` and is expected to return
+`true` to consider the response for compression, or `false` to not compress
+the response.
+
+The default filter function uses the [compressible](https://www.npmjs.com/package/compressible)
+module to determine if `res.getHeader('Content-Type')` is compressible.
+
+##### level
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_COMPRESSION`, or `-1`
+
+The level of zlib compression to apply to responses. A higher level will result
+in better compression, but will take longer to complete. A lower level will
+result in less compression, but will be much faster.
+
+This is an integer in the range of `0` (no compression) to `9` (maximum
+compression). The special value `-1` can be used to mean the "default
+compression level", which is a default compromise between speed and
+compression (currently equivalent to level 6).
+
+- `-1` Default compression level (also `zlib.constants.Z_DEFAULT_COMPRESSION`).
+- `0` No compression (also `zlib.constants.Z_NO_COMPRESSION`).
+- `1` Fastest compression (also `zlib.constants.Z_BEST_SPEED`).
+- `2`
+- `3`
+- `4`
+- `5`
+- `6` (currently what `zlib.constants.Z_DEFAULT_COMPRESSION` points to).
+- `7`
+- `8`
+- `9` Best compression (also `zlib.constants.Z_BEST_COMPRESSION`).
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### memLevel
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_MEMLEVEL`, or `8`
+
+This specifies how much memory should be allocated for the internal compression
+state and is an integer in the range of `1` (minimum level) and `9` (maximum
+level).
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### brotli
+
+Type: `Object`
+
+This specifies the options for configuring Brotli. See [Node.js documentation](https://nodejs.org/api/zlib.html#class-brotlioptions) for a complete list of available options.
+
+##### strategy
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_STRATEGY`
+
+This is used to tune the compression algorithm. This value only affects the
+compression ratio, not the correctness of the compressed output, even if it
+is not set appropriately.
+
+- `zlib.constants.Z_DEFAULT_STRATEGY` Use for normal data.
+- `zlib.constants.Z_FILTERED` Use for data produced by a filter (or predictor).
+ Filtered data consists mostly of small values with a somewhat random
+ distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect is to force more Huffman coding and less
+ string matching; it is somewhat intermediate between `zlib.constants.Z_DEFAULT_STRATEGY`
+ and `zlib.constants.Z_HUFFMAN_ONLY`.
+- `zlib.constants.Z_FIXED` Use to prevent the use of dynamic Huffman codes, allowing
+ for a simpler decoder for special applications.
+- `zlib.constants.Z_HUFFMAN_ONLY` Use to force Huffman encoding only (no string match).
+- `zlib.constants.Z_RLE` Use to limit match distances to one (run-length encoding).
+ This is designed to be almost as fast as `zlib.constants.Z_HUFFMAN_ONLY`, but give
+ better compression for PNG image data.
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### threshold
+
+Type: `Number` or `String`
+Default: `1kb`
+
+The byte threshold for the response body size before compression is considered
+for the response. This is a number of bytes or any string
+accepted by the [bytes](https://www.npmjs.com/package/bytes) module.
+
+**Note** this is only an advisory setting; if the response size cannot be determined
+at the time the response headers are written, then it is assumed the response is
+_over_ the threshold. To guarantee the response size can be determined, be sure
+set a `Content-Length` response header.
+
+##### windowBits
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_WINDOWBITS`, or `15`
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### enforceEncoding
+
+Type: `String`
+Default: `identity`
+
+This is the default encoding to use when the client does not specify an encoding in the request's [Accept-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) header.
+
+#### .filter
+
+The default `filter` function. This is used to construct a custom filter
+function that is an extension of the default function.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+app.use(compression({ filter: shouldCompress }));
+
+function shouldCompress(req, res) {
+ if (req.headers['x-no-compression']) {
+ // don't compress responses with this request header
+ return false;
+ }
+
+ // fallback to standard filter function
+ return compression.filter(req, res);
+}
+```
+
+### res.flush
+
+This module adds a `res.flush()` method to force the partially-compressed
+response to be flushed to the client.
+
+## Examples
+
+### express
+
+When using this module with express, simply `app.use` the module as
+high as you like. Requests that pass through the middleware will be compressed.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress all responses
+app.use(compression());
+
+// add all routes
+```
+
+### Node.js HTTP server
+
+```js
+var compression = require('compression')({ threshold: 0 });
+var http = require('http');
+
+function createServer(fn) {
+ return http.createServer(function (req, res) {
+ compression(req, res, function (err) {
+ if (err) {
+ res.statusCode = err.status || 500;
+ res.end(err.message);
+ return;
+ }
+
+ fn(req, res);
+ });
+ });
+}
+
+var server = createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello world!');
+});
+
+server.listen(3000, () => {
+ console.log('> Listening at http://localhost:3000');
+});
+```
+
+### Server-Sent Events
+
+Because of the nature of compression this module does not work out of the box
+with server-sent events. To compress content, a window of the output needs to
+be buffered up in order to get good compression. Typically when using server-sent
+events, there are certain block of data that need to reach the client.
+
+You can achieve this by calling `res.flush()` when you need the data written to
+actually make it to the client.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress responses
+app.use(compression());
+
+// server-sent event stream
+app.get('/events', function (req, res) {
+ res.setHeader('Content-Type', 'text/event-stream');
+ res.setHeader('Cache-Control', 'no-cache');
+
+ // send a ping approx every 2 seconds
+ var timer = setInterval(function () {
+ res.write('data: ping\n\n');
+
+ // !!! this is the important part
+ res.flush();
+ }, 2000);
+
+ res.on('close', function () {
+ clearInterval(timer);
+ });
+});
+```
+
+## Contributing
+
+The Express.js project welcomes all constructive contributions. Contributions take many forms,
+from code for bug fixes and enhancements, to additions and fixes to documentation, additional
+tests, triaging incoming pull requests and issues, and more!
+
+See the [Contributing Guide](https://github.com/expressjs/express/blob/master/Contributing.md) for more technical details on contributing.
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://badgen.net/npm/v/compression
+[npm-url]: https://npmjs.org/package/compression
+[downloads-image]: https://badgen.net/npm/dm/compression
+[downloads-url]: https://npmcharts.com/compare/compression?minimal=true
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/compression/master?label=CI
+[github-actions-ci-url]: https://github.com/expressjs/compression/actions?query=workflow%3Aci
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/compression/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/compression
+[funding-url]: https://opencollective.com/express
+[funding-image]: https://badgen.net/badge/icon/sponsor/pink?icon=github&label=Open%20Collective
diff --git a/astro/src/content/resources/pt-br/middleware/cookie-parser.md b/astro/src/content/resources/pt-br/middleware/cookie-parser.md
new file mode 100644
index 0000000000..2a59496387
--- /dev/null
+++ b/astro/src/content/resources/pt-br/middleware/cookie-parser.md
@@ -0,0 +1,124 @@
+---
+title: Express cookie-parser middleware
+module: cookie-parser
+---
+
+# cookie-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Parse `Cookie` header and populate `req.cookies` with an object keyed by the
+cookie names. Optionally you may enable signed cookie support by passing a
+`secret` string, which assigns `req.secret` so it may be used by other
+middleware.
+
+## Installation
+
+```sh
+$ npm install cookie-parser
+```
+
+## API
+
+```js
+var cookieParser = require('cookie-parser');
+```
+
+### cookieParser(secret, options)
+
+Create a new cookie parser middleware function using the given `secret` and
+`options`.
+
+- `secret` a string or array used for signing cookies. This is optional and if
+ not specified, will not parse signed cookies. If a string is provided, this
+ is used as the secret. If an array is provided, an attempt will be made to
+ unsign the cookie with each secret in order.
+- `options` an object that is passed to `cookie.parse` as the second option. See
+ [cookie](https://www.npmjs.org/package/cookie) for more information.
+ - `decode` a function to decode the value of the cookie
+
+The middleware will parse the `Cookie` header on the request and expose the
+cookie data as the property `req.cookies` and, if a `secret` was provided, as
+the property `req.signedCookies`. These properties are name value pairs of the
+cookie name to cookie value.
+
+When `secret` is provided, this module will unsign and validate any signed cookie
+values and move those name value pairs from `req.cookies` into `req.signedCookies`.
+A signed cookie is a cookie that has a value prefixed with `s:`. Signed cookies
+that fail signature validation will have the value `false` instead of the tampered
+value.
+
+In addition, this module supports special "JSON cookies". These are cookie where
+the value is prefixed with `j:`. When these values are encountered, the value will
+be exposed as the result of `JSON.parse`. If parsing fails, the original value will
+remain.
+
+### cookieParser.JSONCookie(str)
+
+Parse a cookie value as a JSON cookie. This will return the parsed JSON value
+if it was a JSON cookie, otherwise, it will return the passed value.
+
+### cookieParser.JSONCookies(cookies)
+
+Given an object, this will iterate over the keys and call `JSONCookie` on each
+value, replacing the original value with the parsed value. This returns the
+same object that was passed in.
+
+### cookieParser.signedCookie(str, secret)
+
+Parse a cookie value as a signed cookie. This will return the parsed unsigned
+value if it was a signed cookie and the signature was valid. If the value was
+not signed, the original value is returned. If the value was signed but the
+signature could not be validated, `false` is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+### cookieParser.signedCookies(cookies, secret)
+
+Given an object, this will iterate over the keys and check if any value is a
+signed cookie. If it is a signed cookie and the signature is valid, the key
+will be deleted from the object and added to the new object that is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+## Example
+
+```js
+var express = require('express');
+var cookieParser = require('cookie-parser');
+
+var app = express();
+app.use(cookieParser());
+
+app.get('/', function (req, res) {
+ // Cookies that have not been signed
+ console.log('Cookies: ', req.cookies);
+
+ // Cookies that have been signed
+ console.log('Signed Cookies: ', req.signedCookies);
+});
+
+app.listen(8080);
+
+// curl command that sends an HTTP request with two cookies
+// curl http://127.0.0.1:8080 --cookie "Cho=Kim;Greet=Hello"
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/cookie-parser/master?label=ci
+[ci-url]: https://github.com/expressjs/cookie-parser/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/cookie-parser/master
+[coveralls-url]: https://coveralls.io/r/expressjs/cookie-parser?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/cookie-parser
+[npm-url]: https://npmjs.org/package/cookie-parser
+[npm-version-image]: https://badgen.net/npm/v/cookie-parser
diff --git a/astro/src/content/resources/pt-br/middleware/cookie-session.md b/astro/src/content/resources/pt-br/middleware/cookie-session.md
new file mode 100644
index 0000000000..2d6d1f885b
--- /dev/null
+++ b/astro/src/content/resources/pt-br/middleware/cookie-session.md
@@ -0,0 +1,124 @@
+---
+title: Express cookie-session middleware
+module: cookie-session
+---
+
+# cookie-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Parse `Cookie` header and populate `req.cookies` with an object keyed by the
+cookie names. Optionally you may enable signed cookie support by passing a
+`secret` string, which assigns `req.secret` so it may be used by other
+middleware.
+
+## Installation
+
+```sh
+$ npm install cookie-parser
+```
+
+## API
+
+```js
+var cookieParser = require('cookie-parser');
+```
+
+### cookieParser(secret, options)
+
+Create a new cookie parser middleware function using the given `secret` and
+`options`.
+
+- `secret` a string or array used for signing cookies. This is optional and if
+ not specified, will not parse signed cookies. If a string is provided, this
+ is used as the secret. If an array is provided, an attempt will be made to
+ unsign the cookie with each secret in order.
+- `options` an object that is passed to `cookie.parse` as the second option. See
+ [cookie](https://www.npmjs.org/package/cookie) for more information.
+ - `decode` a function to decode the value of the cookie
+
+The middleware will parse the `Cookie` header on the request and expose the
+cookie data as the property `req.cookies` and, if a `secret` was provided, as
+the property `req.signedCookies`. These properties are name value pairs of the
+cookie name to cookie value.
+
+When `secret` is provided, this module will unsign and validate any signed cookie
+values and move those name value pairs from `req.cookies` into `req.signedCookies`.
+A signed cookie is a cookie that has a value prefixed with `s:`. Signed cookies
+that fail signature validation will have the value `false` instead of the tampered
+value.
+
+In addition, this module supports special "JSON cookies". These are cookie where
+the value is prefixed with `j:`. When these values are encountered, the value will
+be exposed as the result of `JSON.parse`. If parsing fails, the original value will
+remain.
+
+### cookieParser.JSONCookie(str)
+
+Parse a cookie value as a JSON cookie. This will return the parsed JSON value
+if it was a JSON cookie, otherwise, it will return the passed value.
+
+### cookieParser.JSONCookies(cookies)
+
+Given an object, this will iterate over the keys and call `JSONCookie` on each
+value, replacing the original value with the parsed value. This returns the
+same object that was passed in.
+
+### cookieParser.signedCookie(str, secret)
+
+Parse a cookie value as a signed cookie. This will return the parsed unsigned
+value if it was a signed cookie and the signature was valid. If the value was
+not signed, the original value is returned. If the value was signed but the
+signature could not be validated, `false` is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+### cookieParser.signedCookies(cookies, secret)
+
+Given an object, this will iterate over the keys and check if any value is a
+signed cookie. If it is a signed cookie and the signature is valid, the key
+will be deleted from the object and added to the new object that is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+## Example
+
+```js
+var express = require('express');
+var cookieParser = require('cookie-parser');
+
+var app = express();
+app.use(cookieParser());
+
+app.get('/', function (req, res) {
+ // Cookies that have not been signed
+ console.log('Cookies: ', req.cookies);
+
+ // Cookies that have been signed
+ console.log('Signed Cookies: ', req.signedCookies);
+});
+
+app.listen(8080);
+
+// curl command that sends an HTTP request with two cookies
+// curl http://127.0.0.1:8080 --cookie "Cho=Kim;Greet=Hello"
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/cookie-parser/master?label=ci
+[ci-url]: https://github.com/expressjs/cookie-parser/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/cookie-parser/master
+[coveralls-url]: https://coveralls.io/r/expressjs/cookie-parser?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/cookie-parser
+[npm-url]: https://npmjs.org/package/cookie-parser
+[npm-version-image]: https://badgen.net/npm/v/cookie-parser
diff --git a/astro/src/content/resources/pt-br/middleware/cors.md b/astro/src/content/resources/pt-br/middleware/cors.md
new file mode 100644
index 0000000000..55d70922cb
--- /dev/null
+++ b/astro/src/content/resources/pt-br/middleware/cors.md
@@ -0,0 +1,261 @@
+---
+title: Express cors middleware
+module: cors
+---
+
+# cors
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+CORS is a [Node.js](https://nodejs.org/en/) package for providing a [Connect](https://github.com/senchalabs/connect)/[Express](https://expressjs.com/) middleware that can be used to enable [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS) with various options.
+
+- [Installation](#installation)
+- [Usage](#usage)
+ - [Simple Usage](#simple-usage-enable-all-cors-requests)
+ - [Enable CORS for a Single Route](#enable-cors-for-a-single-route)
+ - [Configuring CORS](#configuring-cors)
+ - [Configuring CORS w/ Dynamic Origin](#configuring-cors-w-dynamic-origin)
+ - [Enabling CORS Pre-Flight](#enabling-cors-pre-flight)
+ - [Customizing CORS Settings Dynamically per Request](#customizing-cors-settings-dynamically-per-request)
+- [Configuration Options](#configuration-options)
+- [License](#license)
+- [Original Author](#original-author)
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/downloading-and-installing-packages-locally):
+
+```sh
+$ npm install cors
+```
+
+## Usage
+
+### Simple Usage (Enable _All_ CORS Requests)
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.use(cors());
+
+app.get('/products/:id', function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for all origins!' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Enable CORS for a Single Route
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.get('/products/:id', cors(), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for a Single Route' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Configuring CORS
+
+See the [configuration options](#configuration-options) for details.
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+var corsOptions = {
+ origin: 'http://example.com',
+ optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
+};
+
+app.get('/products/:id', cors(corsOptions), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for only example.com.' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Configuring CORS w/ Dynamic Origin
+
+This module supports validating the origin dynamically using a function provided
+to the `origin` option. This function will be passed a string that is the origin
+(or `undefined` if the request has no origin), and a `callback` with the signature
+`callback(error, origin)`.
+
+The `origin` argument to the callback can be any value allowed for the `origin`
+option of the middleware, except a function. See the
+[configuration options](#configuration-options) section for more information on all
+the possible value types.
+
+This function is designed to allow the dynamic loading of allowed origin(s) from
+a backing datasource, like a database.
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+var corsOptions = {
+ origin: function (origin, callback) {
+ // db.loadOrigins is an example call to load
+ // a list of origins from a backing database
+ db.loadOrigins(function (error, origins) {
+ callback(error, origins);
+ });
+ },
+};
+
+app.get('/products/:id', cors(corsOptions), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for an allowed domain.' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Enabling CORS Pre-Flight
+
+Certain CORS requests are considered 'complex' and require an initial
+`OPTIONS` request (called the "pre-flight request"). An example of a
+'complex' CORS request is one that uses an HTTP verb other than
+GET/HEAD/POST (such as DELETE) or that uses custom headers. To enable
+pre-flighting, you must add a new OPTIONS handler for the route you want
+to support:
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.options('/products/:id', cors()); // enable pre-flight request for DELETE request
+app.del('/products/:id', cors(), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for all origins!' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+You can also enable pre-flight across-the-board like so:
+
+```javascript
+app.options('*', cors()); // include before other routes
+```
+
+NOTE: When using this middleware as an application level middleware (for
+example, `app.use(cors())`), pre-flight requests are already handled for all
+routes.
+
+### Customizing CORS Settings Dynamically per Request
+
+For APIs that require different CORS configurations for specific routes or requests, you can dynamically generate CORS options based on the incoming request. The `cors` middleware allows you to achieve this by passing a function instead of static options. This function is called for each incoming request and must use the callback pattern to return the appropriate CORS options.
+
+The function accepts:
+
+1. **`req`**:
+ - The incoming request object.
+
+2. **`callback(error, corsOptions)`**:
+ - A function used to return the computed CORS options.
+ - **Arguments**:
+ - **`error`**: Pass `null` if there’s no error, or an error object to indicate a failure.
+ - **`corsOptions`**: An object specifying the CORS policy for the current request.
+
+Here’s an example that handles both public routes and restricted, credential-sensitive routes:
+
+```javascript
+var dynamicCorsOptions = function (req, callback) {
+ var corsOptions;
+ if (req.path.startsWith('/auth/connect/')) {
+ corsOptions = {
+ origin: 'http://mydomain.com', // Allow only a specific origin
+ credentials: true, // Enable cookies and credentials
+ };
+ } else {
+ corsOptions = { origin: '*' }; // Allow all origins for other routes
+ }
+ callback(null, corsOptions);
+};
+
+app.use(cors(dynamicCorsOptions));
+
+app.get('/auth/connect/twitter', function (req, res) {
+ res.send('CORS dynamically applied for Twitter authentication.');
+});
+
+app.get('/public', function (req, res) {
+ res.send('Public data with open CORS.');
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+## Configuration Options
+
+- `origin`: Configures the **Access-Control-Allow-Origin** CORS header. Possible values:
+ - `Boolean` - set `origin` to `true` to reflect the [request origin](https://datatracker.ietf.org/doc/html/draft-abarth-origin-09), as defined by `req.header('Origin')`, or set it to `false` to disable CORS.
+ - `String` - set `origin` to a specific origin. For example, if you set it to
+ - `"http://example.com"` only requests from "http://example.com" will be allowed.
+ - `"*"` for all domains to be allowed.
+ - `RegExp` - set `origin` to a regular expression pattern which will be used to test the request origin. If it's a match, the request origin will be reflected. For example the pattern `/example\.com$/` will reflect any request that is coming from an origin ending with "example.com".
+ - `Array` - set `origin` to an array of valid origins. Each origin can be a `String` or a `RegExp`. For example `["http://example1.com", /\.example2\.com$/]` will accept any request from "http://example1.com" or from a subdomain of "example2.com".
+ - `Function` - set `origin` to a function implementing some custom logic. The function takes the request origin as the first parameter and a callback (called as `callback(err, origin)`, where `origin` is a non-function value of the `origin` option) as the second.
+- `methods`: Configures the **Access-Control-Allow-Methods** CORS header. Expects a comma-delimited string (ex: 'GET,PUT,POST') or an array (ex: `['GET', 'PUT', 'POST']`).
+- `allowedHeaders`: Configures the **Access-Control-Allow-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Type,Authorization') or an array (ex: `['Content-Type', 'Authorization']`). If not specified, defaults to reflecting the headers specified in the request's **Access-Control-Request-Headers** header.
+- `exposedHeaders`: Configures the **Access-Control-Expose-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Range,X-Content-Range') or an array (ex: `['Content-Range', 'X-Content-Range']`). If not specified, no custom headers are exposed.
+- `credentials`: Configures the **Access-Control-Allow-Credentials** CORS header. Set to `true` to pass the header, otherwise it is omitted.
+- `maxAge`: Configures the **Access-Control-Max-Age** CORS header. Set to an integer to pass the header, otherwise it is omitted.
+- `preflightContinue`: Pass the CORS preflight response to the next handler.
+- `optionsSuccessStatus`: Provides a status code to use for successful `OPTIONS` requests, since some legacy browsers (IE11, various SmartTVs) choke on `204`.
+
+The default configuration is the equivalent of:
+
+```json
+{
+ "origin": "*",
+ "methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
+ "preflightContinue": false,
+ "optionsSuccessStatus": 204
+}
+```
+
+For details on the effect of each CORS header, read [this](https://web.dev/articles/cross-origin-resource-sharing) article.
+
+## License
+
+[MIT License](http://www.opensource.org/licenses/mit-license.php)
+
+## Original Author
+
+[Troy Goode](https://github.com/TroyGoode) ([troygoode@gmail.com](mailto:troygoode@gmail.com))
+
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/cors/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/cors?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/cors.svg
+[downloads-url]: https://npmjs.com/package/cors
+[github-actions-ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/cors/ci.yml?branch=master&label=ci
+[github-actions-ci-url]: https://github.com/expressjs/cors?query=workflow%3Aci
+[npm-image]: https://img.shields.io/npm/v/cors.svg
+[npm-url]: https://npmjs.com/package/cors
diff --git a/astro/src/content/resources/pt-br/middleware/errorhandler.md b/astro/src/content/resources/pt-br/middleware/errorhandler.md
new file mode 100644
index 0000000000..20df618320
--- /dev/null
+++ b/astro/src/content/resources/pt-br/middleware/errorhandler.md
@@ -0,0 +1,133 @@
+---
+title: Express errorhandler middleware
+module: errorhandler
+---
+
+# errorhandler
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Development-only error handler middleware.
+
+This middleware is only intended to be used in a development environment, as
+the _full error stack traces and internal details of any object passed to this
+module_ will be sent back to the client when an error occurs.
+
+When an object is provided to Express as an error, this module will display
+as much about this object as possible, and will do so by using content negotiation
+for the response between HTML, JSON, and plain text.
+
+- When the object is a standard `Error` object, the string provided by the
+ `stack` property will be returned in HTML/text responses.
+- When the object is a non-`Error` object, the result of
+ [util.inspect](https://nodejs.org/api/util.html#util_util_inspect_object_options)
+ will be returned in HTML/text responses.
+- For JSON responses, the result will be an object with all enumerable properties
+ from the object in the response.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install errorhandler
+```
+
+## API
+
+
+
+```js
+var errorhandler = require('errorhandler');
+```
+
+### errorhandler(options)
+
+Create new middleware to handle errors and respond with content negotiation.
+
+#### Options
+
+Error handler accepts these properties in the options object.
+
+##### log
+
+Provide a function to be called with the error and a string representation of
+the error. Can be used to write the error to any desired location, or set to
+`false` to only send the error back in the response. Called as
+`log(err, str, req, res)` where `err` is the `Error` object, `str` is a string
+representation of the error, `req` is the request object and `res` is the
+response object (note, this function is invoked _after_ the response has been
+written).
+
+The default value for this option is `true` unless `process.env.NODE_ENV === 'test'`.
+
+Possible values:
+
+- `true`: Log errors using `console.error(str)`.
+- `false`: Only send the error back in the response.
+- A function: pass the error to a function for handling.
+
+## Examples
+
+### Simple example
+
+Basic example of adding this middleware as the error handler only in development
+with `connect` (`express` also can be used in this example).
+
+```js
+var connect = require('connect');
+var errorhandler = require('errorhandler');
+
+var app = connect();
+
+// assumes NODE_ENV is set by the user
+if (process.env.NODE_ENV === 'development') {
+ // only use in development
+ app.use(errorhandler());
+}
+```
+
+### Custom output location
+
+Sometimes you may want to output the errors to a different location than STDERR
+during development, like a system notification, for example.
+
+
+
+```js
+var connect = require('connect');
+var errorhandler = require('errorhandler');
+var notifier = require('node-notifier');
+
+var app = connect();
+
+// assumes NODE_ENV is set by the user
+if (process.env.NODE_ENV === 'development') {
+ // only use in development
+ app.use(errorhandler({ log: errorNotification }));
+}
+
+function errorNotification(err, str, req) {
+ var title = 'Error in ' + req.method + ' ' + req.url;
+
+ notifier.notify({
+ title: title,
+ message: str,
+ });
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/errorhandler/master
+[coveralls-url]: https://coveralls.io/r/expressjs/errorhandler?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/errorhandler
+[npm-url]: https://npmjs.org/package/errorhandler
+[npm-version-image]: https://badgen.net/npm/v/errorhandler
diff --git a/astro/src/content/resources/pt-br/middleware/method-override.md b/astro/src/content/resources/pt-br/middleware/method-override.md
new file mode 100644
index 0000000000..7b97ab855e
--- /dev/null
+++ b/astro/src/content/resources/pt-br/middleware/method-override.md
@@ -0,0 +1,187 @@
+---
+title: Express method-override middleware
+module: method-override
+---
+
+# method-override
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][travis-image]][travis-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Lets you use HTTP verbs such as PUT or DELETE in places where the client doesn't support it.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install method-override
+```
+
+## API
+
+**NOTE** It is very important that this module is used **before** any module that
+needs to know the method of the request (for example, it _must_ be used prior to
+the `csurf` module).
+
+### methodOverride(getter, options)
+
+Create a new middleware function to override the `req.method` property with a new
+value. This value will be pulled from the provided `getter`.
+
+- `getter` - The getter to use to look up the overridden request method for the request. (default: `X-HTTP-Method-Override`)
+- `options.methods` - The allowed methods the original request must be in to check for a method override value. (default: `['POST']`)
+
+If the found method is supported by node.js core, then `req.method` will be set to
+this value, as if it has originally been that value. The previous `req.method`
+value will be stored in `req.originalMethod`.
+
+#### getter
+
+This is the method of getting the override value from the request. If a function is provided,
+the `req` is passed as the first argument, the `res` as the second argument and the method is
+expected to be returned. If a string is provided, the string is used to look up the method
+with the following rules:
+
+- If the string starts with `X-`, then it is treated as the name of a header and that header
+ is used for the method override. If the request contains the same header multiple times, the
+ first occurrence is used.
+- All other strings are treated as a key in the URL query string.
+
+#### options.methods
+
+This allows the specification of what methods(s) the request _MUST_ be in in order to check for
+the method override value. This defaults to only `POST` methods, which is the only method the
+override should arrive in. More methods may be specified here, but it may introduce security
+issues and cause weird behavior when requests travel through caches. This value is an array
+of methods in upper-case. `null` can be specified to allow all methods.
+
+## Examples
+
+### override using a header
+
+To use a header to override the method, specify the header name
+as a string argument to the `methodOverride` function. To then make
+the call, send a `POST` request to a URL with the overridden method
+as the value of that header. This method of using a header would
+typically be used in conjunction with `XMLHttpRequest` on implementations
+that do not support the method you are trying to use.
+
+```js
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// override with the X-HTTP-Method-Override header in the request
+app.use(methodOverride('X-HTTP-Method-Override'));
+```
+
+Example call with header override using `XMLHttpRequest`:
+
+
+
+```js
+const xhr = new XMLHttpRequest();
+xhr.onload = onload;
+xhr.open('post', '/resource', true);
+xhr.setRequestHeader('X-HTTP-Method-Override', 'DELETE');
+xhr.send();
+
+function onload() {
+ alert('got response: ' + this.responseText);
+}
+```
+
+### override using a query value
+
+To use a query string value to override the method, specify the query
+string key as a string argument to the `methodOverride` function. To
+then make the call, send a `POST` request to a URL with the overridden
+method as the value of that query string key. This method of using a
+query value would typically be used in conjunction with plain HTML
+`
+```
+
+### multiple format support
+
+```js
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// override with different headers; last one takes precedence
+app.use(methodOverride('X-HTTP-Method')); // Microsoft
+app.use(methodOverride('X-HTTP-Method-Override')); // Google/GData
+app.use(methodOverride('X-Method-Override')); // IBM
+```
+
+### custom logic
+
+You can implement any kind of custom logic with a function for the `getter`. The following
+implements the logic for looking in `req.body` that was in `method-override@1`:
+
+```js
+const bodyParser = require('body-parser');
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// NOTE: when using req.body, you must fully parse the request body
+// before you call methodOverride() in your middleware stack,
+// otherwise req.body will not be populated.
+app.use(bodyParser.urlencoded());
+app.use(
+ methodOverride(function (req, res) {
+ if (req.body && typeof req.body === 'object' && '_method' in req.body) {
+ // look in urlencoded POST bodies and delete it
+ const method = req.body._method;
+ delete req.body._method;
+ return method;
+ }
+ })
+);
+```
+
+Example call with query override using HTML `
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/method-override.svg
+[npm-url]: https://npmjs.org/package/method-override
+[travis-image]: https://img.shields.io/travis/expressjs/method-override/master.svg
+[travis-url]: https://travis-ci.org/expressjs/method-override
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/method-override/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/method-override?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/method-override.svg
+[downloads-url]: https://npmjs.org/package/method-override
diff --git a/astro/src/content/resources/pt-br/middleware/morgan.md b/astro/src/content/resources/pt-br/middleware/morgan.md
new file mode 100644
index 0000000000..5319d93d57
--- /dev/null
+++ b/astro/src/content/resources/pt-br/middleware/morgan.md
@@ -0,0 +1,458 @@
+---
+title: Express morgan middleware
+module: morgan
+---
+
+# morgan
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+HTTP request logger middleware for node.js
+
+> Named after [Dexter](http://en.wikipedia.org/wiki/Dexter_Morgan), a show you should not watch until completion.
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install morgan
+```
+
+## API
+
+
+
+```js
+var morgan = require('morgan');
+```
+
+### morgan(format, options)
+
+Create a new morgan logger middleware function using the given `format` and `options`.
+The `format` argument may be a string of a predefined name (see below for the names),
+a string of a format string, or a function that will produce a log entry.
+
+The `format` function will be called with three arguments `tokens`, `req`, and `res`,
+where `tokens` is an object with all defined tokens, `req` is the HTTP request and `res`
+is the HTTP response. The function is expected to return a string that will be the log
+line, or `undefined` / `null` to skip logging.
+
+#### Using a predefined format string
+
+
+
+```js
+morgan('tiny');
+```
+
+#### Using format string of predefined tokens
+
+
+
+```js
+morgan(':method :url :status :res[content-length] - :response-time ms');
+```
+
+#### Using a custom format function
+
+
+
+```js
+morgan(function (tokens, req, res) {
+ return [
+ tokens.method(req, res),
+ tokens.url(req, res),
+ tokens.status(req, res),
+ tokens.res(req, res, 'content-length'),
+ '-',
+ tokens['response-time'](req, res),
+ 'ms',
+ ].join(' ');
+});
+```
+
+#### Options
+
+Morgan accepts these properties in the options object.
+
+##### immediate
+
+Write log line on request instead of response. This means that a requests will
+be logged even if the server crashes, _but data from the response (like the
+response code, content length, etc.) cannot be logged_.
+
+##### skip
+
+Function to determine if logging is skipped, defaults to `false`. This function
+will be called as `skip(req, res)`.
+
+
+
+```js
+// EXAMPLE: only log error responses
+morgan('combined', {
+ skip: function (req, res) {
+ return res.statusCode < 400;
+ },
+});
+```
+
+##### stream
+
+Output stream for writing log lines, defaults to `process.stdout`.
+
+#### Predefined Formats
+
+There are various pre-defined formats provided:
+
+##### combined
+
+Standard Apache combined log output.
+
+```
+:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"
+# will output
+::1 - - [27/Nov/2024:06:21:42 +0000] "GET /combined HTTP/1.1" 200 2 "-" "curl/8.7.1"
+```
+
+##### common
+
+Standard Apache common log output.
+
+```
+:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length]
+# will output
+::1 - - [27/Nov/2024:06:21:46 +0000] "GET /common HTTP/1.1" 200 2
+```
+
+##### dev
+
+Concise output colored by response status for development use. The `:status`
+token will be colored green for success codes, red for server error codes,
+yellow for client error codes, cyan for redirection codes, and uncolored
+for information codes.
+
+```
+:method :url :status :response-time ms - :res[content-length]
+# will output
+GET /dev 200 0.224 ms - 2
+```
+
+##### short
+
+Shorter than default, also including response time.
+
+```
+:remote-addr :remote-user :method :url HTTP/:http-version :status :res[content-length] - :response-time ms
+# will output
+::1 - GET /short HTTP/1.1 200 2 - 0.283 ms
+```
+
+##### tiny
+
+The minimal output.
+
+```
+:method :url :status :res[content-length] - :response-time ms
+# will output
+GET /tiny 200 2 - 0.188 ms
+```
+
+#### Tokens
+
+##### Creating new tokens
+
+To define a token, simply invoke `morgan.token()` with the name and a callback function.
+This callback function is expected to return a string value. The value returned is then
+available as ":type" in this case:
+
+
+
+```js
+morgan.token('type', function (req, res) {
+ return req.headers['content-type'];
+});
+```
+
+Calling `morgan.token()` using the same name as an existing token will overwrite that
+token definition.
+
+The token function is expected to be called with the arguments `req` and `res`, representing
+the HTTP request and HTTP response. Additionally, the token can accept further arguments of
+it's choosing to customize behavior.
+
+##### :date[format]
+
+The current date and time in UTC. The available formats are:
+
+- `clf` for the common log format (`"10/Oct/2000:13:55:36 +0000"`)
+- `iso` for the common ISO 8601 date time format (`2000-10-10T13:55:36.000Z`)
+- `web` for the common RFC 1123 date time format (`Tue, 10 Oct 2000 13:55:36 GMT`)
+
+If no format is given, then the default is `web`.
+
+##### :http-version
+
+The HTTP version of the request.
+
+##### :method
+
+The HTTP method of the request.
+
+##### :pid
+
+The process ID of the Node.js process handling the request.
+
+##### :referrer
+
+The Referrer header of the request. This will use the standard mis-spelled Referer header if exists, otherwise Referrer.
+
+##### :remote-addr
+
+The remote address of the request. This will use `req.ip`, otherwise the standard `req.connection.remoteAddress` value (socket address).
+
+##### :remote-user
+
+The user authenticated as part of Basic auth for the request.
+
+##### :req[header]
+
+The given `header` of the request. If the header is not present, the
+value will be displayed as `"-"` in the log.
+
+##### :res[header]
+
+The given `header` of the response. If the header is not present, the
+value will be displayed as `"-"` in the log.
+
+##### :response-time[digits]
+
+The time between the request coming into `morgan` and when the response
+headers are written, in milliseconds.
+
+The `digits` argument is a number that specifies the number of digits to
+include on the number, defaulting to `3`, which provides microsecond precision.
+
+##### :status
+
+The status code of the response.
+
+If the request/response cycle completes before a response was sent to the
+client (for example, the TCP socket closed prematurely by a client aborting
+the request), then the status will be empty (displayed as `"-"` in the log).
+
+##### :total-time[digits]
+
+The time between the request coming into `morgan` and when the response
+has finished being written out to the connection, in milliseconds.
+
+The `digits` argument is a number that specifies the number of digits to
+include on the number, defaulting to `3`, which provides microsecond precision.
+
+##### :url
+
+The URL of the request. This will use `req.originalUrl` if exists, otherwise `req.url`.
+
+##### :user-agent
+
+The contents of the User-Agent header of the request.
+
+### morgan.compile(format)
+
+Compile a format string into a `format` function for use by `morgan`. A format string
+is a string that represents a single log line and can utilize token syntax.
+Tokens are references by `:token-name`. If tokens accept arguments, they can
+be passed using `[]`, for example: `:token-name[pretty]` would pass the string
+`'pretty'` as an argument to the token `token-name`.
+
+The function returned from `morgan.compile` takes three arguments `tokens`, `req`, and
+`res`, where `tokens` is object with all defined tokens, `req` is the HTTP request and
+`res` is the HTTP response. The function will return a string that will be the log line,
+or `undefined` / `null` to skip logging.
+
+Normally formats are defined using `morgan.format(name, format)`, but for certain
+advanced uses, this compile function is directly available.
+
+## Examples
+
+### express/connect
+
+Sample app that will log all request in the Apache combined format to STDOUT
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+
+var app = express();
+
+app.use(morgan('combined'));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### vanilla http server
+
+Sample app that will log all request in the Apache combined format to STDOUT
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var morgan = require('morgan');
+
+// create "middleware"
+var logger = morgan('combined');
+
+http.createServer(function (req, res) {
+ var done = finalhandler(req, res);
+ logger(req, res, function (err) {
+ if (err) return done(err);
+
+ // respond to request
+ res.setHeader('content-type', 'text/plain');
+ res.end('hello, world!');
+ });
+});
+```
+
+### write logs to a file
+
+#### single file
+
+Sample app that will log all requests in the Apache combined format to the file
+`access.log`.
+
+```js
+var express = require('express');
+var fs = require('fs');
+var morgan = require('morgan');
+var path = require('path');
+
+var app = express();
+
+// create a write stream (in append mode)
+var accessLogStream = fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' });
+
+// setup the logger
+app.use(morgan('combined', { stream: accessLogStream }));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+#### log file rotation
+
+Sample app that will log all requests in the Apache combined format to one log
+file per day in the `log/` directory using the
+[rotating-file-stream module](https://www.npmjs.com/package/rotating-file-stream).
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+var path = require('path');
+var rfs = require('rotating-file-stream'); // version 2.x
+
+var app = express();
+
+// create a rotating write stream
+var accessLogStream = rfs.createStream('access.log', {
+ interval: '1d', // rotate daily
+ path: path.join(__dirname, 'log'),
+});
+
+// setup the logger
+app.use(morgan('combined', { stream: accessLogStream }));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### split / dual logging
+
+The `morgan` middleware can be used as many times as needed, enabling
+combinations like:
+
+- Log entry on request and one on response
+- Log all requests to file, but errors to console
+- ... and more!
+
+Sample app that will log all requests to a file using Apache format, but
+error responses are logged to the console:
+
+```js
+var express = require('express');
+var fs = require('fs');
+var morgan = require('morgan');
+var path = require('path');
+
+var app = express();
+
+// log only 4xx and 5xx responses to console
+app.use(
+ morgan('dev', {
+ skip: function (req, res) {
+ return res.statusCode < 400;
+ },
+ })
+);
+
+// log all requests to access.log
+app.use(
+ morgan('common', {
+ stream: fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' }),
+ })
+);
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### use custom token formats
+
+Sample app that will use custom token formats. This adds an ID to all requests and displays it using the `:id` token.
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+var uuid = require('node-uuid');
+
+morgan.token('id', function getId(req) {
+ return req.id;
+});
+
+var app = express();
+
+app.use(assignId);
+app.use(morgan(':id :method :url :response-time'));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+
+function assignId(req, res, next) {
+ req.id = uuid.v4();
+ next();
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/morgan/master?label=ci
+[ci-url]: https://github.com/expressjs/morgan/actions/workflows/ci.yml
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/morgan/master
+[coveralls-url]: https://coveralls.io/r/expressjs/morgan?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/morgan
+[npm-url]: https://npmjs.org/package/morgan
+[npm-version-image]: https://badgen.net/npm/v/morgan
diff --git a/astro/src/content/resources/pt-br/middleware/multer.md b/astro/src/content/resources/pt-br/middleware/multer.md
new file mode 100644
index 0000000000..326786ab3d
--- /dev/null
+++ b/astro/src/content/resources/pt-br/middleware/multer.md
@@ -0,0 +1,352 @@
+---
+title: Express multer middleware
+module: multer
+---
+
+# Multer [![NPM Version][npm-version-image]][npm-url] [![NPM Downloads][npm-downloads-image]][npm-url] [![Build Status][ci-image]][ci-url] [![Test Coverage][test-image]][test-url] [![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+
+Multer is a node.js middleware for handling `multipart/form-data`, which is primarily used for uploading files. It is written
+on top of [busboy](https://github.com/mscdex/busboy) for maximum efficiency.
+
+**NOTE**: Multer will not process any form which is not multipart (`multipart/form-data`).
+
+## Translations
+
+This README is also available in other languages:
+
+| | |
+| ------------------------------------------------------------------------------ | --------------- |
+| [العربية](https://github.com/expressjs/multer/blob/main/doc/README-ar.md) | Arabic |
+| [简体中文](https://github.com/expressjs/multer/blob/main/doc/README-zh-cn.md) | Chinese |
+| [Français](https://github.com/expressjs/multer/blob/main/doc/README-fr.md) | French |
+| [한국어](https://github.com/expressjs/multer/blob/main/doc/README-ko.md) | Korean |
+| [Português](https://github.com/expressjs/multer/blob/main/doc/README-pt-br.md) | Portuguese (BR) |
+| [Русский язык](https://github.com/expressjs/multer/blob/main/doc/README-ru.md) | Russian |
+| [Español](https://github.com/expressjs/multer/blob/main/doc/README-es.md) | Spanish |
+| [O'zbek tili](https://github.com/expressjs/multer/blob/main/doc/README-uz.md) | Uzbek |
+| [Việt Nam](https://github.com/expressjs/multer/blob/main/doc/README-vi.md) | Vietnamese |
+
+## Installation
+
+```sh
+$ npm install multer
+```
+
+## Usage
+
+Multer adds a `body` object and a `file` or `files` object to the `request` object. The `body` object contains the values of the text fields of the form, the `file` or `files` object contains the files uploaded via the form.
+
+Basic usage example:
+
+Don't forget the `enctype="multipart/form-data"` in your form.
+
+```html
+
+```
+
+```javascript
+const express = require('express');
+const multer = require('multer');
+const upload = multer({ dest: 'uploads/' });
+
+const app = express();
+
+app.post('/profile', upload.single('avatar'), function (req, res, next) {
+ // req.file is the `avatar` file
+ // req.body will hold the text fields, if there were any
+});
+
+app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
+ // req.files is array of `photos` files
+ // req.body will contain the text fields, if there were any
+});
+
+const uploadMiddleware = upload.fields([
+ { name: 'avatar', maxCount: 1 },
+ { name: 'gallery', maxCount: 8 },
+]);
+app.post('/cool-profile', uploadMiddleware, function (req, res, next) {
+ // req.files is an object (String -> Array) where fieldname is the key, and the value is array of files
+ //
+ // e.g.
+ // req.files['avatar'][0] -> File
+ // req.files['gallery'] -> Array
+ //
+ // req.body will contain the text fields, if there were any
+});
+```
+
+In case you need to handle a text-only multipart form, you should use the `.none()` method:
+
+```javascript
+const express = require('express');
+const app = express();
+const multer = require('multer');
+const upload = multer();
+
+app.post('/profile', upload.none(), function (req, res, next) {
+ // req.body contains the text fields
+});
+```
+
+Here's an example on how multer is used in a HTML form. Take special note of the `enctype="multipart/form-data"` and `name="uploaded_file"` fields:
+
+```html
+
+```
+
+Then in your javascript file you would add these lines to access both the file and the body. It is important that you use the `name` field value from the form in your upload function. This tells multer which field on the request it should look for the files in. If these fields aren't the same in the HTML form and on your server, your upload will fail:
+
+```javascript
+const multer = require('multer');
+const upload = multer({ dest: './public/data/uploads/' });
+app.post('/stats', upload.single('uploaded_file'), function (req, res) {
+ // req.file is the name of your file in the form above, here 'uploaded_file'
+ // req.body will hold the text fields, if there were any
+ console.log(req.file, req.body);
+});
+```
+
+## API
+
+### File information
+
+Each file contains the following information:
+
+| Key | Description | Note |
+| -------------- | --------------------------------------------- | --------------- |
+| `fieldname` | Field name specified in the form |
+| `originalname` | Name of the file on the user's computer |
+| `encoding` | Encoding type of the file |
+| `mimetype` | Mime type of the file |
+| `size` | Size of the file in bytes |
+| `destination` | The folder to which the file has been saved | `DiskStorage` |
+| `filename` | The name of the file within the `destination` | `DiskStorage` |
+| `path` | The full path to the uploaded file | `DiskStorage` |
+| `buffer` | A `Buffer` of the entire file | `MemoryStorage` |
+
+### `multer(opts)`
+
+Multer accepts an options object, the most basic of which is the `dest`
+property, which tells Multer where to upload the files. In case you omit the
+options object, the files will be kept in memory and never written to disk.
+
+By default, Multer will rename the files so as to avoid naming conflicts. The
+renaming function can be customized according to your needs.
+
+The following are the options that can be passed to Multer.
+
+| Key | Description |
+| ------------------- | --------------------------------------------------------- |
+| `dest` or `storage` | Where to store the files |
+| `fileFilter` | Function to control which files are accepted |
+| `limits` | Limits of the uploaded data |
+| `preservePath` | Keep the full path of files instead of just the base name |
+
+In an average web app, only `dest` might be required, and configured as shown in
+the following example.
+
+```javascript
+const upload = multer({ dest: 'uploads/' });
+```
+
+If you want more control over your uploads, you'll want to use the `storage`
+option instead of `dest`. Multer ships with storage engines `DiskStorage`
+and `MemoryStorage`; More engines are available from third parties.
+
+#### `.single(fieldname)`
+
+Accept a single file with the name `fieldname`. The single file will be stored
+in `req.file`.
+
+#### `.array(fieldname[, maxCount])`
+
+Accept an array of files, all with the name `fieldname`. Optionally error out if
+more than `maxCount` files are uploaded. The array of files will be stored in
+`req.files`.
+
+#### `.fields(fields)`
+
+Accept a mix of files, specified by `fields`. An object with arrays of files
+will be stored in `req.files`.
+
+`fields` should be an array of objects with `name` and optionally a `maxCount`.
+Example:
+
+```javascript
+[
+ { name: 'avatar', maxCount: 1 },
+ { name: 'gallery', maxCount: 8 },
+];
+```
+
+#### `.none()`
+
+Accept only text fields. If any file upload is made, error with code
+"LIMIT_UNEXPECTED_FILE" will be issued.
+
+#### `.any()`
+
+Accepts all files that comes over the wire. An array of files will be stored in
+`req.files`.
+
+**WARNING:** Make sure that you always handle the files that a user uploads.
+Never add multer as a global middleware since a malicious user could upload
+files to a route that you didn't anticipate. Only use this function on routes
+where you are handling the uploaded files.
+
+### `storage`
+
+#### `DiskStorage`
+
+The disk storage engine gives you full control on storing files to disk.
+
+```javascript
+const storage = multer.diskStorage({
+ destination: function (req, file, cb) {
+ cb(null, '/tmp/my-uploads');
+ },
+ filename: function (req, file, cb) {
+ const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
+ cb(null, file.fieldname + '-' + uniqueSuffix);
+ },
+});
+
+const upload = multer({ storage: storage });
+```
+
+There are two options available, `destination` and `filename`. They are both
+functions that determine where the file should be stored.
+
+`destination` is used to determine within which folder the uploaded files should
+be stored. This can also be given as a `string` (e.g. `'/tmp/uploads'`). If no
+`destination` is given, the operating system's default directory for temporary
+files is used.
+
+**Note:** You are responsible for creating the directory when providing
+`destination` as a function. When passing a string, multer will make sure that
+the directory is created for you.
+
+`filename` is used to determine what the file should be named inside the folder.
+If no `filename` is given, each file will be given a random name that doesn't
+include any file extension.
+
+**Note:** Multer will not append any file extension for you, your function
+should return a filename complete with a file extension.
+
+Each function gets passed both the request (`req`) and some information about
+the file (`file`) to aid with the decision.
+
+Note that `req.body` might not have been fully populated yet. It depends on the
+order that the client transmits fields and files to the server.
+
+For understanding the calling convention used in the callback (needing to pass
+null as the first param), refer to
+[Node.js error handling](https://web.archive.org/web/20220417042018/https://www.joyent.com/node-js/production/design/errors)
+
+#### `MemoryStorage`
+
+The memory storage engine stores the files in memory as `Buffer` objects. It
+doesn't have any options.
+
+```javascript
+const storage = multer.memoryStorage();
+const upload = multer({ storage: storage });
+```
+
+When using memory storage, the file info will contain a field called
+`buffer` that contains the entire file.
+
+**WARNING**: Uploading very large files, or relatively small files in large
+numbers very quickly, can cause your application to run out of memory when
+memory storage is used.
+
+### `limits`
+
+An object specifying the size limits of the following optional properties. Multer passes this object into busboy directly, and the details of the properties can be found on [busboy's page](https://github.com/mscdex/busboy#busboy-methods).
+
+The following integer values are available:
+
+| Key | Description | Default |
+| --------------- | ----------------------------------------------------------------------- | --------- |
+| `fieldNameSize` | Max field name size | 100 bytes |
+| `fieldSize` | Max field value size (in bytes) | 1MB |
+| `fields` | Max number of non-file fields | Infinity |
+| `fileSize` | For multipart forms, the max file size (in bytes) | Infinity |
+| `files` | For multipart forms, the max number of file fields | Infinity |
+| `parts` | For multipart forms, the max number of parts (fields + files) | Infinity |
+| `headerPairs` | For multipart forms, the max number of header key=>value pairs to parse | 2000 |
+
+Specifying the limits can help protect your site against denial of service (DoS) attacks.
+
+### `fileFilter`
+
+Set this to a function to control which files should be uploaded and which
+should be skipped. The function should look like this:
+
+```javascript
+function fileFilter(req, file, cb) {
+ // The function should call `cb` with a boolean
+ // to indicate if the file should be accepted
+
+ // To reject this file pass `false`, like so:
+ cb(null, false);
+
+ // To accept the file pass `true`, like so:
+ cb(null, true);
+
+ // You can always pass an error if something goes wrong:
+ cb(new Error("I don't have a clue!"));
+}
+```
+
+## Error handling
+
+When encountering an error, Multer will delegate the error to Express. You can
+display a nice error page using [the standard express way](http://expressjs.com/guide/error-handling.html).
+
+If you want to catch errors specifically from Multer, you can call the
+middleware function by yourself. Also, if you want to catch only [the Multer errors](https://github.com/expressjs/multer/blob/main/lib/multer-error.js), you can use the `MulterError` class that is attached to the `multer` object itself (e.g. `err instanceof multer.MulterError`).
+
+```javascript
+const multer = require('multer');
+const upload = multer().single('avatar');
+
+app.post('/profile', function (req, res) {
+ upload(req, res, function (err) {
+ if (err instanceof multer.MulterError) {
+ // A Multer error occurred when uploading.
+ } else if (err) {
+ // An unknown error occurred when uploading.
+ }
+
+ // Everything went fine.
+ });
+});
+```
+
+## Custom storage engine
+
+For information on how to build your own storage engine, see [Multer Storage Engine](https://github.com/expressjs/multer/blob/main/StorageEngine.md).
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://github.com/expressjs/multer/actions/workflows/ci.yml/badge.svg
+[ci-url]: https://github.com/expressjs/multer/actions/workflows/ci.yml
+[test-url]: https://coveralls.io/r/expressjs/multer?branch=main
+[test-image]: https://badgen.net/coveralls/c/github/expressjs/multer/main
+[npm-downloads-image]: https://badgen.net/npm/dm/multer
+[npm-url]: https://npmjs.org/package/multer
+[npm-version-image]: https://badgen.net/npm/v/multer
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/multer/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer
diff --git a/astro/src/content/resources/pt-br/middleware/overview.md b/astro/src/content/resources/pt-br/middleware/overview.md
new file mode 100755
index 0000000000..46217759e7
--- /dev/null
+++ b/astro/src/content/resources/pt-br/middleware/overview.md
@@ -0,0 +1,40 @@
+---
+title: Express middleware
+description: Explore a list of Express.js middleware modules maintained by the Express team and the community, including built-in middleware and popular third-party modules.
+module: mw-home
+---
+
+## Express middleware
+
+The Express middleware modules listed here are maintained by the
+[Expressjs team](https://github.com/orgs/expressjs/people).
+
+| Middleware module | Description |
+| ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
+| [body-parser](/en/resources/middleware/body-parser) | Parse HTTP request body. |
+| [compression](/en/resources/middleware/compression) | Compress HTTP responses. |
+| [cookie-parser](/en/resources/middleware/cookie-parser) | Parse cookie header and populate `req.cookies`. See also [cookies](https://github.com/jed/cookies). |
+| [cookie-session](/en/resources/middleware/cookie-session) | Establish cookie-based sessions. |
+| [cors](/en/resources/middleware/cors) | Enable cross-origin resource sharing (CORS) with various options. |
+| [errorhandler](/en/resources/middleware/errorhandler) | Development error-handling/debugging. |
+| [method-override](/en/resources/middleware/method-override) | Override HTTP methods using header. |
+| [morgan](/en/resources/middleware/morgan) | HTTP request logger. |
+| [multer](/en/resources/middleware/multer) | Handle multi-part form data. |
+| [response-time](/en/resources/middleware/response-time) | Record HTTP response time. |
+| [serve-favicon](/en/resources/middleware/serve-favicon) | Serve a favicon. |
+| [serve-index](/en/resources/middleware/serve-index) | Serve directory listing for a given path. |
+| [serve-static](/en/resources/middleware/serve-static) | Serve static files. |
+| [session](/en/resources/middleware/session) | Establish server-based sessions (development only). |
+| [timeout](/en/resources/middleware/timeout) | Set a timeout perioHTTP request processing. |
+| [vhost](/en/resources/middleware/vhost) | Create virtual domains. |
+
+## Additional middleware modules
+
+These are some additional popular middleware modules.
+
+{% include community-caveat.html %}
+
+| Middleware module | Description |
+| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
+| [helmet](https://github.com/helmetjs/helmet) | Helps secure your apps by setting various HTTP headers. |
+| [passport](https://github.com/jaredhanson/passport) | Authentication using "strategies" such as OAuth, OpenID and many others. See [passportjs.org](https://passportjs.org/) for more information. |
diff --git a/astro/src/content/resources/pt-br/middleware/response-time.md b/astro/src/content/resources/pt-br/middleware/response-time.md
new file mode 100644
index 0000000000..f911f480f5
--- /dev/null
+++ b/astro/src/content/resources/pt-br/middleware/response-time.md
@@ -0,0 +1,314 @@
+---
+title: Express response-time middleware
+module: response-time
+---
+
+# compression
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+[![Funding][funding-image]][funding-url]
+
+Node.js compression middleware.
+
+The following compression codings are supported:
+
+- deflate
+- gzip
+- br (brotli)
+
+**Note** Brotli is supported only since Node.js versions v11.7.0 and v10.16.0.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```bash
+$ npm install compression
+```
+
+## API
+
+```js
+var compression = require('compression');
+```
+
+### compression([options])
+
+Returns the compression middleware using the given `options`. The middleware
+will attempt to compress response bodies for all requests that traverse through
+the middleware, based on the given `options`.
+
+This middleware will never compress responses that include a `Cache-Control`
+header with the [`no-transform` directive](https://tools.ietf.org/html/rfc7234#section-5.2.2.4),
+as compressing will transform the body.
+
+#### Options
+
+`compression()` accepts these properties in the options object. In addition to
+those listed below, [zlib](https://nodejs.org/api/zlib.html) options may be
+passed in to the options object or
+[brotli](https://nodejs.org/api/zlib.html#zlib_class_brotlioptions) options.
+
+##### chunkSize
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_CHUNK`, or `16384`.
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### filter
+
+Type: `Function`
+
+A function to decide if the response should be considered for compression.
+This function is called as `filter(req, res)` and is expected to return
+`true` to consider the response for compression, or `false` to not compress
+the response.
+
+The default filter function uses the [compressible](https://www.npmjs.com/package/compressible)
+module to determine if `res.getHeader('Content-Type')` is compressible.
+
+##### level
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_COMPRESSION`, or `-1`
+
+The level of zlib compression to apply to responses. A higher level will result
+in better compression, but will take longer to complete. A lower level will
+result in less compression, but will be much faster.
+
+This is an integer in the range of `0` (no compression) to `9` (maximum
+compression). The special value `-1` can be used to mean the "default
+compression level", which is a default compromise between speed and
+compression (currently equivalent to level 6).
+
+- `-1` Default compression level (also `zlib.constants.Z_DEFAULT_COMPRESSION`).
+- `0` No compression (also `zlib.constants.Z_NO_COMPRESSION`).
+- `1` Fastest compression (also `zlib.constants.Z_BEST_SPEED`).
+- `2`
+- `3`
+- `4`
+- `5`
+- `6` (currently what `zlib.constants.Z_DEFAULT_COMPRESSION` points to).
+- `7`
+- `8`
+- `9` Best compression (also `zlib.constants.Z_BEST_COMPRESSION`).
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### memLevel
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_MEMLEVEL`, or `8`
+
+This specifies how much memory should be allocated for the internal compression
+state and is an integer in the range of `1` (minimum level) and `9` (maximum
+level).
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### brotli
+
+Type: `Object`
+
+This specifies the options for configuring Brotli. See [Node.js documentation](https://nodejs.org/api/zlib.html#class-brotlioptions) for a complete list of available options.
+
+##### strategy
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_STRATEGY`
+
+This is used to tune the compression algorithm. This value only affects the
+compression ratio, not the correctness of the compressed output, even if it
+is not set appropriately.
+
+- `zlib.constants.Z_DEFAULT_STRATEGY` Use for normal data.
+- `zlib.constants.Z_FILTERED` Use for data produced by a filter (or predictor).
+ Filtered data consists mostly of small values with a somewhat random
+ distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect is to force more Huffman coding and less
+ string matching; it is somewhat intermediate between `zlib.constants.Z_DEFAULT_STRATEGY`
+ and `zlib.constants.Z_HUFFMAN_ONLY`.
+- `zlib.constants.Z_FIXED` Use to prevent the use of dynamic Huffman codes, allowing
+ for a simpler decoder for special applications.
+- `zlib.constants.Z_HUFFMAN_ONLY` Use to force Huffman encoding only (no string match).
+- `zlib.constants.Z_RLE` Use to limit match distances to one (run-length encoding).
+ This is designed to be almost as fast as `zlib.constants.Z_HUFFMAN_ONLY`, but give
+ better compression for PNG image data.
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### threshold
+
+Type: `Number` or `String`
+Default: `1kb`
+
+The byte threshold for the response body size before compression is considered
+for the response. This is a number of bytes or any string
+accepted by the [bytes](https://www.npmjs.com/package/bytes) module.
+
+**Note** this is only an advisory setting; if the response size cannot be determined
+at the time the response headers are written, then it is assumed the response is
+_over_ the threshold. To guarantee the response size can be determined, be sure
+set a `Content-Length` response header.
+
+##### windowBits
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_WINDOWBITS`, or `15`
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### enforceEncoding
+
+Type: `String`
+Default: `identity`
+
+This is the default encoding to use when the client does not specify an encoding in the request's [Accept-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) header.
+
+#### .filter
+
+The default `filter` function. This is used to construct a custom filter
+function that is an extension of the default function.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+app.use(compression({ filter: shouldCompress }));
+
+function shouldCompress(req, res) {
+ if (req.headers['x-no-compression']) {
+ // don't compress responses with this request header
+ return false;
+ }
+
+ // fallback to standard filter function
+ return compression.filter(req, res);
+}
+```
+
+### res.flush
+
+This module adds a `res.flush()` method to force the partially-compressed
+response to be flushed to the client.
+
+## Examples
+
+### express
+
+When using this module with express, simply `app.use` the module as
+high as you like. Requests that pass through the middleware will be compressed.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress all responses
+app.use(compression());
+
+// add all routes
+```
+
+### Node.js HTTP server
+
+```js
+var compression = require('compression')({ threshold: 0 });
+var http = require('http');
+
+function createServer(fn) {
+ return http.createServer(function (req, res) {
+ compression(req, res, function (err) {
+ if (err) {
+ res.statusCode = err.status || 500;
+ res.end(err.message);
+ return;
+ }
+
+ fn(req, res);
+ });
+ });
+}
+
+var server = createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello world!');
+});
+
+server.listen(3000, () => {
+ console.log('> Listening at http://localhost:3000');
+});
+```
+
+### Server-Sent Events
+
+Because of the nature of compression this module does not work out of the box
+with server-sent events. To compress content, a window of the output needs to
+be buffered up in order to get good compression. Typically when using server-sent
+events, there are certain block of data that need to reach the client.
+
+You can achieve this by calling `res.flush()` when you need the data written to
+actually make it to the client.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress responses
+app.use(compression());
+
+// server-sent event stream
+app.get('/events', function (req, res) {
+ res.setHeader('Content-Type', 'text/event-stream');
+ res.setHeader('Cache-Control', 'no-cache');
+
+ // send a ping approx every 2 seconds
+ var timer = setInterval(function () {
+ res.write('data: ping\n\n');
+
+ // !!! this is the important part
+ res.flush();
+ }, 2000);
+
+ res.on('close', function () {
+ clearInterval(timer);
+ });
+});
+```
+
+## Contributing
+
+The Express.js project welcomes all constructive contributions. Contributions take many forms,
+from code for bug fixes and enhancements, to additions and fixes to documentation, additional
+tests, triaging incoming pull requests and issues, and more!
+
+See the [Contributing Guide](https://github.com/expressjs/express/blob/master/Contributing.md) for more technical details on contributing.
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://badgen.net/npm/v/compression
+[npm-url]: https://npmjs.org/package/compression
+[downloads-image]: https://badgen.net/npm/dm/compression
+[downloads-url]: https://npmcharts.com/compare/compression?minimal=true
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/compression/master?label=CI
+[github-actions-ci-url]: https://github.com/expressjs/compression/actions?query=workflow%3Aci
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/compression/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/compression
+[funding-url]: https://opencollective.com/express
+[funding-image]: https://badgen.net/badge/icon/sponsor/pink?icon=github&label=Open%20Collective
diff --git a/astro/src/content/resources/pt-br/middleware/serve-favicon.md b/astro/src/content/resources/pt-br/middleware/serve-favicon.md
new file mode 100644
index 0000000000..7a77865c6b
--- /dev/null
+++ b/astro/src/content/resources/pt-br/middleware/serve-favicon.md
@@ -0,0 +1,156 @@
+---
+title: Express serve-favicon middleware
+module: serve-favicon
+---
+
+# serve-index
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Linux Build Status][ci-image]][ci-url]
+[![Windows Build][appveyor-image]][appveyor-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+Serves pages that contain directory listings for a given path.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-index
+```
+
+## API
+
+```js
+var serveIndex = require('serve-index');
+```
+
+### serveIndex(path, options)
+
+Returns middlware that serves an index of the directory in the given `path`.
+
+The `path` is based off the `req.url` value, so a `req.url` of `'/some/dir`
+with a `path` of `'public'` will look at `'public/some/dir'`. If you are using
+something like `express`, you can change the URL "base" with `app.use` (see
+the express example).
+
+#### Options
+
+Serve index accepts these properties in the options object.
+
+##### filter
+
+Apply this filter function to files. Defaults to `false`. The `filter` function
+is called for each file, with the signature `filter(filename, index, files, dir)`
+where `filename` is the name of the file, `index` is the array index, `files` is
+the array of files and `dir` is the absolute path the file is located (and thus,
+the directory the listing is for).
+
+##### hidden
+
+Display hidden (dot) files. Defaults to `false`.
+
+##### icons
+
+Display icons. Defaults to `false`.
+
+##### stylesheet
+
+Optional path to a CSS stylesheet. Defaults to a built-in stylesheet.
+
+##### template
+
+Optional path to an HTML template or a function that will render a HTML
+string. Defaults to a built-in template.
+
+When given a string, the string is used as a file path to load and then the
+following tokens are replaced in templates:
+
+- `{directory}` with the name of the directory.
+- `{files}` with the HTML of an unordered list of file links.
+- `{linked-path}` with the HTML of a link to the directory.
+- `{style}` with the specified stylesheet and embedded images.
+
+When given as a function, the function is called as `template(locals, callback)`
+and it needs to invoke `callback(error, htmlString)`. The following are the
+provided locals:
+
+- `directory` is the directory being displayed (where `/` is the root).
+- `displayIcons` is a Boolean for if icons should be rendered or not.
+- `fileList` is a sorted array of files in the directory. The array contains
+ objects with the following properties:
+ - `name` is the relative name for the file.
+ - `stat` is a `fs.Stats` object for the file.
+- `path` is the full filesystem path to `directory`.
+- `style` is the default stylesheet or the contents of the `stylesheet` option.
+- `viewName` is the view name provided by the `view` option.
+
+##### view
+
+Display mode. `tiles` and `details` are available. Defaults to `tiles`.
+
+## Examples
+
+### Serve directory indexes with vanilla node.js http server
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var serveIndex = require('serve-index');
+var serveStatic = require('serve-static');
+
+// Serve directory indexes for public/ftp folder (with icons)
+var index = serveIndex('public/ftp', { icons: true });
+
+// Serve up public/ftp folder files
+var serve = serveStatic('public/ftp');
+
+// Create server
+var server = http.createServer(function onRequest(req, res) {
+ var done = finalhandler(req, res);
+ serve(req, res, function onNext(err) {
+ if (err) return done(err);
+ index(req, res, done);
+ });
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve directory indexes with express
+
+```js
+var express = require('express');
+var serveIndex = require('serve-index');
+
+var app = express();
+
+// Serve URLs like /ftp/thing as public/ftp/thing
+// The express.static serves the file contents
+// The serveIndex is this module serving the directory
+app.use('/ftp', express.static('public/ftp'), serveIndex('public/ftp', { icons: true }));
+
+// Listen
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE). The [Silk](http://www.famfamfam.com/lab/icons/silk/) icons
+are created by/copyright of [FAMFAMFAM](http://www.famfamfam.com/).
+
+[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/serve-index/master.svg?label=windows
+[appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index
+[ci-image]: https://badgen.net/github/checks/expressjs/serve-index/master?label=ci
+[ci-url]: https://github.com/expressjs/serve-index/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/serve-index/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-index?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/serve-index.svg
+[downloads-url]: https://npmjs.org/package/serve-index
+[npm-image]: https://img.shields.io/npm/v/serve-index.svg
+[npm-url]: https://npmjs.org/package/serve-index
diff --git a/astro/src/content/resources/pt-br/middleware/serve-index.md b/astro/src/content/resources/pt-br/middleware/serve-index.md
new file mode 100644
index 0000000000..da03cf94b2
--- /dev/null
+++ b/astro/src/content/resources/pt-br/middleware/serve-index.md
@@ -0,0 +1,156 @@
+---
+title: Express serve-index middleware
+module: serve-index
+---
+
+# serve-index
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Linux Build Status][ci-image]][ci-url]
+[![Windows Build][appveyor-image]][appveyor-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+Serves pages that contain directory listings for a given path.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-index
+```
+
+## API
+
+```js
+var serveIndex = require('serve-index');
+```
+
+### serveIndex(path, options)
+
+Returns middlware that serves an index of the directory in the given `path`.
+
+The `path` is based off the `req.url` value, so a `req.url` of `'/some/dir`
+with a `path` of `'public'` will look at `'public/some/dir'`. If you are using
+something like `express`, you can change the URL "base" with `app.use` (see
+the express example).
+
+#### Options
+
+Serve index accepts these properties in the options object.
+
+##### filter
+
+Apply this filter function to files. Defaults to `false`. The `filter` function
+is called for each file, with the signature `filter(filename, index, files, dir)`
+where `filename` is the name of the file, `index` is the array index, `files` is
+the array of files and `dir` is the absolute path the file is located (and thus,
+the directory the listing is for).
+
+##### hidden
+
+Display hidden (dot) files. Defaults to `false`.
+
+##### icons
+
+Display icons. Defaults to `false`.
+
+##### stylesheet
+
+Optional path to a CSS stylesheet. Defaults to a built-in stylesheet.
+
+##### template
+
+Optional path to an HTML template or a function that will render a HTML
+string. Defaults to a built-in template.
+
+When given a string, the string is used as a file path to load and then the
+following tokens are replaced in templates:
+
+- `{directory}` with the name of the directory.
+- `{files}` with the HTML of an unordered list of file links.
+- `{linked-path}` with the HTML of a link to the directory.
+- `{style}` with the specified stylesheet and embedded images.
+
+When given as a function, the function is called as `template(locals, callback)`
+and it needs to invoke `callback(error, htmlString)`. The following are the
+provided locals:
+
+- `directory` is the directory being displayed (where `/` is the root).
+- `displayIcons` is a Boolean for if icons should be rendered or not.
+- `fileList` is a sorted array of files in the directory. The array contains
+ objects with the following properties:
+ - `name` is the relative name for the file.
+ - `stat` is a `fs.Stats` object for the file.
+- `path` is the full filesystem path to `directory`.
+- `style` is the default stylesheet or the contents of the `stylesheet` option.
+- `viewName` is the view name provided by the `view` option.
+
+##### view
+
+Display mode. `tiles` and `details` are available. Defaults to `tiles`.
+
+## Examples
+
+### Serve directory indexes with vanilla node.js http server
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var serveIndex = require('serve-index');
+var serveStatic = require('serve-static');
+
+// Serve directory indexes for public/ftp folder (with icons)
+var index = serveIndex('public/ftp', { icons: true });
+
+// Serve up public/ftp folder files
+var serve = serveStatic('public/ftp');
+
+// Create server
+var server = http.createServer(function onRequest(req, res) {
+ var done = finalhandler(req, res);
+ serve(req, res, function onNext(err) {
+ if (err) return done(err);
+ index(req, res, done);
+ });
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve directory indexes with express
+
+```js
+var express = require('express');
+var serveIndex = require('serve-index');
+
+var app = express();
+
+// Serve URLs like /ftp/thing as public/ftp/thing
+// The express.static serves the file contents
+// The serveIndex is this module serving the directory
+app.use('/ftp', express.static('public/ftp'), serveIndex('public/ftp', { icons: true }));
+
+// Listen
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE). The [Silk](http://www.famfamfam.com/lab/icons/silk/) icons
+are created by/copyright of [FAMFAMFAM](http://www.famfamfam.com/).
+
+[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/serve-index/master.svg?label=windows
+[appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index
+[ci-image]: https://badgen.net/github/checks/expressjs/serve-index/master?label=ci
+[ci-url]: https://github.com/expressjs/serve-index/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/serve-index/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-index?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/serve-index.svg
+[downloads-url]: https://npmjs.org/package/serve-index
+[npm-image]: https://img.shields.io/npm/v/serve-index.svg
+[npm-url]: https://npmjs.org/package/serve-index
diff --git a/astro/src/content/resources/pt-br/middleware/serve-static.md b/astro/src/content/resources/pt-br/middleware/serve-static.md
new file mode 100644
index 0000000000..b048165d7b
--- /dev/null
+++ b/astro/src/content/resources/pt-br/middleware/serve-static.md
@@ -0,0 +1,260 @@
+---
+title: Express serve-static middleware
+module: serve-static
+---
+
+# serve-static
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![CI][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-static
+```
+
+## API
+
+```js
+const serveStatic = require('serve-static');
+```
+
+### serveStatic(root, options)
+
+Create a new middleware function to serve files from within a given root
+directory. The file to serve will be determined by combining `req.url`
+with the provided root directory. When a file is not found, instead of
+sending a 404 response, this module will instead call `next()` to move on
+to the next middleware, allowing for stacking and fall-backs.
+
+#### Options
+
+##### acceptRanges
+
+Enable or disable accepting ranged requests, defaults to true.
+Disabling this will not send `Accept-Ranges` and ignore the contents
+of the `Range` request header.
+
+##### cacheControl
+
+Enable or disable setting `Cache-Control` response header, defaults to
+true. Disabling this will ignore the `immutable` and `maxAge` options.
+
+##### dotfiles
+
+Set how "dotfiles" are treated when encountered. A dotfile is a file
+or directory that begins with a dot ("."). Note this check is done on
+the path itself without checking if the path actually exists on the
+disk. If `root` is specified, only the dotfiles above the root are
+checked (i.e. the root itself can be within a dotfile when set
+to "deny").
+
+- `'allow'` No special treatment for dotfiles.
+- `'deny'` Deny a request for a dotfile and 403/`next()`.
+- `'ignore'` Pretend like the dotfile does not exist and 404/`next()`.
+
+The default value is `'ignore'`.
+
+##### etag
+
+Enable or disable etag generation, defaults to true.
+
+##### extensions
+
+Set file extension fallbacks. When set, if a file is not found, the given
+extensions will be added to the file name and search for. The first that
+exists will be served. Example: `['html', 'htm']`.
+
+The default value is `false`.
+
+##### fallthrough
+
+Set the middleware to have client errors fall-through as just unhandled
+requests, otherwise forward a client error. The difference is that client
+errors like a bad request or a request to a non-existent file will cause
+this middleware to simply `next()` to your next middleware when this value
+is `true`. When this value is `false`, these errors (even 404s), will invoke
+`next(err)`.
+
+Typically `true` is desired such that multiple physical directories can be
+mapped to the same web address or for routes to fill in non-existent files.
+
+The value `false` can be used if this middleware is mounted at a path that
+is designed to be strictly a single file system directory, which allows for
+short-circuiting 404s for less overhead. This middleware will also reply to
+all methods.
+
+The default value is `true`.
+
+##### immutable
+
+Enable or disable the `immutable` directive in the `Cache-Control` response
+header, defaults to `false`. If set to `true`, the `maxAge` option should
+also be specified to enable caching. The `immutable` directive will prevent
+supported clients from making conditional requests during the life of the
+`maxAge` option to check if the file has changed.
+
+##### index
+
+By default this module will send "index.html" files in response to a request
+on a directory. To disable this set `false` or to supply a new index pass a
+string or an array in preferred order.
+
+##### lastModified
+
+Enable or disable `Last-Modified` header, defaults to true. Uses the file
+system's last modified value.
+
+##### maxAge
+
+Provide a max-age in milliseconds for http caching, defaults to 0. This
+can also be a string accepted by the [ms](https://www.npmjs.org/package/ms#readme)
+module.
+
+##### redirect
+
+Redirect to trailing "/" when the pathname is a dir. Defaults to `true`.
+
+##### setHeaders
+
+Function to set custom headers on response. Alterations to the headers need to
+occur synchronously. The function is called as `fn(res, path, stat)`, where
+the arguments are:
+
+- `res` the response object
+- `path` the file path that is being sent
+- `stat` the stat object of the file that is being sent
+
+## Examples
+
+### Serve files with vanilla node.js http server
+
+```js
+const finalhandler = require('finalhandler');
+const http = require('http');
+const serveStatic = require('serve-static');
+
+// Serve up public/ftp folder
+const serve = serveStatic('public/ftp', { index: ['index.html', 'index.htm'] });
+
+// Create server
+const server = http.createServer((req, res) => {
+ serve(req, res, finalhandler(req, res));
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve all files as downloads
+
+```js
+const contentDisposition = require('content-disposition');
+const finalhandler = require('finalhandler');
+const http = require('http');
+const serveStatic = require('serve-static');
+
+// Serve up public/ftp folder
+const serve = serveStatic('public/ftp', {
+ index: false,
+ setHeaders: setHeaders,
+});
+
+// Set header to force download
+function setHeaders(res, path) {
+ res.setHeader('Content-Disposition', contentDisposition(path));
+}
+
+// Create server
+const server = http.createServer((req, res) => {
+ serve(req, res, finalhandler(req, res));
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serving using express
+
+#### Simple
+
+This is a simple example of using Express.
+
+```js
+const express = require('express');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(serveStatic('public/ftp', { index: ['default.html', 'default.htm'] }));
+app.listen(3000);
+```
+
+#### Multiple roots
+
+This example shows a simple way to search through multiple directories.
+Files are searched for in `public-optimized/` first, then `public/` second
+as a fallback.
+
+```js
+const express = require('express');
+const path = require('path');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(serveStatic(path.join(__dirname, 'public-optimized')));
+app.use(serveStatic(path.join(__dirname, 'public')));
+app.listen(3000);
+```
+
+#### Different settings for paths
+
+This example shows how to set a different max age depending on the served
+file. In this example, HTML files are not cached, while everything else
+is for 1 day.
+
+```js
+const express = require('express');
+const path = require('path');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(
+ serveStatic(path.join(__dirname, 'public'), {
+ maxAge: '1d',
+ setHeaders: setCustomCacheControl,
+ })
+);
+
+app.listen(3000);
+
+function setCustomCacheControl(res, file) {
+ if (path.extname(file) === '.html') {
+ // Custom Cache-Control for HTML files
+ res.setHeader('Cache-Control', 'public, max-age=0');
+ }
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/serve-static/master
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-static?branch=master
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/serve-static/master?label=linux
+[github-actions-ci-url]: https://github.com/expressjs/serve-static/actions/workflows/ci.yml
+[node-image]: https://badgen.net/npm/node/serve-static
+[node-url]: https://nodejs.org/en/download/
+[npm-downloads-image]: https://badgen.net/npm/dm/serve-static
+[npm-url]: https://npmjs.org/package/serve-static
+[npm-version-image]: https://badgen.net/npm/v/serve-static
diff --git a/astro/src/content/resources/pt-br/middleware/session.md b/astro/src/content/resources/pt-br/middleware/session.md
new file mode 100644
index 0000000000..90f3837a42
--- /dev/null
+++ b/astro/src/content/resources/pt-br/middleware/session.md
@@ -0,0 +1,1046 @@
+---
+title: Express session middleware
+module: session
+---
+
+# express-session
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][node-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install express-session
+```
+
+## API
+
+```js
+var session = require('express-session');
+```
+
+### session(options)
+
+Create a session middleware with the given `options`.
+
+**Note** Session data is _not_ saved in the cookie itself, just the session ID.
+Session data is stored server-side.
+
+**Note** Since version 1.5.0, the [`cookie-parser` middleware](https://www.npmjs.com/package/cookie-parser)
+no longer needs to be used for this module to work. This module now directly reads
+and writes cookies on `req`/`res`. Using `cookie-parser` may result in issues
+if the `secret` is not the same between this module and `cookie-parser`.
+
+**Warning** The default server-side session storage, `MemoryStore`, is _purposely_
+not designed for a production environment. It will leak memory under most
+conditions, does not scale past a single process, and is meant for debugging and
+developing.
+
+For a list of stores, see [compatible session stores](#compatible-session-stores).
+
+#### Options
+
+`express-session` accepts these properties in the options object.
+
+##### cookie
+
+Settings object for the session ID cookie. The default value is
+`{ path: '/', httpOnly: true, secure: false, maxAge: null }`.
+
+The following are options that can be set in this object.
+
+##### cookie.domain
+
+Specifies the value for the `Domain` `Set-Cookie` attribute. By default, no domain
+is set, and most clients will consider the cookie to apply to only the current
+domain.
+
+##### cookie.expires
+
+Specifies the `Date` object to be the value for the `Expires` `Set-Cookie` attribute.
+By default, no expiration is set, and most clients will consider this a
+"non-persistent cookie" and will delete it on a condition like exiting a web browser
+application.
+
+**Note** If both `expires` and `maxAge` are set in the options, then the last one
+defined in the object is what is used.
+
+**Note** The `expires` option should not be set directly; instead only use the `maxAge`
+option.
+
+##### cookie.httpOnly
+
+Specifies the `boolean` value for the `HttpOnly` `Set-Cookie` attribute. When truthy,
+the `HttpOnly` attribute is set, otherwise it is not. By default, the `HttpOnly`
+attribute is set.
+
+**Note** be careful when setting this to `true`, as compliant clients will not allow
+client-side JavaScript to see the cookie in `document.cookie`.
+
+##### cookie.maxAge
+
+Specifies the `number` (in milliseconds) to use when calculating the `Expires`
+`Set-Cookie` attribute. This is done by taking the current server time and adding
+`maxAge` milliseconds to the value to calculate an `Expires` datetime. By default,
+no maximum age is set.
+
+**Note** If both `expires` and `maxAge` are set in the options, then the last one
+defined in the object is what is used.
+
+##### cookie.partitioned
+
+Specifies the `boolean` value for the [`Partitioned` `Set-Cookie`](rfc-cutler-httpbis-partitioned-cookies)
+attribute. When truthy, the `Partitioned` attribute is set, otherwise it is not.
+By default, the `Partitioned` attribute is not set.
+
+**Note** This is an attribute that has not yet been fully standardized, and may
+change in the future. This also means many clients may ignore this attribute until
+they understand it.
+
+More information about can be found in [the proposal](https://github.com/privacycg/CHIPS).
+
+##### cookie.path
+
+Specifies the value for the `Path` `Set-Cookie`. By default, this is set to `'/'`, which
+is the root path of the domain.
+
+##### cookie.priority
+
+Specifies the `string` to be the value for the [`Priority` `Set-Cookie` attribute][rfc-west-cookie-priority-00-4.1].
+
+- `'low'` will set the `Priority` attribute to `Low`.
+- `'medium'` will set the `Priority` attribute to `Medium`, the default priority when not set.
+- `'high'` will set the `Priority` attribute to `High`.
+
+More information about the different priority levels can be found in
+[the specification][rfc-west-cookie-priority-00-4.1].
+
+**Note** This is an attribute that has not yet been fully standardized, and may change in the future.
+This also means many clients may ignore this attribute until they understand it.
+
+##### cookie.sameSite
+
+Specifies the `boolean` or `string` to be the value for the `SameSite` `Set-Cookie` attribute.
+By default, this is `false`.
+
+- `true` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
+- `false` will not set the `SameSite` attribute.
+- `'lax'` will set the `SameSite` attribute to `Lax` for lax same site enforcement.
+- `'none'` will set the `SameSite` attribute to `None` for an explicit cross-site cookie.
+- `'strict'` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
+
+More information about the different enforcement levels can be found in
+[the specification][rfc-6265bis-03-4.1.2.7].
+
+**Note** This is an attribute that has not yet been fully standardized, and may change in
+the future. This also means many clients may ignore this attribute until they understand it.
+
+**Note** There is a [draft spec](https://tools.ietf.org/html/draft-west-cookie-incrementalism-01)
+that requires that the `Secure` attribute be set to `true` when the `SameSite` attribute has been
+set to `'none'`. Some web browsers or other clients may be adopting this specification.
+
+##### cookie.secure
+
+Specifies the `boolean` value for the `Secure` `Set-Cookie` attribute. When truthy,
+the `Secure` attribute is set, otherwise it is not. By default, the `Secure`
+attribute is not set.
+
+**Note** be careful when setting this to `true`, as compliant clients will not send
+the cookie back to the server in the future if the browser does not have an HTTPS
+connection.
+
+Please note that `secure: true` is a **recommended** option. However, it requires
+an https-enabled website, i.e., HTTPS is necessary for secure cookies. If `secure`
+is set, and you access your site over HTTP, the cookie will not be set. If you
+have your node.js behind a proxy and are using `secure: true`, you need to set
+"trust proxy" in express:
+
+```js
+var app = express();
+app.set('trust proxy', 1); // trust first proxy
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ cookie: { secure: true },
+ })
+);
+```
+
+For using secure cookies in production, but allowing for testing in development,
+the following is an example of enabling this setup based on `NODE_ENV` in express:
+
+```js
+var app = express();
+var sess = {
+ secret: 'keyboard cat',
+ cookie: {},
+};
+
+if (app.get('env') === 'production') {
+ app.set('trust proxy', 1); // trust first proxy
+ sess.cookie.secure = true; // serve secure cookies
+}
+
+app.use(session(sess));
+```
+
+The `cookie.secure` option can also be set to the special value `'auto'` to have
+this setting automatically match the determined security of the connection. Be
+careful when using this setting if the site is available both as HTTP and HTTPS,
+as once the cookie is set on HTTPS, it will no longer be visible over HTTP. This
+is useful when the Express `"trust proxy"` setting is properly setup to simplify
+development vs production configuration.
+
+##### genid
+
+Function to call to generate a new session ID. Provide a function that returns
+a string that will be used as a session ID. The function is given `req` as the
+first argument if you want to use some value attached to `req` when generating
+the ID.
+
+The default value is a function which uses the `uid-safe` library to generate IDs.
+
+**NOTE** be careful to generate unique IDs so your sessions do not conflict.
+
+```js
+app.use(
+ session({
+ genid: function (req) {
+ return genuuid(); // use UUIDs for session IDs
+ },
+ secret: 'keyboard cat',
+ })
+);
+```
+
+##### name
+
+The name of the session ID cookie to set in the response (and read from in the
+request).
+
+The default value is `'connect.sid'`.
+
+**Note** if you have multiple apps running on the same hostname (this is just
+the name, i.e. `localhost` or `127.0.0.1`; different schemes and ports do not
+name a different hostname), then you need to separate the session cookies from
+each other. The simplest method is to simply set different `name`s per app.
+
+##### proxy
+
+Trust the reverse proxy when setting secure cookies (via the "X-Forwarded-Proto"
+header).
+
+The default value is `undefined`.
+
+- `true` The "X-Forwarded-Proto" header will be used.
+- `false` All headers are ignored and the connection is considered secure only
+ if there is a direct TLS/SSL connection.
+- `undefined` Uses the "trust proxy" setting from express
+
+##### resave
+
+Forces the session to be saved back to the session store, even if the session
+was never modified during the request. Depending on your store this may be
+necessary, but it can also create race conditions where a client makes two
+parallel requests to your server and changes made to the session in one
+request may get overwritten when the other request ends, even if it made no
+changes (this behavior also depends on what store you're using).
+
+The default value is `true`, but using the default has been deprecated,
+as the default will change in the future. Please research into this setting
+and choose what is appropriate to your use-case. Typically, you'll want
+`false`.
+
+How do I know if this is necessary for my store? The best way to know is to
+check with your store if it implements the `touch` method. If it does, then
+you can safely set `resave: false`. If it does not implement the `touch`
+method and your store sets an expiration date on stored sessions, then you
+likely need `resave: true`.
+
+##### rolling
+
+Force the session identifier cookie to be set on every response. The expiration
+is reset to the original [`maxAge`](#cookiemaxage), resetting the expiration
+countdown.
+
+The default value is `false`.
+
+With this enabled, the session identifier cookie will expire in
+[`maxAge`](#cookiemaxage) since the last response was sent instead of in
+[`maxAge`](#cookiemaxage) since the session was last modified by the server.
+
+This is typically used in conjunction with short, non-session-length
+[`maxAge`](#cookiemaxage) values to provide a quick timeout of the session data
+with reduced potential of it occurring during on going server interactions.
+
+**Note** When this option is set to `true` but the `saveUninitialized` option is
+set to `false`, the cookie will not be set on a response with an uninitialized
+session. This option only modifies the behavior when an existing session was
+loaded for the request.
+
+##### saveUninitialized
+
+Forces a session that is "uninitialized" to be saved to the store. A session is
+uninitialized when it is new but not modified. Choosing `false` is useful for
+implementing login sessions, reducing server storage usage, or complying with
+laws that require permission before setting a cookie. Choosing `false` will also
+help with race conditions where a client makes multiple parallel requests
+without a session.
+
+The default value is `true`, but using the default has been deprecated, as the
+default will change in the future. Please research into this setting and
+choose what is appropriate to your use-case.
+
+**Note** if you are using Session in conjunction with PassportJS, Passport
+will add an empty Passport object to the session for use after a user is
+authenticated, which will be treated as a modification to the session, causing
+it to be saved. _This has been fixed in PassportJS 0.3.0_
+
+##### secret
+
+**Required option**
+
+This is the secret used to sign the session ID cookie. The secret can be any type
+of value that is supported by Node.js `crypto.createHmac` (like a string or a
+`Buffer`). This can be either a single secret, or an array of multiple secrets. If
+an array of secrets is provided, only the first element will be used to sign the
+session ID cookie, while all the elements will be considered when verifying the
+signature in requests. The secret itself should be not easily parsed by a human and
+would best be a random set of characters. A best practice may include:
+
+- The use of environment variables to store the secret, ensuring the secret itself
+ does not exist in your repository.
+- Periodic updates of the secret, while ensuring the previous secret is in the
+ array.
+
+Using a secret that cannot be guessed will reduce the ability to hijack a session to
+only guessing the session ID (as determined by the `genid` option).
+
+Changing the secret value will invalidate all existing sessions. In order to rotate
+the secret without invalidating sessions, provide an array of secrets, with the new
+secret as first element of the array, and including previous secrets as the later
+elements.
+
+**Note** HMAC-256 is used to sign the session ID. For this reason, the secret should
+contain at least 32 bytes of entropy.
+
+##### store
+
+The session store instance, defaults to a new `MemoryStore` instance.
+
+##### unset
+
+Control the result of unsetting `req.session` (through `delete`, setting to `null`,
+etc.).
+
+The default value is `'keep'`.
+
+- `'destroy'` The session will be destroyed (deleted) when the response ends.
+- `'keep'` The session in the store will be kept, but modifications made during
+ the request are ignored and not saved.
+
+### req.session
+
+To store or access session data, simply use the request property `req.session`,
+which is (generally) serialized as JSON by the store, so nested objects
+are typically fine. For example below is a user-specific view counter:
+
+```js
+// Use the session middleware
+app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 } }));
+
+// Access the session as req.session
+app.get('/', function (req, res, next) {
+ if (req.session.views) {
+ req.session.views++;
+ res.setHeader('Content-Type', 'text/html');
+ res.write('views: ' + req.session.views + '
');
+ res.write('expires in: ' + req.session.cookie.maxAge / 1000 + 's
');
+ res.end();
+ } else {
+ req.session.views = 1;
+ res.end('welcome to the session demo. refresh!');
+ }
+});
+```
+
+#### Session.regenerate(callback)
+
+To regenerate the session simply invoke the method. Once complete,
+a new SID and `Session` instance will be initialized at `req.session`
+and the `callback` will be invoked.
+
+```js
+req.session.regenerate(function (err) {
+ // will have a new session here
+});
+```
+
+#### Session.destroy(callback)
+
+Destroys the session and will unset the `req.session` property.
+Once complete, the `callback` will be invoked.
+
+```js
+req.session.destroy(function (err) {
+ // cannot access session here
+});
+```
+
+#### Session.reload(callback)
+
+Reloads the session data from the store and re-populates the
+`req.session` object. Once complete, the `callback` will be invoked.
+
+```js
+req.session.reload(function (err) {
+ // session updated
+});
+```
+
+#### Session.save(callback)
+
+Save the session back to the store, replacing the contents on the store with the
+contents in memory (though a store may do something else--consult the store's
+documentation for exact behavior).
+
+This method is automatically called at the end of the HTTP response if the
+session data has been altered (though this behavior can be altered with various
+options in the middleware constructor). Because of this, typically this method
+does not need to be called.
+
+There are some cases where it is useful to call this method, for example,
+redirects, long-lived requests or in WebSockets.
+
+```js
+req.session.save(function (err) {
+ // session saved
+});
+```
+
+#### Session.touch()
+
+Updates the `.maxAge` property. Typically this is
+not necessary to call, as the session middleware does this for you.
+
+### req.session.id
+
+Each session has a unique ID associated with it. This property is an
+alias of [`req.sessionID`](#reqsessionid-1) and cannot be modified.
+It has been added to make the session ID accessible from the `session`
+object.
+
+### req.session.cookie
+
+Each session has a unique cookie object accompany it. This allows
+you to alter the session cookie per visitor. For example we can
+set `req.session.cookie.expires` to `false` to enable the cookie
+to remain for only the duration of the user-agent.
+
+#### Cookie.maxAge
+
+Alternatively `req.session.cookie.maxAge` will return the time
+remaining in milliseconds, which we may also re-assign a new value
+to adjust the `.expires` property appropriately. The following
+are essentially equivalent
+
+```js
+var hour = 3600000;
+req.session.cookie.expires = new Date(Date.now() + hour);
+req.session.cookie.maxAge = hour;
+```
+
+For example when `maxAge` is set to `60000` (one minute), and 30 seconds
+has elapsed it will return `30000` until the current request has completed,
+at which time `req.session.touch()` is called to reset
+`req.session.cookie.maxAge` to its original value.
+
+```js
+req.session.cookie.maxAge; // => 30000
+```
+
+#### Cookie.originalMaxAge
+
+The `req.session.cookie.originalMaxAge` property returns the original
+`maxAge` (time-to-live), in milliseconds, of the session cookie.
+
+### req.sessionID
+
+To get the ID of the loaded session, access the request property
+`req.sessionID`. This is simply a read-only value set when a session
+is loaded/created.
+
+## Session Store Implementation
+
+Every session store _must_ be an `EventEmitter` and implement specific
+methods. The following methods are the list of **required**, **recommended**,
+and **optional**.
+
+- Required methods are ones that this module will always call on the store.
+- Recommended methods are ones that this module will call on the store if
+ available.
+- Optional methods are ones this module does not call at all, but helps
+ present uniform stores to users.
+
+For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo.
+
+### store.all(callback)
+
+**Optional**
+
+This optional method is used to get all sessions in the store as an array. The
+`callback` should be called as `callback(error, sessions)`.
+
+### store.destroy(sid, callback)
+
+**Required**
+
+This required method is used to destroy/delete a session from the store given
+a session ID (`sid`). The `callback` should be called as `callback(error)` once
+the session is destroyed.
+
+### store.clear(callback)
+
+**Optional**
+
+This optional method is used to delete all sessions from the store. The
+`callback` should be called as `callback(error)` once the store is cleared.
+
+### store.length(callback)
+
+**Optional**
+
+This optional method is used to get the count of all sessions in the store.
+The `callback` should be called as `callback(error, len)`.
+
+### store.get(sid, callback)
+
+**Required**
+
+This required method is used to get a session from the store given a session
+ID (`sid`). The `callback` should be called as `callback(error, session)`.
+
+The `session` argument should be a session if found, otherwise `null` or
+`undefined` if the session was not found (and there was no error). A special
+case is made when `error.code === 'ENOENT'` to act like `callback(null, null)`.
+
+### store.set(sid, session, callback)
+
+**Required**
+
+This required method is used to upsert a session into the store given a
+session ID (`sid`) and session (`session`) object. The callback should be
+called as `callback(error)` once the session has been set in the store.
+
+### store.touch(sid, session, callback)
+
+**Recommended**
+
+This recommended method is used to "touch" a given session given a
+session ID (`sid`) and session (`session`) object. The `callback` should be
+called as `callback(error)` once the session has been touched.
+
+This is primarily used when the store will automatically delete idle sessions
+and this method is used to signal to the store the given session is active,
+potentially resetting the idle timer.
+
+## Compatible Session Stores
+
+The following modules implement a session store that is compatible with this
+module. Please make a PR to add additional modules :)
+
+[![★][aerospike-session-store-image] aerospike-session-store][aerospike-session-store-url] A session store using [Aerospike](http://www.aerospike.com/).
+
+[aerospike-session-store-url]: https://www.npmjs.com/package/aerospike-session-store
+[aerospike-session-store-image]: https://badgen.net/github/stars/aerospike/aerospike-session-store-expressjs?label=%E2%98%85
+
+[![★][better-sqlite3-session-store-image] better-sqlite3-session-store][better-sqlite3-session-store-url] A session store based on [better-sqlite3](https://github.com/JoshuaWise/better-sqlite3).
+
+[better-sqlite3-session-store-url]: https://www.npmjs.com/package/better-sqlite3-session-store
+[better-sqlite3-session-store-image]: https://badgen.net/github/stars/timdaub/better-sqlite3-session-store?label=%E2%98%85
+
+[![★][cassandra-store-image] cassandra-store][cassandra-store-url] An Apache Cassandra-based session store.
+
+[cassandra-store-url]: https://www.npmjs.com/package/cassandra-store
+[cassandra-store-image]: https://badgen.net/github/stars/webcc/cassandra-store?label=%E2%98%85
+
+[![★][cluster-store-image] cluster-store][cluster-store-url] A wrapper for using in-process / embedded
+stores - such as SQLite (via knex), leveldb, files, or memory - with node cluster (desirable for Raspberry Pi 2
+and other multi-core embedded devices).
+
+[cluster-store-url]: https://www.npmjs.com/package/cluster-store
+[cluster-store-image]: https://badgen.net/github/stars/coolaj86/cluster-store?label=%E2%98%85
+
+[![★][connect-arango-image] connect-arango][connect-arango-url] An ArangoDB-based session store.
+
+[connect-arango-url]: https://www.npmjs.com/package/connect-arango
+[connect-arango-image]: https://badgen.net/github/stars/AlexanderArvidsson/connect-arango?label=%E2%98%85
+
+[![★][connect-azuretables-image] connect-azuretables][connect-azuretables-url] An [Azure Table Storage](https://azure.microsoft.com/en-gb/services/storage/tables/)-based session store.
+
+[connect-azuretables-url]: https://www.npmjs.com/package/connect-azuretables
+[connect-azuretables-image]: https://badgen.net/github/stars/mike-goodwin/connect-azuretables?label=%E2%98%85
+
+[![★][connect-cloudant-store-image] connect-cloudant-store][connect-cloudant-store-url] An [IBM Cloudant](https://cloudant.com/)-based session store.
+
+[connect-cloudant-store-url]: https://www.npmjs.com/package/connect-cloudant-store
+[connect-cloudant-store-image]: https://badgen.net/github/stars/adriantanasa/connect-cloudant-store?label=%E2%98%85
+
+[![★][connect-cosmosdb-image] connect-cosmosdb][connect-cosmosdb-url] An Azure [Cosmos DB](https://azure.microsoft.com/en-us/products/cosmos-db/)-based session store.
+
+[connect-cosmosdb-url]: https://www.npmjs.com/package/connect-cosmosdb
+[connect-cosmosdb-image]: https://badgen.net/github/stars/thekillingspree/connect-cosmosdb?label=%E2%98%85
+
+[![★][connect-couchbase-image] connect-couchbase][connect-couchbase-url] A [couchbase](http://www.couchbase.com/)-based session store.
+
+[connect-couchbase-url]: https://www.npmjs.com/package/connect-couchbase
+[connect-couchbase-image]: https://badgen.net/github/stars/christophermina/connect-couchbase?label=%E2%98%85
+
+[![★][connect-datacache-image] connect-datacache][connect-datacache-url] An [IBM Bluemix Data Cache](http://www.ibm.com/cloud-computing/bluemix/)-based session store.
+
+[connect-datacache-url]: https://www.npmjs.com/package/connect-datacache
+[connect-datacache-image]: https://badgen.net/github/stars/adriantanasa/connect-datacache?label=%E2%98%85
+
+[![★][@google-cloud/connect-datastore-image] @google-cloud/connect-datastore][@google-cloud/connect-datastore-url] A [Google Cloud Datastore](https://cloud.google.com/datastore/docs/concepts/overview)-based session store.
+
+[@google-cloud/connect-datastore-url]: https://www.npmjs.com/package/@google-cloud/connect-datastore
+[@google-cloud/connect-datastore-image]: https://badgen.net/github/stars/GoogleCloudPlatform/cloud-datastore-session-node?label=%E2%98%85
+
+[![★][connect-db2-image] connect-db2][connect-db2-url] An IBM DB2-based session store built using [ibm_db](https://www.npmjs.com/package/ibm_db) module.
+
+[connect-db2-url]: https://www.npmjs.com/package/connect-db2
+[connect-db2-image]: https://badgen.net/github/stars/wallali/connect-db2?label=%E2%98%85
+
+[![★][connect-dynamodb-image] connect-dynamodb][connect-dynamodb-url] A DynamoDB-based session store.
+
+[connect-dynamodb-url]: https://www.npmjs.com/package/connect-dynamodb
+[connect-dynamodb-image]: https://badgen.net/github/stars/ca98am79/connect-dynamodb?label=%E2%98%85
+
+[![★][@google-cloud/connect-firestore-image] @google-cloud/connect-firestore][@google-cloud/connect-firestore-url] A [Google Cloud Firestore](https://cloud.google.com/firestore/docs/overview)-based session store.
+
+[@google-cloud/connect-firestore-url]: https://www.npmjs.com/package/@google-cloud/connect-firestore
+[@google-cloud/connect-firestore-image]: https://badgen.net/github/stars/googleapis/nodejs-firestore-session?label=%E2%98%85
+
+[![★][connect-hazelcast-image] connect-hazelcast][connect-hazelcast-url] Hazelcast session store for Connect and Express.
+
+[connect-hazelcast-url]: https://www.npmjs.com/package/connect-hazelcast
+[connect-hazelcast-image]: https://badgen.net/github/stars/huseyinbabal/connect-hazelcast?label=%E2%98%85
+
+[![★][connect-loki-image] connect-loki][connect-loki-url] A Loki.js-based session store.
+
+[connect-loki-url]: https://www.npmjs.com/package/connect-loki
+[connect-loki-image]: https://badgen.net/github/stars/Requarks/connect-loki?label=%E2%98%85
+
+[![★][connect-lowdb-image] connect-lowdb][connect-lowdb-url] A lowdb-based session store.
+
+[connect-lowdb-url]: https://www.npmjs.com/package/connect-lowdb
+[connect-lowdb-image]: https://badgen.net/github/stars/travishorn/connect-lowdb?label=%E2%98%85
+
+[![★][connect-memcached-image] connect-memcached][connect-memcached-url] A memcached-based session store.
+
+[connect-memcached-url]: https://www.npmjs.com/package/connect-memcached
+[connect-memcached-image]: https://badgen.net/github/stars/balor/connect-memcached?label=%E2%98%85
+
+[![★][connect-memjs-image] connect-memjs][connect-memjs-url] A memcached-based session store using
+[memjs](https://www.npmjs.com/package/memjs) as the memcached client.
+
+[connect-memjs-url]: https://www.npmjs.com/package/connect-memjs
+[connect-memjs-image]: https://badgen.net/github/stars/liamdon/connect-memjs?label=%E2%98%85
+
+[![★][connect-ml-image] connect-ml][connect-ml-url] A MarkLogic Server-based session store.
+
+[connect-ml-url]: https://www.npmjs.com/package/connect-ml
+[connect-ml-image]: https://badgen.net/github/stars/bluetorch/connect-ml?label=%E2%98%85
+
+[![★][connect-monetdb-image] connect-monetdb][connect-monetdb-url] A MonetDB-based session store.
+
+[connect-monetdb-url]: https://www.npmjs.com/package/connect-monetdb
+[connect-monetdb-image]: https://badgen.net/github/stars/MonetDB/npm-connect-monetdb?label=%E2%98%85
+
+[![★][connect-mongo-image] connect-mongo][connect-mongo-url] A MongoDB-based session store.
+
+[connect-mongo-url]: https://www.npmjs.com/package/connect-mongo
+[connect-mongo-image]: https://badgen.net/github/stars/kcbanner/connect-mongo?label=%E2%98%85
+
+[![★][connect-mongodb-session-image] connect-mongodb-session][connect-mongodb-session-url] Lightweight MongoDB-based session store built and maintained by MongoDB.
+
+[connect-mongodb-session-url]: https://www.npmjs.com/package/connect-mongodb-session
+[connect-mongodb-session-image]: https://badgen.net/github/stars/mongodb-js/connect-mongodb-session?label=%E2%98%85
+
+[![★][connect-mssql-v2-image] connect-mssql-v2][connect-mssql-v2-url] A Microsoft SQL Server-based session store based on [connect-mssql](https://www.npmjs.com/package/connect-mssql).
+
+[connect-mssql-v2-url]: https://www.npmjs.com/package/connect-mssql-v2
+[connect-mssql-v2-image]: https://badgen.net/github/stars/jluboff/connect-mssql-v2?label=%E2%98%85
+
+[![★][connect-neo4j-image] connect-neo4j][connect-neo4j-url] A [Neo4j](https://neo4j.com)-based session store.
+
+[connect-neo4j-url]: https://www.npmjs.com/package/connect-neo4j
+[connect-neo4j-image]: https://badgen.net/github/stars/MaxAndersson/connect-neo4j?label=%E2%98%85
+
+[![★][connect-ottoman-image] connect-ottoman][connect-ottoman-url] A [couchbase ottoman](http://www.couchbase.com/)-based session store.
+
+[connect-ottoman-url]: https://www.npmjs.com/package/connect-ottoman
+[connect-ottoman-image]: https://badgen.net/github/stars/noiissyboy/connect-ottoman?label=%E2%98%85
+
+[![★][connect-pg-simple-image] connect-pg-simple][connect-pg-simple-url] A PostgreSQL-based session store.
+
+[connect-pg-simple-url]: https://www.npmjs.com/package/connect-pg-simple
+[connect-pg-simple-image]: https://badgen.net/github/stars/voxpelli/node-connect-pg-simple?label=%E2%98%85
+
+[![★][connect-redis-image] connect-redis][connect-redis-url] A Redis-based session store.
+
+[connect-redis-url]: https://www.npmjs.com/package/connect-redis
+[connect-redis-image]: https://badgen.net/github/stars/tj/connect-redis?label=%E2%98%85
+
+[![★][connect-session-firebase-image] connect-session-firebase][connect-session-firebase-url] A session store based on the [Firebase Realtime Database](https://firebase.google.com/docs/database/)
+
+[connect-session-firebase-url]: https://www.npmjs.com/package/connect-session-firebase
+[connect-session-firebase-image]: https://badgen.net/github/stars/benweier/connect-session-firebase?label=%E2%98%85
+
+[![★][connect-session-knex-image] connect-session-knex][connect-session-knex-url] A session store using
+[Knex.js](http://knexjs.org/), which is a SQL query builder for PostgreSQL, MySQL, MariaDB, SQLite3, and Oracle.
+
+[connect-session-knex-url]: https://www.npmjs.com/package/connect-session-knex
+[connect-session-knex-image]: https://badgen.net/github/stars/llambda/connect-session-knex?label=%E2%98%85
+
+[![★][connect-session-sequelize-image] connect-session-sequelize][connect-session-sequelize-url] A session store using
+[Sequelize.js](http://sequelizejs.com/), which is a Node.js / io.js ORM for PostgreSQL, MySQL, SQLite and MSSQL.
+
+[connect-session-sequelize-url]: https://www.npmjs.com/package/connect-session-sequelize
+[connect-session-sequelize-image]: https://badgen.net/github/stars/mweibel/connect-session-sequelize?label=%E2%98%85
+
+[![★][connect-sqlite3-image] connect-sqlite3][connect-sqlite3-url] A [SQLite3](https://github.com/mapbox/node-sqlite3) session store modeled after the TJ's `connect-redis` store.
+
+[connect-sqlite3-url]: https://www.npmjs.com/package/connect-sqlite3
+[connect-sqlite3-image]: https://badgen.net/github/stars/rawberg/connect-sqlite3?label=%E2%98%85
+
+[![★][connect-typeorm-image] connect-typeorm][connect-typeorm-url] A [TypeORM](https://github.com/typeorm/typeorm)-based session store.
+
+[connect-typeorm-url]: https://www.npmjs.com/package/connect-typeorm
+[connect-typeorm-image]: https://badgen.net/github/stars/makepost/connect-typeorm?label=%E2%98%85
+
+[![★][couchdb-expression-image] couchdb-expression][couchdb-expression-url] A [CouchDB](https://couchdb.apache.org/)-based session store.
+
+[couchdb-expression-url]: https://www.npmjs.com/package/couchdb-expression
+[couchdb-expression-image]: https://badgen.net/github/stars/tkshnwesper/couchdb-expression?label=%E2%98%85
+
+[![★][dynamodb-store-image] dynamodb-store][dynamodb-store-url] A DynamoDB-based session store.
+
+[dynamodb-store-url]: https://www.npmjs.com/package/dynamodb-store
+[dynamodb-store-image]: https://badgen.net/github/stars/rafaelrpinto/dynamodb-store?label=%E2%98%85
+
+[![★][dynamodb-store-v3-image] dynamodb-store-v3][dynamodb-store-v3-url] Implementation of a session store using DynamoDB backed by the [AWS SDK for JavaScript v3](https://github.com/aws/aws-sdk-js-v3).
+
+[dynamodb-store-v3-url]: https://www.npmjs.com/package/dynamodb-store-v3
+[dynamodb-store-v3-image]: https://badgen.net/github/stars/FryDay/dynamodb-store-v3?label=%E2%98%85
+
+[![★][express-etcd-image] express-etcd][express-etcd-url] An [etcd](https://github.com/stianeikeland/node-etcd) based session store.
+
+[express-etcd-url]: https://www.npmjs.com/package/express-etcd
+[express-etcd-image]: https://badgen.net/github/stars/gildean/express-etcd?label=%E2%98%85
+
+[![★][express-mysql-session-image] express-mysql-session][express-mysql-session-url] A session store using native
+[MySQL](https://www.mysql.com/) via the [node-mysql](https://github.com/felixge/node-mysql) module.
+
+[express-mysql-session-url]: https://www.npmjs.com/package/express-mysql-session
+[express-mysql-session-image]: https://badgen.net/github/stars/chill117/express-mysql-session?label=%E2%98%85
+
+[![★][express-nedb-session-image] express-nedb-session][express-nedb-session-url] A NeDB-based session store.
+
+[express-nedb-session-url]: https://www.npmjs.com/package/express-nedb-session
+[express-nedb-session-image]: https://badgen.net/github/stars/louischatriot/express-nedb-session?label=%E2%98%85
+
+[![★][express-oracle-session-image] express-oracle-session][express-oracle-session-url] A session store using native
+[oracle](https://www.oracle.com/) via the [node-oracledb](https://www.npmjs.com/package/oracledb) module.
+
+[express-oracle-session-url]: https://www.npmjs.com/package/express-oracle-session
+[express-oracle-session-image]: https://badgen.net/github/stars/slumber86/express-oracle-session?label=%E2%98%85
+
+[![★][express-session-cache-manager-image] express-session-cache-manager][express-session-cache-manager-url]
+A store that implements [cache-manager](https://www.npmjs.com/package/cache-manager), which supports
+a [variety of storage types](https://www.npmjs.com/package/cache-manager#store-engines).
+
+[express-session-cache-manager-url]: https://www.npmjs.com/package/express-session-cache-manager
+[express-session-cache-manager-image]: https://badgen.net/github/stars/theogravity/express-session-cache-manager?label=%E2%98%85
+
+[![★][express-session-etcd3-image] express-session-etcd3][express-session-etcd3-url] An [etcd3](https://github.com/mixer/etcd3) based session store.
+
+[express-session-etcd3-url]: https://www.npmjs.com/package/express-session-etcd3
+[express-session-etcd3-image]: https://badgen.net/github/stars/willgm/express-session-etcd3?label=%E2%98%85
+
+[![★][express-session-level-image] express-session-level][express-session-level-url] A [LevelDB](https://github.com/Level/levelup) based session store.
+
+[express-session-level-url]: https://www.npmjs.com/package/express-session-level
+[express-session-level-image]: https://badgen.net/github/stars/tgohn/express-session-level?label=%E2%98%85
+
+[![★][express-session-rsdb-image] express-session-rsdb][express-session-rsdb-url] Session store based on Rocket-Store: A very simple, super fast and yet powerful, flat file database.
+
+[express-session-rsdb-url]: https://www.npmjs.com/package/express-session-rsdb
+[express-session-rsdb-image]: https://badgen.net/github/stars/paragi/express-session-rsdb?label=%E2%98%85
+
+[![★][express-sessions-image] express-sessions][express-sessions-url] A session store supporting both MongoDB and Redis.
+
+[express-sessions-url]: https://www.npmjs.com/package/express-sessions
+[express-sessions-image]: https://badgen.net/github/stars/konteck/express-sessions?label=%E2%98%85
+
+[![★][firestore-store-image] firestore-store][firestore-store-url] A [Firestore](https://github.com/hendrysadrak/firestore-store)-based session store.
+
+[firestore-store-url]: https://www.npmjs.com/package/firestore-store
+[firestore-store-image]: https://badgen.net/github/stars/hendrysadrak/firestore-store?label=%E2%98%85
+
+[![★][fortune-session-image] fortune-session][fortune-session-url] A [Fortune.js](https://github.com/fortunejs/fortune)
+based session store. Supports all backends supported by Fortune (MongoDB, Redis, Postgres, NeDB).
+
+[fortune-session-url]: https://www.npmjs.com/package/fortune-session
+[fortune-session-image]: https://badgen.net/github/stars/aliceklipper/fortune-session?label=%E2%98%85
+
+[![★][hazelcast-store-image] hazelcast-store][hazelcast-store-url] A Hazelcast-based session store built on the [Hazelcast Node Client](https://www.npmjs.com/package/hazelcast-client).
+
+[hazelcast-store-url]: https://www.npmjs.com/package/hazelcast-store
+[hazelcast-store-image]: https://badgen.net/github/stars/jackspaniel/hazelcast-store?label=%E2%98%85
+
+[![★][level-session-store-image] level-session-store][level-session-store-url] A LevelDB-based session store.
+
+[level-session-store-url]: https://www.npmjs.com/package/level-session-store
+[level-session-store-image]: https://badgen.net/github/stars/toddself/level-session-store?label=%E2%98%85
+
+[![★][lowdb-session-store-image] lowdb-session-store][lowdb-session-store-url] A [lowdb](https://www.npmjs.com/package/lowdb)-based session store.
+
+[lowdb-session-store-url]: https://www.npmjs.com/package/lowdb-session-store
+[lowdb-session-store-image]: https://badgen.net/github/stars/fhellwig/lowdb-session-store?label=%E2%98%85
+
+[![★][medea-session-store-image] medea-session-store][medea-session-store-url] A Medea-based session store.
+
+[medea-session-store-url]: https://www.npmjs.com/package/medea-session-store
+[medea-session-store-image]: https://badgen.net/github/stars/BenjaminVadant/medea-session-store?label=%E2%98%85
+
+[![★][memorystore-image] memorystore][memorystore-url] A memory session store made for production.
+
+[memorystore-url]: https://www.npmjs.com/package/memorystore
+[memorystore-image]: https://badgen.net/github/stars/roccomuso/memorystore?label=%E2%98%85
+
+[![★][mssql-session-store-image] mssql-session-store][mssql-session-store-url] A SQL Server-based session store.
+
+[mssql-session-store-url]: https://www.npmjs.com/package/mssql-session-store
+[mssql-session-store-image]: https://badgen.net/github/stars/jwathen/mssql-session-store?label=%E2%98%85
+
+[![★][nedb-session-store-image] nedb-session-store][nedb-session-store-url] An alternate NeDB-based (either in-memory or file-persisted) session store.
+
+[nedb-session-store-url]: https://www.npmjs.com/package/nedb-session-store
+[nedb-session-store-image]: https://badgen.net/github/stars/JamesMGreene/nedb-session-store?label=%E2%98%85
+
+[![★][@quixo3/prisma-session-store-image] @quixo3/prisma-session-store][@quixo3/prisma-session-store-url] A session store for the [Prisma Framework](https://www.prisma.io).
+
+[@quixo3/prisma-session-store-url]: https://www.npmjs.com/package/@quixo3/prisma-session-store
+[@quixo3/prisma-session-store-image]: https://badgen.net/github/stars/kleydon/prisma-session-store?label=%E2%98%85
+
+[![★][restsession-image] restsession][restsession-url] Store sessions utilizing a RESTful API
+
+[restsession-url]: https://www.npmjs.com/package/restsession
+[restsession-image]: https://badgen.net/github/stars/jankal/restsession?label=%E2%98%85
+
+[![★][sequelstore-connect-image] sequelstore-connect][sequelstore-connect-url] A session store using [Sequelize.js](http://sequelizejs.com/).
+
+[sequelstore-connect-url]: https://www.npmjs.com/package/sequelstore-connect
+[sequelstore-connect-image]: https://badgen.net/github/stars/MattMcFarland/sequelstore-connect?label=%E2%98%85
+
+[![★][session-file-store-image] session-file-store][session-file-store-url] A file system-based session store.
+
+[session-file-store-url]: https://www.npmjs.com/package/session-file-store
+[session-file-store-image]: https://badgen.net/github/stars/valery-barysok/session-file-store?label=%E2%98%85
+
+[![★][session-pouchdb-store-image] session-pouchdb-store][session-pouchdb-store-url] Session store for PouchDB / CouchDB. Accepts embedded, custom, or remote PouchDB instance and realtime synchronization.
+
+[session-pouchdb-store-url]: https://www.npmjs.com/package/session-pouchdb-store
+[session-pouchdb-store-image]: https://badgen.net/github/stars/solzimer/session-pouchdb-store?label=%E2%98%85
+
+[![★][@cyclic.sh/session-store-image] @cyclic.sh/session-store][@cyclic.sh/session-store-url] A DynamoDB-based session store for [Cyclic.sh](https://www.cyclic.sh/) apps.
+
+[@cyclic.sh/session-store-url]: https://www.npmjs.com/package/@cyclic.sh/session-store
+[@cyclic.sh/session-store-image]: https://badgen.net/github/stars/cyclic-software/session-store?label=%E2%98%85
+
+[![★][@databunker/session-store-image] @databunker/session-store][@databunker/session-store-url] A [Databunker](https://databunker.org/)-based encrypted session store.
+
+[@databunker/session-store-url]: https://www.npmjs.com/package/@databunker/session-store
+[@databunker/session-store-image]: https://badgen.net/github/stars/securitybunker/databunker-session-store?label=%E2%98%85
+
+[![★][sessionstore-image] sessionstore][sessionstore-url] A session store that works with various databases.
+
+[sessionstore-url]: https://www.npmjs.com/package/sessionstore
+[sessionstore-image]: https://badgen.net/github/stars/adrai/sessionstore?label=%E2%98%85
+
+[![★][tch-nedb-session-image] tch-nedb-session][tch-nedb-session-url] A file system session store based on NeDB.
+
+[tch-nedb-session-url]: https://www.npmjs.com/package/tch-nedb-session
+[tch-nedb-session-image]: https://badgen.net/github/stars/tomaschyly/NeDBSession?label=%E2%98%85
+
+## Examples
+
+### View counter
+
+A simple example using `express-session` to store page views for a user.
+
+```js
+var express = require('express');
+var parseurl = require('parseurl');
+var session = require('express-session');
+
+var app = express();
+
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ })
+);
+
+app.use(function (req, res, next) {
+ if (!req.session.views) {
+ req.session.views = {};
+ }
+
+ // get the url pathname
+ var pathname = parseurl(req).pathname;
+
+ // count the views
+ req.session.views[pathname] = (req.session.views[pathname] || 0) + 1;
+
+ next();
+});
+
+app.get('/foo', function (req, res, next) {
+ res.send('you viewed this page ' + req.session.views['/foo'] + ' times');
+});
+
+app.get('/bar', function (req, res, next) {
+ res.send('you viewed this page ' + req.session.views['/bar'] + ' times');
+});
+
+app.listen(3000);
+```
+
+### User login
+
+A simple example using `express-session` to keep a user log in session.
+
+```js
+var escapeHtml = require('escape-html');
+var express = require('express');
+var session = require('express-session');
+
+var app = express();
+
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ })
+);
+
+// middleware to test if authenticated
+function isAuthenticated(req, res, next) {
+ if (req.session.user) next();
+ else next('route');
+}
+
+app.get('/', isAuthenticated, function (req, res) {
+ // this is only called when there is an authentication user due to isAuthenticated
+ res.send('hello, ' + escapeHtml(req.session.user) + '!' + ' Logout ');
+});
+
+app.get('/', function (req, res) {
+ res.send(
+ ''
+ );
+});
+
+app.post('/login', express.urlencoded({ extended: false }), function (req, res) {
+ // login logic to validate req.body.user and req.body.pass
+ // would be implemented here. for this example any combo works
+
+ // regenerate the session, which is good practice to help
+ // guard against forms of session fixation
+ req.session.regenerate(function (err) {
+ if (err) next(err);
+
+ // store user information in session, typically a user id
+ req.session.user = req.body.user;
+
+ // save the session before redirection to ensure page
+ // load does not happen before session is saved
+ req.session.save(function (err) {
+ if (err) return next(err);
+ res.redirect('/');
+ });
+ });
+});
+
+app.get('/logout', function (req, res, next) {
+ // logout logic
+
+ // clear the user from the session object and save.
+ // this will ensure that re-using the old session id
+ // does not have a logged in user
+ req.session.user = null;
+ req.session.save(function (err) {
+ if (err) next(err);
+
+ // regenerate the session, which is good practice to help
+ // guard against forms of session fixation
+ req.session.regenerate(function (err) {
+ if (err) next(err);
+ res.redirect('/');
+ });
+ });
+});
+
+app.listen(3000);
+```
+
+## Debugging
+
+This module uses the [debug](https://www.npmjs.com/package/debug) module
+internally to log information about session operations.
+
+To see all the internal logs, set the `DEBUG` environment variable to
+`express-session` when launching your app (`npm start`, in this example):
+
+```sh
+$ DEBUG=express-session npm start
+```
+
+On Windows, use the corresponding command;
+
+```sh
+> set DEBUG=express-session & npm start
+```
+
+## License
+
+[MIT](LICENSE)
+
+[rfc-6265bis-03-4.1.2.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7
+[rfc-cutler-httpbis-partitioned-cookies]: https://tools.ietf.org/html/draft-cutler-httpbis-partitioned-cookies/
+[rfc-west-cookie-priority-00-4.1]: https://tools.ietf.org/html/draft-west-cookie-priority-00#section-4.1
+[ci-image]: https://badgen.net/github/checks/expressjs/session/master?label=ci
+[ci-url]: https://github.com/expressjs/session/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/session/master
+[coveralls-url]: https://coveralls.io/r/expressjs/session?branch=master
+[node-url]: https://nodejs.org/en/download
+[npm-downloads-image]: https://badgen.net/npm/dm/express-session
+[npm-url]: https://npmjs.org/package/express-session
+[npm-version-image]: https://badgen.net/npm/v/express-session
diff --git a/astro/src/content/resources/pt-br/middleware/timeout.md b/astro/src/content/resources/pt-br/middleware/timeout.md
new file mode 100644
index 0000000000..f6057aedfd
--- /dev/null
+++ b/astro/src/content/resources/pt-br/middleware/timeout.md
@@ -0,0 +1,176 @@
+---
+title: Express timeout middleware
+module: timeout
+---
+
+# connect-timeout
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][travis-image]][travis-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Times out a request in the Connect/Express application framework.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install connect-timeout
+```
+
+## API
+
+**NOTE** This module is not recommend as a "top-level" middleware (i.e.
+`app.use(timeout('5s'))`) unless you take precautions to halt your own
+middleware processing. See [as top-level middleware](#as-top-level-middleware)
+for how to use as a top-level middleware.
+
+While the library will emit a 'timeout' event when requests exceed the given
+timeout, node will continue processing the slow request until it terminates.
+Slow requests will continue to use CPU and memory, even if you are returning
+a HTTP response in the timeout callback. For better control over CPU/memory,
+you may need to find the events that are taking a long time (3rd party HTTP
+requests, disk I/O, database calls) and find a way to cancel them, and/or
+close the attached sockets.
+
+### timeout(time, [options])
+
+Returns middleware that times out in `time` milliseconds. `time` can also
+be a string accepted by the [ms](https://www.npmjs.org/package/ms#readme)
+module. On timeout, `req` will emit `"timeout"`.
+
+#### Options
+
+The `timeout` function takes an optional `options` object that may contain
+any of the following keys:
+
+##### respond
+
+Controls if this module will "respond" in the form of forwarding an error.
+If `true`, the timeout error is passed to `next()` so that you may customize
+the response behavior. This error has a `.timeout` property as well as
+`.status == 503`. This defaults to `true`.
+
+### req.clearTimeout()
+
+Clears the timeout on the request. The timeout is completely removed and
+will not fire for this request in the future.
+
+### req.timedout
+
+`true` if timeout fired; `false` otherwise.
+
+## Examples
+
+### as top-level middleware
+
+Because of the way middleware processing works, once this module
+passes the request to the next middleware (which it has to do in order
+for you to do work), it can no longer stop the flow, so you must take
+care to check if the request has timedout before you continue to act
+on the request.
+
+```javascript
+var bodyParser = require('body-parser');
+var cookieParser = require('cookie-parser');
+var express = require('express');
+var timeout = require('connect-timeout');
+
+// example of using this top-level; note the use of haltOnTimedout
+// after every middleware; it will stop the request flow on a timeout
+var app = express();
+app.use(timeout('5s'));
+app.use(bodyParser());
+app.use(haltOnTimedout);
+app.use(cookieParser());
+app.use(haltOnTimedout);
+
+// Add your routes here, etc.
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+app.listen(3000);
+```
+
+### express 3.x
+
+```javascript
+var express = require('express');
+var bodyParser = require('body-parser');
+var timeout = require('connect-timeout');
+
+var app = express();
+app.post('/save', timeout('5s'), bodyParser.json(), haltOnTimedout, function (req, res, next) {
+ savePost(req.body, function (err, id) {
+ if (err) return next(err);
+ if (req.timedout) return;
+ res.send('saved as id ' + id);
+ });
+});
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+function savePost(post, cb) {
+ setTimeout(
+ function () {
+ cb(null, (Math.random() * 40000) >>> 0);
+ },
+ (Math.random() * 7000) >>> 0
+ );
+}
+
+app.listen(3000);
+```
+
+### connect
+
+```javascript
+var bodyParser = require('body-parser');
+var connect = require('connect');
+var timeout = require('connect-timeout');
+
+var app = connect();
+app.use('/save', timeout('5s'), bodyParser.json(), haltOnTimedout, function (req, res, next) {
+ savePost(req.body, function (err, id) {
+ if (err) return next(err);
+ if (req.timedout) return;
+ res.send('saved as id ' + id);
+ });
+});
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+function savePost(post, cb) {
+ setTimeout(
+ function () {
+ cb(null, (Math.random() * 40000) >>> 0);
+ },
+ (Math.random() * 7000) >>> 0
+ );
+}
+
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/connect-timeout.svg
+[npm-url]: https://npmjs.org/package/connect-timeout
+[travis-image]: https://img.shields.io/travis/expressjs/timeout/master.svg
+[travis-url]: https://travis-ci.org/expressjs/timeout
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/timeout/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/timeout?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/connect-timeout.svg
+[downloads-url]: https://npmjs.org/package/connect-timeout
diff --git a/astro/src/content/resources/pt-br/middleware/vhost.md b/astro/src/content/resources/pt-br/middleware/vhost.md
new file mode 100644
index 0000000000..72f49d7f93
--- /dev/null
+++ b/astro/src/content/resources/pt-br/middleware/vhost.md
@@ -0,0 +1,174 @@
+---
+title: Express vhost middleware
+module: vhost
+---
+
+# vhost
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Install
+
+```sh
+$ npm install vhost
+```
+
+## API
+
+```js
+var vhost = require('vhost');
+```
+
+### vhost(hostname, handle)
+
+Create a new middleware function to hand off request to `handle` when the incoming
+host for the request matches `hostname`. The function is called as
+`handle(req, res, next)`, like a standard middleware.
+
+`hostname` can be a string or a RegExp object. When `hostname` is a string it can
+contain `*` to match 1 or more characters in that section of the hostname. When
+`hostname` is a RegExp, it will be forced to case-insensitive (since hostnames are)
+and will be forced to match based on the start and end of the hostname.
+
+When host is matched and the request is sent down to a vhost handler, the `req.vhost`
+property will be populated with an object. This object will have numeric properties
+corresponding to each wildcard (or capture group if RegExp object provided) and the
+`hostname` that was matched.
+
+```js
+var connect = require('connect');
+var vhost = require('vhost');
+var app = connect();
+
+app.use(
+ vhost('*.*.example.com', function handle(req, res, next) {
+ // for match of "foo.bar.example.com:8080" against "*.*.example.com":
+ console.dir(req.vhost.host); // => 'foo.bar.example.com:8080'
+ console.dir(req.vhost.hostname); // => 'foo.bar.example.com'
+ console.dir(req.vhost.length); // => 2
+ console.dir(req.vhost[0]); // => 'foo'
+ console.dir(req.vhost[1]); // => 'bar'
+ })
+);
+```
+
+## Examples
+
+### using with connect for static serving
+
+```js
+var connect = require('connect');
+var serveStatic = require('serve-static');
+var vhost = require('vhost');
+
+var mailapp = connect();
+
+// add middlewares to mailapp for mail.example.com
+
+// create app to serve static files on subdomain
+var staticapp = connect();
+staticapp.use(serveStatic('public'));
+
+// create main app
+var app = connect();
+
+// add vhost routing to main app for mail
+app.use(vhost('mail.example.com', mailapp));
+
+// route static assets for "assets-*" subdomain to get
+// around max host connections limit on browsers
+app.use(vhost('assets-*.example.com', staticapp));
+
+// add middlewares and main usage to app
+
+app.listen(3000);
+```
+
+### using with connect for user subdomains
+
+```js
+var connect = require('connect');
+var serveStatic = require('serve-static');
+var vhost = require('vhost');
+
+var mainapp = connect();
+
+// add middlewares to mainapp for the main web site
+
+// create app that will server user content from public/{username}/
+var userapp = connect();
+
+userapp.use(function (req, res, next) {
+ var username = req.vhost[0]; // username is the "*"
+
+ // pretend request was for /{username}/* for file serving
+ req.originalUrl = req.url;
+ req.url = '/' + username + req.url;
+
+ next();
+});
+userapp.use(serveStatic('public'));
+
+// create main app
+var app = connect();
+
+// add vhost routing for main app
+app.use(vhost('userpages.local', mainapp));
+app.use(vhost('www.userpages.local', mainapp));
+
+// listen on all subdomains for user pages
+app.use(vhost('*.userpages.local', userapp));
+
+app.listen(3000);
+```
+
+### using with any generic request handler
+
+```js
+var connect = require('connect');
+var http = require('http');
+var vhost = require('vhost');
+
+// create main app
+var app = connect();
+
+app.use(
+ vhost('mail.example.com', function (req, res) {
+ // handle req + res belonging to mail.example.com
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello from mail!');
+ })
+);
+
+// an external api server in any framework
+var httpServer = http.createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello from the api!');
+});
+
+app.use(
+ vhost('api.example.com', function (req, res) {
+ // handle req + res belonging to api.example.com
+ // pass the request to a standard Node.js HTTP server
+ httpServer.emit('request', req, res);
+ })
+);
+
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/vhost.svg
+[npm-url]: https://npmjs.org/package/vhost
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/vhost/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/vhost
+[downloads-image]: https://img.shields.io/npm/dm/vhost.svg
+[downloads-url]: https://npmjs.org/package/vhost
+[github-actions-ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/vhost/ci.yml?branch=master&label=ci
+[github-actions-ci-url]: https://github.com/expressjs/vhost/actions/workflows/ci.yml
diff --git a/astro/src/content/resources/pt-br/utils.md b/astro/src/content/resources/pt-br/utils.md
new file mode 100644
index 0000000000..546b2f09b4
--- /dev/null
+++ b/astro/src/content/resources/pt-br/utils.md
@@ -0,0 +1,22 @@
+---
+title: Express utilities
+description: Discover utility modules related to Express.js and Node.js, including tools for cookies, CSRF protection, URL parsing, routing, and more to enhance your applications.
+---
+
+## Express utility functions
+
+The [pillarjs](https://github.com/pillarjs) GitHub organization contains a number of modules
+for utility functions that may be generally useful.
+
+| Utility modules | Description |
+| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| [cookies](https://www.npmjs.com/package/cookies) | Get and set HTTP(S) cookies that can be signed to prevent tampering, using Keygrip. Can be used with the Node.js HTTP library or as Express middleware. |
+| [csrf](https://www.npmjs.com/package/csrf) | Contains the logic behind CSRF token creation and verification. Use this module to create custom CSRF middleware. |
+| [finalhandler](https://www.npmjs.com/package/finalhandler) | Function to invoke as the final step to respond to HTTP request. |
+| [parseurl](https://www.npmjs.com/package/parseurl) | Parse a URL with caching. |
+| [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) | Turn an Express-style path string such as ``/user/:name` into a regular expression. |
+| [resolve-path](https://www.npmjs.com/package/resolve-path) | Resolves a relative path against a root path with validation. |
+| [router](https://www.npmjs.com/package/router) | Simple middleware-style router. |
+| [send](https://www.npmjs.com/package/send) | Library for streaming files as a HTTP response, with support for partial responses (ranges), conditional-GET negotiation, and granular events. |
+
+For additional low-level HTTP-related modules, see [jshttp](https://github.com/jshttp).
diff --git a/astro/src/content/resources/zh-cn/community.md b/astro/src/content/resources/zh-cn/community.md
new file mode 100755
index 0000000000..e40d97e421
--- /dev/null
+++ b/astro/src/content/resources/zh-cn/community.md
@@ -0,0 +1,70 @@
+---
+title: Express community
+description: Connect with the Express.js community, learn about the technical committee, find resources, explore community-contributed modules, and get involved in discussions.
+---
+
+# Community
+
+## Technical committee
+
+The Express technical committee meets online every two weeks (as needed) to discuss development and maintenance of Express,
+and other issues relevant to the Express project. Each meeting is typically announced in an
+[expressjs/discussions issue](https://github.com/expressjs/discussions/issues) with a link to join or view the meeting, which is
+open to all observers.
+
+The meetings are recorded; for a list of the recordings, see the [Express.js YouTube channel](https://www.youtube.com/channel/UCYjxjAeH6TRik9Iwy5nXw7g).
+
+Members of the Express technical committee are:
+
+**Active:**
+
+- [@blakeembrey](https://github.com/blakeembrey) - Blake Embrey
+- [@crandmck](https://github.com/crandmck) - Rand McKinney
+- [@LinusU](https://github.com/LinusU) - Linus Unnebäck
+- [@ulisesgascon](https://github.com/ulisesGascon) - Ulises Gascón
+- [@sheplu](https://github.com/sheplu) - Jean Burellier
+- [@wesleytodd](https://github.com/wesleytodd) - Wes Todd
+- [@jonchurch](https://github.com/jonchurch) - Jon Church
+- [@ctcpip](https://github.com/ctcpip/) - Chris de Almeida
+
+**Inactive:**
+
+- [@dougwilson](https://github.com/dougwilson) - Douglas Wilson
+- [@hacksparrow](https://github.com/hacksparrow) - Hage Yaapa
+- [@jonathanong](https://github.com/jonathanong) - jongleberry
+- [@niftylettuce](https://github.com/niftylettuce) - niftylettuce
+- [@troygoode](https://github.com/troygoode) - Troy Goode
+
+## Express is made of many modules
+
+Our vibrant community has created a large variety of extensions,
+[middleware modules](/en/resources/middleware) and higher-level frameworks.
+
+Additionally, the Express community maintains modules in these two GitHub orgs:
+
+- [jshttp](https://github.com/jshttp) modules providing useful utility functions; see [Utility modules](/en/resources/utils).
+- [pillarjs](https://github.com/pillarjs): low-level modules that Express uses internally.
+
+To keep up with what is going on in the whole community, check out the [ExpressJS StatusBoard](https://expressjs.github.io/statusboard/).
+
+## Issues
+
+If you've come across what you think is a bug, or just want to make
+a feature request open a ticket in the [issue queue](https://github.com/expressjs/express/issues).
+
+## Examples
+
+View dozens of Express application [examples](https://github.com/expressjs/express/tree/master/examples)
+in the repository covering everything from API design and authentication to template engine integration.
+
+## Github Discussions
+
+The [GitHub Discussions](https://github.com/expressjs/discussions) section is an excellent space to engage in conversations about the development and maintenance of Express, as well as to share ideas and discuss topics related to its usage.
+
+# Branding of Express.js
+
+## Express.js Logo
+
+Express is a project of the OpenJS Foundation. Please review the [trademark policy](https://trademark-policy.openjsf.org/) for information about permissible use of Express.js logos and marks.
+
+
diff --git a/astro/src/content/resources/zh-cn/contributing.md b/astro/src/content/resources/zh-cn/contributing.md
new file mode 100644
index 0000000000..96c92467ee
--- /dev/null
+++ b/astro/src/content/resources/zh-cn/contributing.md
@@ -0,0 +1,482 @@
+---
+title: Contributing to Express
+description: Find out how to contribute to Express.js, including guidelines for reporting issues, submitting pull requests, becoming a collaborator, and understanding security policies.
+---
+
+# Contributing to Express
+
+### Looking to contribute to Expressjs.com? Click [here](#expressjs-website-contributing).
+
+Express and the other projects in the [expressjs organization on GitHub](https://github.com/expressjs) are projects of the [OpenJs Foundation](https://openjsf.org/).
+These projects are governed under the general policies and guidelines of the Node.js Foundation along with the additional guidelines below.
+
+- [Technical committee](#technical-committee)
+- [Community contributing guide](#community-contributing-guide)
+- [Collaborator's guide](#collaborators-guide)
+- [Security policies and procedures](#security-policies-and-procedures)
+
+## Technical committee
+
+The Express technical committee consists of active project members, and guides development and maintenance of the Express project. For more information, see [Express Community - Technical committee](/en/resources/community#technical-committee).
+
+## Community contributing guide
+
+
+
+The goal of this document is to create a contribution process that:
+
+- Encourages new contributions.
+- Encourages contributors to remain involved.
+- Avoids unnecessary processes and bureaucracy whenever possible.
+- Creates a transparent decision making process that makes it clear how
+ contributors can be involved in decision making.
+
+### Vocabulary
+
+- A **Contributor** is any individual creating or commenting on an issue or pull request.
+- A **Committer** is a subset of contributors who have been given write access to the repository.
+- A **Project Captain** is the lead maintainer of a repository.
+- A **TC (Technical Committee)** is a group of committers representing the required technical
+ expertise to resolve rare disputes.
+- A **Triager** is a subset of contributors who have been given triage access to the repository.
+
+### Logging Issues
+
+Log an issue for any question or problem you might have. When in doubt, log an issue, and
+any additional policies about what to include will be provided in the responses. The only
+exception is security disclosures which should be sent privately.
+
+Committers may direct you to another repository, ask for additional clarifications, and
+add appropriate metadata before the issue is addressed.
+
+Please be courteous and respectful. Every participant is expected to follow the
+project's Code of Conduct.
+
+### Contributions
+
+Any change to resources in this repository must be through pull requests. This applies to all changes
+to documentation, code, binary files, etc. Even long term committers and TC members must use
+pull requests.
+
+No pull request can be merged without being reviewed.
+
+For non-trivial contributions, pull requests should sit for at least 36 hours to ensure that
+contributors in other timezones have time to review. Consideration should also be given to
+weekends and other holiday periods to ensure active committers all have reasonable time to
+become involved in the discussion and review process if they wish.
+
+The default for each contribution is that it is accepted once no committer has an objection.
+During a review, committers may also request that a specific contributor who is most versed in a
+particular area gives a "LGTM" before the PR can be merged. There is no additional "sign off"
+process for contributions to land. Once all issues brought by committers are addressed it can
+be landed by any committer.
+
+In the case of an objection being raised in a pull request by another committer, all involved
+committers should seek to arrive at a consensus by way of addressing concerns being expressed
+by discussion, compromise on the proposed change, or withdrawal of the proposed change.
+
+If a contribution is controversial and committers cannot agree about how to get it to land
+or if it should land then it should be escalated to the TC. TC members should regularly
+discuss pending contributions in order to find a resolution. It is expected that only a
+small minority of issues be brought to the TC for resolution and that discussion and
+compromise among committers be the default resolution mechanism.
+
+### Becoming a Triager
+
+Anyone can become a triager! Read more about the process of being a triager in
+[the triage process document](https://github.com/expressjs/discussions/blob/master/Triager-Guide.md).
+
+Currently, any existing [organization member](https://github.com/orgs/expressjs/people) can nominate
+a new triager. If you are interested in becoming a triager, our best advice is to actively participate
+in the community by helping triaging issues and pull requests. As well we recommend
+to engage in other community activities like attending the TC meetings, and participating in the Slack
+discussions. If you feel ready and have been helping triage some issues, reach out to an active member of the organization to ask if they'd
+be willing to support you. If they agree, they can create a pull request to formalize your nomination. In the case of an objection to the nomination, the triage team is responsible for working with the individuals involved and finding a resolution.
+
+You can also reach out to any of the [organization members](https://github.com/orgs/expressjs/people)
+if you have questions or need guidance.
+
+### Becoming a Committer
+
+All contributors who have landed significant and valuable contributions should be onboarded in a timely manner,
+and added as a committer, and be given write access to the repository.
+
+Committers are expected to follow this policy and continue to send pull requests, go through
+proper review, and have other committers merge their pull requests.
+
+### TC Process
+
+The TC uses a "consensus seeking" process for issues that are escalated to the TC.
+The group tries to find a resolution that has no open objections among TC members.
+If a consensus cannot be reached that has no objections then a majority wins vote
+is called. It is also expected that the majority of decisions made by the TC are via
+a consensus seeking process and that voting is only used as a last-resort.
+
+Resolution may involve returning the issue to project captains with suggestions on
+how to move forward towards a consensus. It is not expected that a meeting of the TC
+will resolve all issues on its agenda during that meeting and may prefer to continue
+the discussion happening among the project captains.
+
+Members can be added to the TC at any time. Any TC member can nominate another committer
+to the TC and the TC uses its standard consensus seeking process to evaluate whether or
+not to add this new member. The TC will consist of a minimum of 3 active members and a
+maximum of 10. If the TC should drop below 5 members the active TC members should nominate
+someone new. If a TC member is stepping down, they are encouraged (but not required) to
+nominate someone to take their place.
+
+TC members will be added as admin's on the Github orgs, npm orgs, and other resources as
+necessary to be effective in the role.
+
+To remain "active" a TC member should have participation within the last 12 months and miss
+no more than six consecutive TC meetings. Our goal is to increase participation, not punish
+people for any lack of participation, this guideline should be only be used as such
+(replace an inactive member with a new active one, for example). Members who do not meet this
+are expected to step down. If A TC member does not step down, an issue can be opened in the
+discussions repo to move them to inactive status. TC members who step down or are removed due
+to inactivity will be moved into inactive status.
+
+Inactive status members can become active members by self nomination if the TC is not already
+larger than the maximum of 10. They will also be given preference if, while at max size, an
+active member steps down.
+
+### Project Captains
+
+The Express TC can designate captains for individual projects/repos in the
+organizations. These captains are responsible for being the primary
+day-to-day maintainers of the repo on a technical and community front.
+Repo captains are empowered with repo ownership and package publication rights.
+When there are conflicts, especially on topics that effect the Express project
+at large, captains are responsible to raise it up to the TC and drive
+those conflicts to resolution. Captains are also responsible for making sure
+community members follow the community guidelines, maintaining the repo
+and the published package, as well as in providing user support.
+
+Like TC members, Repo captains are a subset of committers.
+
+To become a captain for a project the candidate is expected to participate in that
+project for at least 6 months as a committer prior to the request. They should have
+helped with code contributions as well as triaging issues. They are also required to
+have 2FA enabled on both their GitHub and npm accounts.
+
+Any TC member or an existing captain on the **same** repo can nominate another committer
+to the captain role. To do so, they should submit a PR to this document, updating the
+**Active Project Captains** section (while maintaining the sort order) with the project
+name, the nominee's GitHub handle, and their npm username (if different).
+
+- Repos can have as many captains as make sense for the scope of work.
+- A TC member or an existing repo captain **on the same project** can nominate a new captain.
+ Repo captains from other projects should not nominate captains for a different project.
+
+The PR will require at least 2 approvals from TC members and 2 weeks hold time to allow
+for comment and/or dissent. When the PR is merged, a TC member will add them to the
+proper GitHub/npm groups.
+
+#### Active Projects and Captains
+
+The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members)
+
+#### Current Initiative Captains
+
+The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains)
+
+### Inactivity and Emeritus Policy for Any Role
+
+To support the health and continuity of the project, all individuals holding a role within the community (such as Triager, Committer, WG member, Project Captain, or TC member) are encouraged to maintain active participation.
+
+Inactivity is defined as the absence of meaningful involvement in the project—such as contributions, code reviews, triage, meeting attendance, or discussion participation—for a continuous period of 6 months.
+
+#### Exceptions
+
+Anyone may request a temporary leave from active participation due to personal or professional reasons. In such cases, the individual should inform the relevant team or the Technical Committee (TC). During this time, the inactivity policy is paused, and the individual will not be flagged as inactive.
+
+#### Inactivity Process
+
+- If someone is deemed inactive, the individual may be transitioned to an emeritus role that reflects their past contributions. A best effort will be made to inform them that this has occurred. They may request to be reinstated when they are ready to be active again.
+- The emeritus status helps preserve a clear record of contributors who have meaningfully shaped the project over time.
+
+#### Accountability
+
+- The Technical Committee (TC) and the respective captains of each package/team are responsible for assessing activity levels and enacting this policy fairly and transparently, in coordination with other relevant teams.
+- In case of disagreement, the situation can be discussed and resolved by consensus within the TC or appropriate team.
+
+### Developer's Certificate of Origin 1.1
+
+```text
+By making a contribution to this project, I certify that:
+
+ (a) The contribution was created in whole or in part by me and I
+ have the right to submit it under the open source license
+ indicated in the file; or
+
+ (b) The contribution is based upon previous work that, to the best
+ of my knowledge, is covered under an appropriate open source
+ license and I have the right under that license to submit that
+ work with modifications, whether created in whole or in part
+ by me, under the same open source license (unless I am
+ permitted to submit under a different license), as indicated
+ in the file; or
+
+ (c) The contribution was provided directly to me by some other
+ person who certified (a), (b) or (c) and I have not modified
+ it.
+
+ (d) I understand and agree that this project and the contribution
+ are public and that a record of the contribution (including all
+ personal information I submit with it, including my sign-off) is
+ maintained indefinitely and may be redistributed consistent with
+ this project or the open source license(s) involved.
+```
+
+## Collaborator's guide
+
+
+
+### Website Issues
+
+Open issues for the expressjs.com website in https://github.com/expressjs/expressjs.com.
+
+For issues in other Express managed repos (everything in `expressjs`, `pillarjs` or `jshttp` other than `expressjs/express`), be sure to check their contributing guide and open issues and PRs in the appropriate repository.
+
+### PRs and Code contributions
+
+- Tests must pass.
+- Follow the [JavaScript Standard Style](https://standardjs.com/) and `npm run lint`.
+- If you fix a bug, add a test.
+
+### Branches
+
+Use the `master` branch for bug fixes or minor work that is intended for the
+current release stream.
+
+Use the correspondingly named branch, e.g. `6.x`, for anything intended for
+a future release of Express.
+
+### Steps for contributing
+
+1. Create an issue for the
+ bug you want to fix or the feature that you want to add.
+2. Create your own fork on GitHub, then
+ checkout your fork.
+3. Write your code in your local copy. It's good practice to create a branch for
+ each new issue you work on, although not compulsory.
+4. To run the test suite, first install the dependencies by running `npm install`,
+ then run `npm test`.
+5. Ensure your code is linted by running `npm run lint` -- fix any issue you
+ see listed.
+6. If the tests pass, you can commit your changes to your fork and then create
+ a pull request from there. Make sure to reference your issue from the pull
+ request comments by including the issue number e.g. `#123`.
+
+### Issues which are questions
+
+We will typically close any vague issues or questions that are specific to some
+app you are writing. Please double check the docs and other references before
+being trigger happy with posting a question issue.
+
+Things that will help get your question issue looked at:
+
+- Full and runnable JS code.
+- Clear description of the problem or unexpected behavior.
+- Clear description of the expected result.
+- Steps you have taken to debug it yourself.
+
+If you post a question and do not outline the above items or make it easy for
+us to understand and reproduce your issue, it will be closed.
+
+If your question meets all of the above requirements but you do not believe it needs to be looked at
+by the maintainers
+(for example, if you are just looking for community input) please open it as a discussion topic instead
+of an issue. If you
+are unsure and open an issue, we may move it to discussions if we triage them and decide they do
+not need high
+visibility or maintainer input.
+
+## Security Policies and Procedures
+
+
+
+This document outlines security procedures and general policies for the Express
+project.
+
+- [Reporting a Bug](#reporting-a-bug)
+- [Disclosure Policy](#disclosure-policy)
+- [Comments on this Policy](#comments-on-this-policy)
+
+### Reporting a Bug
+
+The Express team and community take all security bugs in Express seriously.
+Thank you for improving the security of Express. We appreciate your efforts and
+responsible disclosure and will make every effort to acknowledge your
+contributions.
+
+Report security bugs by emailing `express-security@lists.openjsf.org`.
+
+To ensure the timely response to your report, please ensure that the entirety
+of the report is contained within the email body and not solely behind a web
+link or an attachment.
+
+The lead maintainer will acknowledge your email within 48 hours, and will send a
+more detailed response within 48 hours indicating the next steps in handling
+your report. After the initial reply to your report, the security team will
+endeavor to keep you informed of the progress towards a fix and full
+announcement, and may ask for additional information or guidance.
+
+Report security bugs in third-party modules to the person or team maintaining
+the module.
+
+### Pre-release Versions
+
+Alpha and Beta releases are unstable and **not suitable for production use**.
+Vulnerabilities found in pre-releases should be reported according to the [Reporting a Bug](#reporting-a-bug) section.
+Due to the unstable nature of the branch it is not guaranteed that any fixes will be released in the next pre-release.
+
+### Disclosure Policy
+
+When the security team receives a security bug report, they will assign it to a
+primary handler. This person will coordinate the fix and release process,
+involving the following steps:
+
+- Confirm the problem and determine the affected versions.
+- Audit code to find any potential similar problems.
+- Prepare fixes for all releases still under maintenance. These fixes will be
+ released as fast as possible to npm.
+
+### The Express Threat Model
+
+We are currently working on a new version of the security model, the most updated version can be found [here](https://github.com/expressjs/security-wg/blob/main/docs/ThreatModel.md)
+
+### Comments on this Policy
+
+If you have suggestions on how this process could be improved please submit a
+pull request.
+
+---
+
+# Contributing to Expressjs.com {#expressjs-website-contributing}
+
+
+
+### The Official Documentation of the Express.js Framework
+
+This is the contribution documentation for the [expressjs.com](https://github.com/expressjs/expressjs.com) website.
+
+#### Need some ideas? These are some typical issues.
+
+1. **Website issues**: If you see anything on the site that could use a tune-up, think about how to fix it.
+ - Display or screen sizing problems
+ - Mobile responsiveness issues
+ - Missing or broken accessibility features
+ - Website outages
+ - Broken links
+ - Page structure or user interface enhancements
+
+2. **Content Issues**: Fix anything related to site content or typos.
+ - Spelling errors
+ - Incorrect/outdated Express.js documentation
+ - Missing content
+
+3. **Translation Issues**: Fix any translation errors or contribute new content.
+ - Fix spelling errors
+ - Fix incorrect/poorly translated words
+ - Check out the [Contributing translations](#contributing-translations) section below for a contributing guide.
+
+#### Want to work on a backlog issue?
+
+We often have bugs or enhancements that need work. You can find these under our repo's [Issues tab](https://github.com/expressjs/expressjs.com/issues). Check out the tags to find something that's a good match for you.
+
+#### Have an idea? Found a bug?
+
+If you've found a bug or a typo, or if you have an idea for an enhancement, you can:
+
+- Submit a [new issue](https://github.com/expressjs/expressjs.com/issues/new/choose) on our repo. Do this for larger proposals, or if you'd like to discuss or get feedback first.
+
+- Make a [GitHub pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). If you have already done work, and it's ready to go, feel free to send it our way.
+
+## Getting Started
+
+The steps below will guide you through the Expressjs.com contribution process.
+
+#### Step 1: (OPTIONAL) Open a New Issue
+
+So you've found a problem that you want to fix, or have a site enhancement you want to make.
+
+1. If you want to get feedback or discuss, open a discussion [issue](https://github.com/expressjs/expressjs.com/issues/new/choose) prior to starting work. This is not required, but encouraged for larger proposals.
+ - While we highly encourage this step, it is only for submissions proposing significant change. It helps us to clarify and focus the work, and ensure it aligns with overall project priorities.
+ - For submissions proposing minor improvements or corrections, this is not needed. You can skip this step.
+ - When opening an issue please give it a title and fill in the description section. The more details you provide, the more feedback we can give.
+
+2. After receiving your issue the Express.js documentation team will respond with feedback. We read every submission and always try to respond quickly with feedback.
+ - For submissions proposing significant change, we encourage you to follow the review process before starting work.
+
+#### Step 2: Get the Application Code Base
+
+Clone the repo and get the code:
+
+```sh
+git clone https://github.com/expressjs/expressjs.com.git
+```
+
+After you've got the code you're ready to start making your changes!
+
+But just in case you need a little extra explanation, this section below outlines the main sections of the code base, where most changes are likely to be made.
+
+**Markdown Page Files**:
+
+- These files render to html and make up the individual pages of the site. Most of the site's documentation text content is written in `md` files.
+- Change these to make changes to individual pages' content/text or markup.
+- Each language has its own complete set of pages, located under their respective language directories - all the Spanish markdown content is found in the `es` directory, for example.
+
+**Includes Partials and Layout Templates**
+
+- `_includes` are partials that are imported and reused across multiple pages.
+ - These are used to import text content for reuse across pages, such as the API documentation, e.g., `_includes > api > en > 5x`, which is included in every language.
+ - These are used to include the page components that make up site-wide user interface and periphery structure, e.g., Header, Footer, etc.
+- `_layouts` are the templates used to wrap the site's individual pages.
+ - These are used to display the structure of the site's periphery, such as the header and footer, and for injecting and displaying individual markdown pages inside the `content` tag.
+
+**Blog Markdown Files**
+
+- These files make up the individual blog posts. If you want to contribute a blog post please
+ follow the specific instructions for [How to write a blog post.](https://expressjs.com/en/blog/write-post)
+- Located under the `_posts` directory.
+
+**CSS or Javascript**
+
+- All css and js files are kept in `css` and `js` folders on the project root.
+
+The Express.js website is built using [Jekyll](https://jekyllrb.com/) and is hosted on [GitHub Pages](https://pages.github.com/).
+
+#### Step 3: Running the Application
+
+Now you'll need a way to see your changes, which means you'll need a running version of the application. You have two options.
+
+1. **Run Locally**: This gets the local version of the application up and running on your machine. Follow our [Local Setup Guide](https://github.com/expressjs/expressjs.com?tab=readme-ov-file#build-the-website-locally) to use this option.
+ - This is the recommended option for moderate to complex work.
+
+2. **Run using Deploy Preview**: Use this option if you don't want to bother with a local installation. Part of our continuous integration pipeline includes [Netlify Deploy Preview](https://docs.netlify.com/deploy/deploy-types/deploy-previews/).
+ 1. To use this you'll need to get your changes online - after you've made your first commit on your feature branch, make a _draft_ pull request.
+ 2. After the build steps are complete, you'll have access to a **Deploy Preview** tab that will run your changes on the web, rebuilding after each commit is pushed.
+ 3. After you are completely done your work, and it's ready for review, remove the draft status on your pull request and submit your work.
+
+## Contributing translations
+
+We use Crowdin to manage our translations in multiple languages and achieve automatic translation with artificial intelligence. Since these translations can be inefficient in some cases, we need help from the community to provide accurate and helpful translations.
+
+The documentation is translated into these languages:
+
+- Chinese Simplified (`zh-cn`)
+- Chinese Traditional (`zh-tw`)
+- English (`en`)
+- French (`fr`)
+- German (`de`)
+- Italian (`it`)
+- Japanese (`ja`)
+- Korean (`ko`)
+- Brazilian Portuguese (`pt-br`)
+- Spanish (`es`)
+
+### How to translate
+
+1. Request to join the Express.js Website project on [Crowdin](https://express.crowdin.com/website)
+2. [Select the language you want to translate](https://support.crowdin.com/for-translators/#starting-translation)
+3. [Start translating](https://support.crowdin.com/online-editor/)
diff --git a/astro/src/content/resources/zh-cn/glossary.md b/astro/src/content/resources/zh-cn/glossary.md
new file mode 100755
index 0000000000..8b45bf01eb
--- /dev/null
+++ b/astro/src/content/resources/zh-cn/glossary.md
@@ -0,0 +1,62 @@
+---
+title: Express glossary
+description: A comprehensive glossary of terms related to Express.js, Node.js, middleware, routing, and other key concepts to help you understand and use Express effectively.
+---
+
+# Glossary
+
+### application
+
+In general, one or more programs that are designed to carry out operations for a specific purpose. In the context of Express, a program that uses the Express API running on the Node.js platform. Might also refer to an [app object](/en/api#express).
+
+### API
+
+Application programming interface. Spell out the abbreviation when it is first used.
+
+### Express
+
+A fast, un-opinionated, minimalist web framework for Node.js applications. In general, "Express" is preferred to "Express.js," though the latter is acceptable.
+
+### libuv
+
+A multi-platform support library which focuses on asynchronous I/O, primarily developed for use by Node.js.
+
+### middleware
+
+A function that is invoked by the Express routing layer before the final request handler, and thus sits in the middle between a raw request and the final intended route. A few fine points of terminology around middleware:
+
+- `var foo = require('middleware')` is called _requiring_ or _using_ a Node.js module. Then the statement `var mw = foo()` typically returns the middleware.
+- `app.use(mw)` is called _adding the middleware to the global processing stack_.
+- `app.get('/foo', mw, function (req, res) { ... })` is called _adding the middleware to the "GET /foo" processing stack_.
+
+### Node.js
+
+A software platform that is used to build scalable network applications. Node.js uses JavaScript as its scripting language, and achieves high throughput via non-blocking I/O and a single-threaded event loop. See [nodejs.org](https://nodejs.org/en/). **Usage note**: Initially, "Node.js," thereafter "Node".
+
+### open-source, open source
+
+When used as an adjective, hyphenate; for example: "This is open-source software." See [Open-source software on Wikipedia](http://en.wikipedia.org/wiki/Open-source_software).
+
+{% capture english-rules %}
+
+Although it is common not to hyphenate this term, we are using the standard English rules for hyphenating a compound adjective.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=english-rules %}
+
+### request
+
+An HTTP request. A client submits an HTTP request message to a server, which returns a response. The request must use one of several [request methods](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods) such as GET, POST, and so on.
+
+### response
+
+An HTTP response. A server returns an HTTP response message to the client. The response contains completion status information about the request and might also contain requested content in its message body.
+
+### route
+
+Part of a URL that identifies a resource. For example, in `http://foo.com/products/id`, "/products/id" is the route.
+
+### router
+
+See [router](/en/api#router) in the API reference.
diff --git a/astro/src/content/resources/zh-cn/middleware/body-parser.md b/astro/src/content/resources/zh-cn/middleware/body-parser.md
new file mode 100644
index 0000000000..e82649a95c
--- /dev/null
+++ b/astro/src/content/resources/zh-cn/middleware/body-parser.md
@@ -0,0 +1,498 @@
+---
+title: Express body-parser middleware
+module: body-parser
+---
+
+# body-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+
+Node.js body parsing middleware.
+
+Parse incoming request bodies in a middleware before your handlers, available
+under the `req.body` property.
+
+**Note** As `req.body`'s shape is based on user-controlled input, all
+properties and values in this object are untrusted and should be validated
+before trusting. For example, `req.body.foo.toString()` may fail in multiple
+ways, for example the `foo` property may not be there or may not be a string,
+and `toString` may not be a function and instead a string or other user input.
+
+[Learn about the anatomy of an HTTP transaction in Node.js](https://nodejs.org/en/learn/http/anatomy-of-an-http-transaction).
+
+_This does not handle multipart bodies_, due to their complex and typically
+large nature. For multipart bodies, you may be interested in the following
+modules:
+
+- [busboy](https://www.npmjs.com/package/busboy#readme) and
+ [connect-busboy](https://www.npmjs.com/package/connect-busboy#readme)
+- [multiparty](https://www.npmjs.com/package/multiparty#readme) and
+ [connect-multiparty](https://www.npmjs.com/package/connect-multiparty#readme)
+- [formidable](https://www.npmjs.com/package/formidable#readme)
+- [multer](https://www.npmjs.com/package/multer#readme)
+
+This module provides the following parsers:
+
+- [JSON body parser](#bodyparserjsonoptions)
+- [Raw body parser](#bodyparserrawoptions)
+- [Text body parser](#bodyparsertextoptions)
+- [URL-encoded form body parser](#bodyparserurlencodedoptions)
+
+Other body parsers you might be interested in:
+
+- [body](https://www.npmjs.com/package/body#readme)
+- [co-body](https://www.npmjs.com/package/co-body#readme)
+
+## Installation
+
+```sh
+$ npm install body-parser
+```
+
+## API
+
+```js
+const bodyParser = require('body-parser');
+```
+
+The `bodyParser` object exposes various factories to create middlewares. All
+middlewares will populate the `req.body` property with the parsed body when
+the `Content-Type` request header matches the `type` option.
+
+The various errors returned by this module are described in the
+[errors section](#errors).
+
+### bodyParser.json([options])
+
+Returns middleware that only parses `json` and only looks at requests where
+the `Content-Type` header matches the `type` option. This parser accepts any
+Unicode encoding of the body and supports automatic inflation of `gzip`,
+`br` (brotli) and `deflate` encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`).
+
+#### Options
+
+The `json` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### defaultCharset
+
+Specify the default character set for the json content if the charset is not
+specified in the `Content-Type` header of the request. Defaults to `utf-8`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### reviver
+
+The `reviver` option is passed directly to `JSON.parse` as the second
+argument. You can find more information on this argument
+[in the MDN documentation about JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Example.3A_Using_the_reviver_parameter).
+
+##### strict
+
+When set to `true`, will only accept arrays and objects; when `false` will
+accept anything `JSON.parse` accepts. Defaults to `true`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not a
+function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `json`), a mime type (like `application/json`), or
+a mime type with a wildcard (like `*/*` or `*/json`). If a function, the `type`
+option is called as `fn(req)` and the request is parsed if it returns a truthy
+value. Defaults to `application/json`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.raw([options])
+
+Returns middleware that parses all bodies as a `Buffer` and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser supports automatic inflation of `gzip`, `br` (brotli) and `deflate`
+encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This will be a `Buffer` object
+of the body.
+
+#### Options
+
+The `raw` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function.
+If not a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this
+can be an extension name (like `bin`), a mime type (like
+`application/octet-stream`), or a mime type with a wildcard (like `*/*` or
+`application/*`). If a function, the `type` option is called as `fn(req)`
+and the request is parsed if it returns a truthy value. Defaults to
+`application/octet-stream`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.text([options])
+
+Returns middleware that parses all bodies as a string and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser supports automatic inflation of `gzip`, `br` (brotli) and `deflate`
+encodings.
+
+A new `body` string containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This will be a string of the
+body.
+
+#### Options
+
+The `text` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### defaultCharset
+
+Specify the default character set for the text content if the charset is not
+specified in the `Content-Type` header of the request. Defaults to `utf-8`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not
+a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `txt`), a mime type (like `text/plain`), or a mime
+type with a wildcard (like `*/*` or `text/*`). If a function, the `type`
+option is called as `fn(req)` and the request is parsed if it returns a
+truthy value. Defaults to `text/plain`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.urlencoded([options])
+
+Returns middleware that only parses `urlencoded` bodies and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser accepts only UTF-8 encoding of the body and supports automatic
+inflation of `gzip`, `br` (brotli) and `deflate` encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This object will contain
+key-value pairs, where the value can be a string or array (when `extended` is
+`false`), or any type (when `extended` is `true`).
+
+#### Options
+
+The `urlencoded` function takes an optional `options` object that may contain
+any of the following keys:
+
+##### extended
+
+The "extended" syntax allows for rich objects and arrays to be encoded into the
+URL-encoded format, allowing for a JSON-like experience with URL-encoded. For
+more information, please [see the qs
+library](https://www.npmjs.com/package/qs#readme).
+
+Defaults to `false`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### parameterLimit
+
+The `parameterLimit` option controls the maximum number of parameters that
+are allowed in the URL-encoded data. If a request contains more parameters
+than this value, a 413 will be returned to the client. Defaults to `1000`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not
+a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `urlencoded`), a mime type (like
+`application/x-www-form-urlencoded`), or a mime type with a wildcard (like
+`*/x-www-form-urlencoded`). If a function, the `type` option is called as
+`fn(req)` and the request is parsed if it returns a truthy value. Defaults
+to `application/x-www-form-urlencoded`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+##### defaultCharset
+
+The default charset to parse as, if not specified in content-type. Must be
+either `utf-8` or `iso-8859-1`. Defaults to `utf-8`.
+
+##### charsetSentinel
+
+Whether to let the value of the `utf8` parameter take precedence as the charset
+selector. It requires the form to contain a parameter named `utf8` with a value
+of `✓`. Defaults to `false`.
+
+##### interpretNumericEntities
+
+Whether to decode numeric entities such as `☺` when parsing an iso-8859-1
+form. Defaults to `false`.
+
+##### depth
+
+The `depth` option is used to configure the maximum depth of the `qs` library when `extended` is `true`. This allows you to limit the amount of keys that are parsed and can be useful to prevent certain types of abuse. Defaults to `32`. It is recommended to keep this value as low as possible.
+
+## Errors
+
+The middlewares provided by this module create errors using the
+[`http-errors` module](https://www.npmjs.com/package/http-errors). The errors
+will typically have a `status`/`statusCode` property that contains the suggested
+HTTP response code, an `expose` property to determine if the `message` property
+should be displayed to the client, a `type` property to determine the type of
+error without matching against the `message`, and a `body` property containing
+the read body, if available.
+
+The following are the common errors created, though any error can come through
+for various reasons.
+
+### content encoding unsupported
+
+This error will occur when the request had a `Content-Encoding` header that
+contained an encoding but the "inflation" option was set to `false`. The
+`status` property is set to `415`, the `type` property is set to
+`'encoding.unsupported'`, and the `charset` property will be set to the
+encoding that is unsupported.
+
+### entity parse failed
+
+This error will occur when the request contained an entity that could not be
+parsed by the middleware. The `status` property is set to `400`, the `type`
+property is set to `'entity.parse.failed'`, and the `body` property is set to
+the entity value that failed parsing.
+
+### entity verify failed
+
+This error will occur when the request contained an entity that could not be
+failed verification by the defined `verify` option. The `status` property is
+set to `403`, the `type` property is set to `'entity.verify.failed'`, and the
+`body` property is set to the entity value that failed verification.
+
+### request aborted
+
+This error will occur when the request is aborted by the client before reading
+the body has finished. The `received` property will be set to the number of
+bytes received before the request was aborted and the `expected` property is
+set to the number of expected bytes. The `status` property is set to `400`
+and `type` property is set to `'request.aborted'`.
+
+### request entity too large
+
+This error will occur when the request body's size is larger than the "limit"
+option. The `limit` property will be set to the byte limit and the `length`
+property will be set to the request body's length. The `status` property is
+set to `413` and the `type` property is set to `'entity.too.large'`.
+
+### request size did not match content length
+
+This error will occur when the request's length did not match the length from
+the `Content-Length` header. This typically occurs when the request is malformed,
+typically when the `Content-Length` header was calculated based on characters
+instead of bytes. The `status` property is set to `400` and the `type` property
+is set to `'request.size.invalid'`.
+
+### stream encoding should not be set
+
+This error will occur when something called the `req.setEncoding` method prior
+to this middleware. This module operates directly on bytes only and you cannot
+call `req.setEncoding` when using this module. The `status` property is set to
+`500` and the `type` property is set to `'stream.encoding.set'`.
+
+### stream is not readable
+
+This error will occur when the request is no longer readable when this middleware
+attempts to read it. This typically means something other than a middleware from
+this module read the request body already and the middleware was also configured to
+read the same request. The `status` property is set to `500` and the `type`
+property is set to `'stream.not.readable'`.
+
+### too many parameters
+
+This error will occur when the content of the request exceeds the configured
+`parameterLimit` for the `urlencoded` parser. The `status` property is set to
+`413` and the `type` property is set to `'parameters.too.many'`.
+
+### unsupported charset "BOGUS"
+
+This error will occur when the request had a charset parameter in the
+`Content-Type` header, but the `iconv-lite` module does not support it OR the
+parser does not support it. The charset is contained in the message as well
+as in the `charset` property. The `status` property is set to `415`, the
+`type` property is set to `'charset.unsupported'`, and the `charset` property
+is set to the charset that is unsupported.
+
+### unsupported content encoding "bogus"
+
+This error will occur when the request had a `Content-Encoding` header that
+contained an unsupported encoding. The encoding is contained in the message
+as well as in the `encoding` property. The `status` property is set to `415`,
+the `type` property is set to `'encoding.unsupported'`, and the `encoding`
+property is set to the encoding that is unsupported.
+
+### The input exceeded the depth
+
+This error occurs when using `bodyParser.urlencoded` with the `extended` property set to `true` and the input exceeds the configured `depth` option. The `status` property is set to `400`. It is recommended to review the `depth` option and evaluate if it requires a higher value. When the `depth` option is set to `32` (default value), the error will not be thrown.
+
+## Examples
+
+### Express/Connect top-level generic
+
+This example demonstrates adding a generic JSON and URL-encoded parser as a
+top-level middleware, which will parse the bodies of all incoming requests.
+This is the simplest setup.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// parse application/x-www-form-urlencoded
+app.use(bodyParser.urlencoded());
+
+// parse application/json
+app.use(bodyParser.json());
+
+app.use(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.write('you posted:\n');
+ res.end(String(JSON.stringify(req.body, null, 2)));
+});
+```
+
+### Express route-specific
+
+This example demonstrates adding body parsers specifically to the routes that
+need them. In general, this is the most recommended way to use body-parser with
+Express.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// create application/json parser
+const jsonParser = bodyParser.json();
+
+// create application/x-www-form-urlencoded parser
+const urlencodedParser = bodyParser.urlencoded();
+
+// POST /login gets urlencoded bodies
+app.post('/login', urlencodedParser, function (req, res) {
+ if (!req.body || !req.body.username) res.sendStatus(400);
+ res.send('welcome, ' + req.body.username);
+});
+
+// POST /api/users gets JSON bodies
+app.post('/api/users', jsonParser, function (req, res) {
+ if (!req.body) res.sendStatus(400);
+ // create user in req.body
+});
+```
+
+### Change accepted type for parsers
+
+All the parsers accept a `type` option which allows you to change the
+`Content-Type` that the middleware will parse.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// parse various different custom JSON types as JSON
+app.use(bodyParser.json({ type: 'application/*+json' }));
+
+// parse some custom thing into a Buffer
+app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }));
+
+// parse an HTML body into a string
+app.use(bodyParser.text({ type: 'text/html' }));
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/body-parser/ci.yml?branch=master&label=ci
+[ci-url]: https://github.com/expressjs/body-parser/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coverallsCoverage/github/expressjs/body-parser?branch=master
+[coveralls-url]: https://coveralls.io/r/expressjs/body-parser?branch=master
+[npm-downloads-image]: https://img.shields.io/npm/dm/body-parser
+[npm-url]: https://npmjs.com/package/body-parser
+[npm-version-image]: https://img.shields.io/npm/v/body-parser
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/body-parser/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/body-parser
diff --git a/astro/src/content/resources/zh-cn/middleware/compression.md b/astro/src/content/resources/zh-cn/middleware/compression.md
new file mode 100644
index 0000000000..6ac63fcb7a
--- /dev/null
+++ b/astro/src/content/resources/zh-cn/middleware/compression.md
@@ -0,0 +1,314 @@
+---
+title: Express compression middleware
+module: compression
+---
+
+# compression
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+[![Funding][funding-image]][funding-url]
+
+Node.js compression middleware.
+
+The following compression codings are supported:
+
+- deflate
+- gzip
+- br (brotli)
+
+**Note** Brotli is supported only since Node.js versions v11.7.0 and v10.16.0.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```bash
+$ npm install compression
+```
+
+## API
+
+```js
+var compression = require('compression');
+```
+
+### compression([options])
+
+Returns the compression middleware using the given `options`. The middleware
+will attempt to compress response bodies for all requests that traverse through
+the middleware, based on the given `options`.
+
+This middleware will never compress responses that include a `Cache-Control`
+header with the [`no-transform` directive](https://tools.ietf.org/html/rfc7234#section-5.2.2.4),
+as compressing will transform the body.
+
+#### Options
+
+`compression()` accepts these properties in the options object. In addition to
+those listed below, [zlib](https://nodejs.org/api/zlib.html) options may be
+passed in to the options object or
+[brotli](https://nodejs.org/api/zlib.html#zlib_class_brotlioptions) options.
+
+##### chunkSize
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_CHUNK`, or `16384`.
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### filter
+
+Type: `Function`
+
+A function to decide if the response should be considered for compression.
+This function is called as `filter(req, res)` and is expected to return
+`true` to consider the response for compression, or `false` to not compress
+the response.
+
+The default filter function uses the [compressible](https://www.npmjs.com/package/compressible)
+module to determine if `res.getHeader('Content-Type')` is compressible.
+
+##### level
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_COMPRESSION`, or `-1`
+
+The level of zlib compression to apply to responses. A higher level will result
+in better compression, but will take longer to complete. A lower level will
+result in less compression, but will be much faster.
+
+This is an integer in the range of `0` (no compression) to `9` (maximum
+compression). The special value `-1` can be used to mean the "default
+compression level", which is a default compromise between speed and
+compression (currently equivalent to level 6).
+
+- `-1` Default compression level (also `zlib.constants.Z_DEFAULT_COMPRESSION`).
+- `0` No compression (also `zlib.constants.Z_NO_COMPRESSION`).
+- `1` Fastest compression (also `zlib.constants.Z_BEST_SPEED`).
+- `2`
+- `3`
+- `4`
+- `5`
+- `6` (currently what `zlib.constants.Z_DEFAULT_COMPRESSION` points to).
+- `7`
+- `8`
+- `9` Best compression (also `zlib.constants.Z_BEST_COMPRESSION`).
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### memLevel
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_MEMLEVEL`, or `8`
+
+This specifies how much memory should be allocated for the internal compression
+state and is an integer in the range of `1` (minimum level) and `9` (maximum
+level).
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### brotli
+
+Type: `Object`
+
+This specifies the options for configuring Brotli. See [Node.js documentation](https://nodejs.org/api/zlib.html#class-brotlioptions) for a complete list of available options.
+
+##### strategy
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_STRATEGY`
+
+This is used to tune the compression algorithm. This value only affects the
+compression ratio, not the correctness of the compressed output, even if it
+is not set appropriately.
+
+- `zlib.constants.Z_DEFAULT_STRATEGY` Use for normal data.
+- `zlib.constants.Z_FILTERED` Use for data produced by a filter (or predictor).
+ Filtered data consists mostly of small values with a somewhat random
+ distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect is to force more Huffman coding and less
+ string matching; it is somewhat intermediate between `zlib.constants.Z_DEFAULT_STRATEGY`
+ and `zlib.constants.Z_HUFFMAN_ONLY`.
+- `zlib.constants.Z_FIXED` Use to prevent the use of dynamic Huffman codes, allowing
+ for a simpler decoder for special applications.
+- `zlib.constants.Z_HUFFMAN_ONLY` Use to force Huffman encoding only (no string match).
+- `zlib.constants.Z_RLE` Use to limit match distances to one (run-length encoding).
+ This is designed to be almost as fast as `zlib.constants.Z_HUFFMAN_ONLY`, but give
+ better compression for PNG image data.
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### threshold
+
+Type: `Number` or `String`
+Default: `1kb`
+
+The byte threshold for the response body size before compression is considered
+for the response. This is a number of bytes or any string
+accepted by the [bytes](https://www.npmjs.com/package/bytes) module.
+
+**Note** this is only an advisory setting; if the response size cannot be determined
+at the time the response headers are written, then it is assumed the response is
+_over_ the threshold. To guarantee the response size can be determined, be sure
+set a `Content-Length` response header.
+
+##### windowBits
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_WINDOWBITS`, or `15`
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### enforceEncoding
+
+Type: `String`
+Default: `identity`
+
+This is the default encoding to use when the client does not specify an encoding in the request's [Accept-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) header.
+
+#### .filter
+
+The default `filter` function. This is used to construct a custom filter
+function that is an extension of the default function.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+app.use(compression({ filter: shouldCompress }));
+
+function shouldCompress(req, res) {
+ if (req.headers['x-no-compression']) {
+ // don't compress responses with this request header
+ return false;
+ }
+
+ // fallback to standard filter function
+ return compression.filter(req, res);
+}
+```
+
+### res.flush
+
+This module adds a `res.flush()` method to force the partially-compressed
+response to be flushed to the client.
+
+## Examples
+
+### express
+
+When using this module with express, simply `app.use` the module as
+high as you like. Requests that pass through the middleware will be compressed.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress all responses
+app.use(compression());
+
+// add all routes
+```
+
+### Node.js HTTP server
+
+```js
+var compression = require('compression')({ threshold: 0 });
+var http = require('http');
+
+function createServer(fn) {
+ return http.createServer(function (req, res) {
+ compression(req, res, function (err) {
+ if (err) {
+ res.statusCode = err.status || 500;
+ res.end(err.message);
+ return;
+ }
+
+ fn(req, res);
+ });
+ });
+}
+
+var server = createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello world!');
+});
+
+server.listen(3000, () => {
+ console.log('> Listening at http://localhost:3000');
+});
+```
+
+### Server-Sent Events
+
+Because of the nature of compression this module does not work out of the box
+with server-sent events. To compress content, a window of the output needs to
+be buffered up in order to get good compression. Typically when using server-sent
+events, there are certain block of data that need to reach the client.
+
+You can achieve this by calling `res.flush()` when you need the data written to
+actually make it to the client.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress responses
+app.use(compression());
+
+// server-sent event stream
+app.get('/events', function (req, res) {
+ res.setHeader('Content-Type', 'text/event-stream');
+ res.setHeader('Cache-Control', 'no-cache');
+
+ // send a ping approx every 2 seconds
+ var timer = setInterval(function () {
+ res.write('data: ping\n\n');
+
+ // !!! this is the important part
+ res.flush();
+ }, 2000);
+
+ res.on('close', function () {
+ clearInterval(timer);
+ });
+});
+```
+
+## Contributing
+
+The Express.js project welcomes all constructive contributions. Contributions take many forms,
+from code for bug fixes and enhancements, to additions and fixes to documentation, additional
+tests, triaging incoming pull requests and issues, and more!
+
+See the [Contributing Guide](https://github.com/expressjs/express/blob/master/Contributing.md) for more technical details on contributing.
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://badgen.net/npm/v/compression
+[npm-url]: https://npmjs.org/package/compression
+[downloads-image]: https://badgen.net/npm/dm/compression
+[downloads-url]: https://npmcharts.com/compare/compression?minimal=true
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/compression/master?label=CI
+[github-actions-ci-url]: https://github.com/expressjs/compression/actions?query=workflow%3Aci
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/compression/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/compression
+[funding-url]: https://opencollective.com/express
+[funding-image]: https://badgen.net/badge/icon/sponsor/pink?icon=github&label=Open%20Collective
diff --git a/astro/src/content/resources/zh-cn/middleware/cookie-parser.md b/astro/src/content/resources/zh-cn/middleware/cookie-parser.md
new file mode 100644
index 0000000000..2a59496387
--- /dev/null
+++ b/astro/src/content/resources/zh-cn/middleware/cookie-parser.md
@@ -0,0 +1,124 @@
+---
+title: Express cookie-parser middleware
+module: cookie-parser
+---
+
+# cookie-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Parse `Cookie` header and populate `req.cookies` with an object keyed by the
+cookie names. Optionally you may enable signed cookie support by passing a
+`secret` string, which assigns `req.secret` so it may be used by other
+middleware.
+
+## Installation
+
+```sh
+$ npm install cookie-parser
+```
+
+## API
+
+```js
+var cookieParser = require('cookie-parser');
+```
+
+### cookieParser(secret, options)
+
+Create a new cookie parser middleware function using the given `secret` and
+`options`.
+
+- `secret` a string or array used for signing cookies. This is optional and if
+ not specified, will not parse signed cookies. If a string is provided, this
+ is used as the secret. If an array is provided, an attempt will be made to
+ unsign the cookie with each secret in order.
+- `options` an object that is passed to `cookie.parse` as the second option. See
+ [cookie](https://www.npmjs.org/package/cookie) for more information.
+ - `decode` a function to decode the value of the cookie
+
+The middleware will parse the `Cookie` header on the request and expose the
+cookie data as the property `req.cookies` and, if a `secret` was provided, as
+the property `req.signedCookies`. These properties are name value pairs of the
+cookie name to cookie value.
+
+When `secret` is provided, this module will unsign and validate any signed cookie
+values and move those name value pairs from `req.cookies` into `req.signedCookies`.
+A signed cookie is a cookie that has a value prefixed with `s:`. Signed cookies
+that fail signature validation will have the value `false` instead of the tampered
+value.
+
+In addition, this module supports special "JSON cookies". These are cookie where
+the value is prefixed with `j:`. When these values are encountered, the value will
+be exposed as the result of `JSON.parse`. If parsing fails, the original value will
+remain.
+
+### cookieParser.JSONCookie(str)
+
+Parse a cookie value as a JSON cookie. This will return the parsed JSON value
+if it was a JSON cookie, otherwise, it will return the passed value.
+
+### cookieParser.JSONCookies(cookies)
+
+Given an object, this will iterate over the keys and call `JSONCookie` on each
+value, replacing the original value with the parsed value. This returns the
+same object that was passed in.
+
+### cookieParser.signedCookie(str, secret)
+
+Parse a cookie value as a signed cookie. This will return the parsed unsigned
+value if it was a signed cookie and the signature was valid. If the value was
+not signed, the original value is returned. If the value was signed but the
+signature could not be validated, `false` is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+### cookieParser.signedCookies(cookies, secret)
+
+Given an object, this will iterate over the keys and check if any value is a
+signed cookie. If it is a signed cookie and the signature is valid, the key
+will be deleted from the object and added to the new object that is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+## Example
+
+```js
+var express = require('express');
+var cookieParser = require('cookie-parser');
+
+var app = express();
+app.use(cookieParser());
+
+app.get('/', function (req, res) {
+ // Cookies that have not been signed
+ console.log('Cookies: ', req.cookies);
+
+ // Cookies that have been signed
+ console.log('Signed Cookies: ', req.signedCookies);
+});
+
+app.listen(8080);
+
+// curl command that sends an HTTP request with two cookies
+// curl http://127.0.0.1:8080 --cookie "Cho=Kim;Greet=Hello"
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/cookie-parser/master?label=ci
+[ci-url]: https://github.com/expressjs/cookie-parser/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/cookie-parser/master
+[coveralls-url]: https://coveralls.io/r/expressjs/cookie-parser?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/cookie-parser
+[npm-url]: https://npmjs.org/package/cookie-parser
+[npm-version-image]: https://badgen.net/npm/v/cookie-parser
diff --git a/astro/src/content/resources/zh-cn/middleware/cookie-session.md b/astro/src/content/resources/zh-cn/middleware/cookie-session.md
new file mode 100644
index 0000000000..2d6d1f885b
--- /dev/null
+++ b/astro/src/content/resources/zh-cn/middleware/cookie-session.md
@@ -0,0 +1,124 @@
+---
+title: Express cookie-session middleware
+module: cookie-session
+---
+
+# cookie-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Parse `Cookie` header and populate `req.cookies` with an object keyed by the
+cookie names. Optionally you may enable signed cookie support by passing a
+`secret` string, which assigns `req.secret` so it may be used by other
+middleware.
+
+## Installation
+
+```sh
+$ npm install cookie-parser
+```
+
+## API
+
+```js
+var cookieParser = require('cookie-parser');
+```
+
+### cookieParser(secret, options)
+
+Create a new cookie parser middleware function using the given `secret` and
+`options`.
+
+- `secret` a string or array used for signing cookies. This is optional and if
+ not specified, will not parse signed cookies. If a string is provided, this
+ is used as the secret. If an array is provided, an attempt will be made to
+ unsign the cookie with each secret in order.
+- `options` an object that is passed to `cookie.parse` as the second option. See
+ [cookie](https://www.npmjs.org/package/cookie) for more information.
+ - `decode` a function to decode the value of the cookie
+
+The middleware will parse the `Cookie` header on the request and expose the
+cookie data as the property `req.cookies` and, if a `secret` was provided, as
+the property `req.signedCookies`. These properties are name value pairs of the
+cookie name to cookie value.
+
+When `secret` is provided, this module will unsign and validate any signed cookie
+values and move those name value pairs from `req.cookies` into `req.signedCookies`.
+A signed cookie is a cookie that has a value prefixed with `s:`. Signed cookies
+that fail signature validation will have the value `false` instead of the tampered
+value.
+
+In addition, this module supports special "JSON cookies". These are cookie where
+the value is prefixed with `j:`. When these values are encountered, the value will
+be exposed as the result of `JSON.parse`. If parsing fails, the original value will
+remain.
+
+### cookieParser.JSONCookie(str)
+
+Parse a cookie value as a JSON cookie. This will return the parsed JSON value
+if it was a JSON cookie, otherwise, it will return the passed value.
+
+### cookieParser.JSONCookies(cookies)
+
+Given an object, this will iterate over the keys and call `JSONCookie` on each
+value, replacing the original value with the parsed value. This returns the
+same object that was passed in.
+
+### cookieParser.signedCookie(str, secret)
+
+Parse a cookie value as a signed cookie. This will return the parsed unsigned
+value if it was a signed cookie and the signature was valid. If the value was
+not signed, the original value is returned. If the value was signed but the
+signature could not be validated, `false` is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+### cookieParser.signedCookies(cookies, secret)
+
+Given an object, this will iterate over the keys and check if any value is a
+signed cookie. If it is a signed cookie and the signature is valid, the key
+will be deleted from the object and added to the new object that is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+## Example
+
+```js
+var express = require('express');
+var cookieParser = require('cookie-parser');
+
+var app = express();
+app.use(cookieParser());
+
+app.get('/', function (req, res) {
+ // Cookies that have not been signed
+ console.log('Cookies: ', req.cookies);
+
+ // Cookies that have been signed
+ console.log('Signed Cookies: ', req.signedCookies);
+});
+
+app.listen(8080);
+
+// curl command that sends an HTTP request with two cookies
+// curl http://127.0.0.1:8080 --cookie "Cho=Kim;Greet=Hello"
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/cookie-parser/master?label=ci
+[ci-url]: https://github.com/expressjs/cookie-parser/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/cookie-parser/master
+[coveralls-url]: https://coveralls.io/r/expressjs/cookie-parser?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/cookie-parser
+[npm-url]: https://npmjs.org/package/cookie-parser
+[npm-version-image]: https://badgen.net/npm/v/cookie-parser
diff --git a/astro/src/content/resources/zh-cn/middleware/cors.md b/astro/src/content/resources/zh-cn/middleware/cors.md
new file mode 100644
index 0000000000..55d70922cb
--- /dev/null
+++ b/astro/src/content/resources/zh-cn/middleware/cors.md
@@ -0,0 +1,261 @@
+---
+title: Express cors middleware
+module: cors
+---
+
+# cors
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+CORS is a [Node.js](https://nodejs.org/en/) package for providing a [Connect](https://github.com/senchalabs/connect)/[Express](https://expressjs.com/) middleware that can be used to enable [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS) with various options.
+
+- [Installation](#installation)
+- [Usage](#usage)
+ - [Simple Usage](#simple-usage-enable-all-cors-requests)
+ - [Enable CORS for a Single Route](#enable-cors-for-a-single-route)
+ - [Configuring CORS](#configuring-cors)
+ - [Configuring CORS w/ Dynamic Origin](#configuring-cors-w-dynamic-origin)
+ - [Enabling CORS Pre-Flight](#enabling-cors-pre-flight)
+ - [Customizing CORS Settings Dynamically per Request](#customizing-cors-settings-dynamically-per-request)
+- [Configuration Options](#configuration-options)
+- [License](#license)
+- [Original Author](#original-author)
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/downloading-and-installing-packages-locally):
+
+```sh
+$ npm install cors
+```
+
+## Usage
+
+### Simple Usage (Enable _All_ CORS Requests)
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.use(cors());
+
+app.get('/products/:id', function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for all origins!' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Enable CORS for a Single Route
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.get('/products/:id', cors(), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for a Single Route' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Configuring CORS
+
+See the [configuration options](#configuration-options) for details.
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+var corsOptions = {
+ origin: 'http://example.com',
+ optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
+};
+
+app.get('/products/:id', cors(corsOptions), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for only example.com.' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Configuring CORS w/ Dynamic Origin
+
+This module supports validating the origin dynamically using a function provided
+to the `origin` option. This function will be passed a string that is the origin
+(or `undefined` if the request has no origin), and a `callback` with the signature
+`callback(error, origin)`.
+
+The `origin` argument to the callback can be any value allowed for the `origin`
+option of the middleware, except a function. See the
+[configuration options](#configuration-options) section for more information on all
+the possible value types.
+
+This function is designed to allow the dynamic loading of allowed origin(s) from
+a backing datasource, like a database.
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+var corsOptions = {
+ origin: function (origin, callback) {
+ // db.loadOrigins is an example call to load
+ // a list of origins from a backing database
+ db.loadOrigins(function (error, origins) {
+ callback(error, origins);
+ });
+ },
+};
+
+app.get('/products/:id', cors(corsOptions), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for an allowed domain.' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Enabling CORS Pre-Flight
+
+Certain CORS requests are considered 'complex' and require an initial
+`OPTIONS` request (called the "pre-flight request"). An example of a
+'complex' CORS request is one that uses an HTTP verb other than
+GET/HEAD/POST (such as DELETE) or that uses custom headers. To enable
+pre-flighting, you must add a new OPTIONS handler for the route you want
+to support:
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.options('/products/:id', cors()); // enable pre-flight request for DELETE request
+app.del('/products/:id', cors(), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for all origins!' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+You can also enable pre-flight across-the-board like so:
+
+```javascript
+app.options('*', cors()); // include before other routes
+```
+
+NOTE: When using this middleware as an application level middleware (for
+example, `app.use(cors())`), pre-flight requests are already handled for all
+routes.
+
+### Customizing CORS Settings Dynamically per Request
+
+For APIs that require different CORS configurations for specific routes or requests, you can dynamically generate CORS options based on the incoming request. The `cors` middleware allows you to achieve this by passing a function instead of static options. This function is called for each incoming request and must use the callback pattern to return the appropriate CORS options.
+
+The function accepts:
+
+1. **`req`**:
+ - The incoming request object.
+
+2. **`callback(error, corsOptions)`**:
+ - A function used to return the computed CORS options.
+ - **Arguments**:
+ - **`error`**: Pass `null` if there’s no error, or an error object to indicate a failure.
+ - **`corsOptions`**: An object specifying the CORS policy for the current request.
+
+Here’s an example that handles both public routes and restricted, credential-sensitive routes:
+
+```javascript
+var dynamicCorsOptions = function (req, callback) {
+ var corsOptions;
+ if (req.path.startsWith('/auth/connect/')) {
+ corsOptions = {
+ origin: 'http://mydomain.com', // Allow only a specific origin
+ credentials: true, // Enable cookies and credentials
+ };
+ } else {
+ corsOptions = { origin: '*' }; // Allow all origins for other routes
+ }
+ callback(null, corsOptions);
+};
+
+app.use(cors(dynamicCorsOptions));
+
+app.get('/auth/connect/twitter', function (req, res) {
+ res.send('CORS dynamically applied for Twitter authentication.');
+});
+
+app.get('/public', function (req, res) {
+ res.send('Public data with open CORS.');
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+## Configuration Options
+
+- `origin`: Configures the **Access-Control-Allow-Origin** CORS header. Possible values:
+ - `Boolean` - set `origin` to `true` to reflect the [request origin](https://datatracker.ietf.org/doc/html/draft-abarth-origin-09), as defined by `req.header('Origin')`, or set it to `false` to disable CORS.
+ - `String` - set `origin` to a specific origin. For example, if you set it to
+ - `"http://example.com"` only requests from "http://example.com" will be allowed.
+ - `"*"` for all domains to be allowed.
+ - `RegExp` - set `origin` to a regular expression pattern which will be used to test the request origin. If it's a match, the request origin will be reflected. For example the pattern `/example\.com$/` will reflect any request that is coming from an origin ending with "example.com".
+ - `Array` - set `origin` to an array of valid origins. Each origin can be a `String` or a `RegExp`. For example `["http://example1.com", /\.example2\.com$/]` will accept any request from "http://example1.com" or from a subdomain of "example2.com".
+ - `Function` - set `origin` to a function implementing some custom logic. The function takes the request origin as the first parameter and a callback (called as `callback(err, origin)`, where `origin` is a non-function value of the `origin` option) as the second.
+- `methods`: Configures the **Access-Control-Allow-Methods** CORS header. Expects a comma-delimited string (ex: 'GET,PUT,POST') or an array (ex: `['GET', 'PUT', 'POST']`).
+- `allowedHeaders`: Configures the **Access-Control-Allow-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Type,Authorization') or an array (ex: `['Content-Type', 'Authorization']`). If not specified, defaults to reflecting the headers specified in the request's **Access-Control-Request-Headers** header.
+- `exposedHeaders`: Configures the **Access-Control-Expose-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Range,X-Content-Range') or an array (ex: `['Content-Range', 'X-Content-Range']`). If not specified, no custom headers are exposed.
+- `credentials`: Configures the **Access-Control-Allow-Credentials** CORS header. Set to `true` to pass the header, otherwise it is omitted.
+- `maxAge`: Configures the **Access-Control-Max-Age** CORS header. Set to an integer to pass the header, otherwise it is omitted.
+- `preflightContinue`: Pass the CORS preflight response to the next handler.
+- `optionsSuccessStatus`: Provides a status code to use for successful `OPTIONS` requests, since some legacy browsers (IE11, various SmartTVs) choke on `204`.
+
+The default configuration is the equivalent of:
+
+```json
+{
+ "origin": "*",
+ "methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
+ "preflightContinue": false,
+ "optionsSuccessStatus": 204
+}
+```
+
+For details on the effect of each CORS header, read [this](https://web.dev/articles/cross-origin-resource-sharing) article.
+
+## License
+
+[MIT License](http://www.opensource.org/licenses/mit-license.php)
+
+## Original Author
+
+[Troy Goode](https://github.com/TroyGoode) ([troygoode@gmail.com](mailto:troygoode@gmail.com))
+
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/cors/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/cors?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/cors.svg
+[downloads-url]: https://npmjs.com/package/cors
+[github-actions-ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/cors/ci.yml?branch=master&label=ci
+[github-actions-ci-url]: https://github.com/expressjs/cors?query=workflow%3Aci
+[npm-image]: https://img.shields.io/npm/v/cors.svg
+[npm-url]: https://npmjs.com/package/cors
diff --git a/astro/src/content/resources/zh-cn/middleware/errorhandler.md b/astro/src/content/resources/zh-cn/middleware/errorhandler.md
new file mode 100644
index 0000000000..20df618320
--- /dev/null
+++ b/astro/src/content/resources/zh-cn/middleware/errorhandler.md
@@ -0,0 +1,133 @@
+---
+title: Express errorhandler middleware
+module: errorhandler
+---
+
+# errorhandler
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Development-only error handler middleware.
+
+This middleware is only intended to be used in a development environment, as
+the _full error stack traces and internal details of any object passed to this
+module_ will be sent back to the client when an error occurs.
+
+When an object is provided to Express as an error, this module will display
+as much about this object as possible, and will do so by using content negotiation
+for the response between HTML, JSON, and plain text.
+
+- When the object is a standard `Error` object, the string provided by the
+ `stack` property will be returned in HTML/text responses.
+- When the object is a non-`Error` object, the result of
+ [util.inspect](https://nodejs.org/api/util.html#util_util_inspect_object_options)
+ will be returned in HTML/text responses.
+- For JSON responses, the result will be an object with all enumerable properties
+ from the object in the response.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install errorhandler
+```
+
+## API
+
+
+
+```js
+var errorhandler = require('errorhandler');
+```
+
+### errorhandler(options)
+
+Create new middleware to handle errors and respond with content negotiation.
+
+#### Options
+
+Error handler accepts these properties in the options object.
+
+##### log
+
+Provide a function to be called with the error and a string representation of
+the error. Can be used to write the error to any desired location, or set to
+`false` to only send the error back in the response. Called as
+`log(err, str, req, res)` where `err` is the `Error` object, `str` is a string
+representation of the error, `req` is the request object and `res` is the
+response object (note, this function is invoked _after_ the response has been
+written).
+
+The default value for this option is `true` unless `process.env.NODE_ENV === 'test'`.
+
+Possible values:
+
+- `true`: Log errors using `console.error(str)`.
+- `false`: Only send the error back in the response.
+- A function: pass the error to a function for handling.
+
+## Examples
+
+### Simple example
+
+Basic example of adding this middleware as the error handler only in development
+with `connect` (`express` also can be used in this example).
+
+```js
+var connect = require('connect');
+var errorhandler = require('errorhandler');
+
+var app = connect();
+
+// assumes NODE_ENV is set by the user
+if (process.env.NODE_ENV === 'development') {
+ // only use in development
+ app.use(errorhandler());
+}
+```
+
+### Custom output location
+
+Sometimes you may want to output the errors to a different location than STDERR
+during development, like a system notification, for example.
+
+
+
+```js
+var connect = require('connect');
+var errorhandler = require('errorhandler');
+var notifier = require('node-notifier');
+
+var app = connect();
+
+// assumes NODE_ENV is set by the user
+if (process.env.NODE_ENV === 'development') {
+ // only use in development
+ app.use(errorhandler({ log: errorNotification }));
+}
+
+function errorNotification(err, str, req) {
+ var title = 'Error in ' + req.method + ' ' + req.url;
+
+ notifier.notify({
+ title: title,
+ message: str,
+ });
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/errorhandler/master
+[coveralls-url]: https://coveralls.io/r/expressjs/errorhandler?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/errorhandler
+[npm-url]: https://npmjs.org/package/errorhandler
+[npm-version-image]: https://badgen.net/npm/v/errorhandler
diff --git a/astro/src/content/resources/zh-cn/middleware/method-override.md b/astro/src/content/resources/zh-cn/middleware/method-override.md
new file mode 100644
index 0000000000..7b97ab855e
--- /dev/null
+++ b/astro/src/content/resources/zh-cn/middleware/method-override.md
@@ -0,0 +1,187 @@
+---
+title: Express method-override middleware
+module: method-override
+---
+
+# method-override
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][travis-image]][travis-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Lets you use HTTP verbs such as PUT or DELETE in places where the client doesn't support it.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install method-override
+```
+
+## API
+
+**NOTE** It is very important that this module is used **before** any module that
+needs to know the method of the request (for example, it _must_ be used prior to
+the `csurf` module).
+
+### methodOverride(getter, options)
+
+Create a new middleware function to override the `req.method` property with a new
+value. This value will be pulled from the provided `getter`.
+
+- `getter` - The getter to use to look up the overridden request method for the request. (default: `X-HTTP-Method-Override`)
+- `options.methods` - The allowed methods the original request must be in to check for a method override value. (default: `['POST']`)
+
+If the found method is supported by node.js core, then `req.method` will be set to
+this value, as if it has originally been that value. The previous `req.method`
+value will be stored in `req.originalMethod`.
+
+#### getter
+
+This is the method of getting the override value from the request. If a function is provided,
+the `req` is passed as the first argument, the `res` as the second argument and the method is
+expected to be returned. If a string is provided, the string is used to look up the method
+with the following rules:
+
+- If the string starts with `X-`, then it is treated as the name of a header and that header
+ is used for the method override. If the request contains the same header multiple times, the
+ first occurrence is used.
+- All other strings are treated as a key in the URL query string.
+
+#### options.methods
+
+This allows the specification of what methods(s) the request _MUST_ be in in order to check for
+the method override value. This defaults to only `POST` methods, which is the only method the
+override should arrive in. More methods may be specified here, but it may introduce security
+issues and cause weird behavior when requests travel through caches. This value is an array
+of methods in upper-case. `null` can be specified to allow all methods.
+
+## Examples
+
+### override using a header
+
+To use a header to override the method, specify the header name
+as a string argument to the `methodOverride` function. To then make
+the call, send a `POST` request to a URL with the overridden method
+as the value of that header. This method of using a header would
+typically be used in conjunction with `XMLHttpRequest` on implementations
+that do not support the method you are trying to use.
+
+```js
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// override with the X-HTTP-Method-Override header in the request
+app.use(methodOverride('X-HTTP-Method-Override'));
+```
+
+Example call with header override using `XMLHttpRequest`:
+
+
+
+```js
+const xhr = new XMLHttpRequest();
+xhr.onload = onload;
+xhr.open('post', '/resource', true);
+xhr.setRequestHeader('X-HTTP-Method-Override', 'DELETE');
+xhr.send();
+
+function onload() {
+ alert('got response: ' + this.responseText);
+}
+```
+
+### override using a query value
+
+To use a query string value to override the method, specify the query
+string key as a string argument to the `methodOverride` function. To
+then make the call, send a `POST` request to a URL with the overridden
+method as the value of that query string key. This method of using a
+query value would typically be used in conjunction with plain HTML
+`
+```
+
+### multiple format support
+
+```js
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// override with different headers; last one takes precedence
+app.use(methodOverride('X-HTTP-Method')); // Microsoft
+app.use(methodOverride('X-HTTP-Method-Override')); // Google/GData
+app.use(methodOverride('X-Method-Override')); // IBM
+```
+
+### custom logic
+
+You can implement any kind of custom logic with a function for the `getter`. The following
+implements the logic for looking in `req.body` that was in `method-override@1`:
+
+```js
+const bodyParser = require('body-parser');
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// NOTE: when using req.body, you must fully parse the request body
+// before you call methodOverride() in your middleware stack,
+// otherwise req.body will not be populated.
+app.use(bodyParser.urlencoded());
+app.use(
+ methodOverride(function (req, res) {
+ if (req.body && typeof req.body === 'object' && '_method' in req.body) {
+ // look in urlencoded POST bodies and delete it
+ const method = req.body._method;
+ delete req.body._method;
+ return method;
+ }
+ })
+);
+```
+
+Example call with query override using HTML `
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/method-override.svg
+[npm-url]: https://npmjs.org/package/method-override
+[travis-image]: https://img.shields.io/travis/expressjs/method-override/master.svg
+[travis-url]: https://travis-ci.org/expressjs/method-override
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/method-override/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/method-override?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/method-override.svg
+[downloads-url]: https://npmjs.org/package/method-override
diff --git a/astro/src/content/resources/zh-cn/middleware/morgan.md b/astro/src/content/resources/zh-cn/middleware/morgan.md
new file mode 100644
index 0000000000..5319d93d57
--- /dev/null
+++ b/astro/src/content/resources/zh-cn/middleware/morgan.md
@@ -0,0 +1,458 @@
+---
+title: Express morgan middleware
+module: morgan
+---
+
+# morgan
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+HTTP request logger middleware for node.js
+
+> Named after [Dexter](http://en.wikipedia.org/wiki/Dexter_Morgan), a show you should not watch until completion.
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install morgan
+```
+
+## API
+
+
+
+```js
+var morgan = require('morgan');
+```
+
+### morgan(format, options)
+
+Create a new morgan logger middleware function using the given `format` and `options`.
+The `format` argument may be a string of a predefined name (see below for the names),
+a string of a format string, or a function that will produce a log entry.
+
+The `format` function will be called with three arguments `tokens`, `req`, and `res`,
+where `tokens` is an object with all defined tokens, `req` is the HTTP request and `res`
+is the HTTP response. The function is expected to return a string that will be the log
+line, or `undefined` / `null` to skip logging.
+
+#### Using a predefined format string
+
+
+
+```js
+morgan('tiny');
+```
+
+#### Using format string of predefined tokens
+
+
+
+```js
+morgan(':method :url :status :res[content-length] - :response-time ms');
+```
+
+#### Using a custom format function
+
+
+
+```js
+morgan(function (tokens, req, res) {
+ return [
+ tokens.method(req, res),
+ tokens.url(req, res),
+ tokens.status(req, res),
+ tokens.res(req, res, 'content-length'),
+ '-',
+ tokens['response-time'](req, res),
+ 'ms',
+ ].join(' ');
+});
+```
+
+#### Options
+
+Morgan accepts these properties in the options object.
+
+##### immediate
+
+Write log line on request instead of response. This means that a requests will
+be logged even if the server crashes, _but data from the response (like the
+response code, content length, etc.) cannot be logged_.
+
+##### skip
+
+Function to determine if logging is skipped, defaults to `false`. This function
+will be called as `skip(req, res)`.
+
+
+
+```js
+// EXAMPLE: only log error responses
+morgan('combined', {
+ skip: function (req, res) {
+ return res.statusCode < 400;
+ },
+});
+```
+
+##### stream
+
+Output stream for writing log lines, defaults to `process.stdout`.
+
+#### Predefined Formats
+
+There are various pre-defined formats provided:
+
+##### combined
+
+Standard Apache combined log output.
+
+```
+:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"
+# will output
+::1 - - [27/Nov/2024:06:21:42 +0000] "GET /combined HTTP/1.1" 200 2 "-" "curl/8.7.1"
+```
+
+##### common
+
+Standard Apache common log output.
+
+```
+:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length]
+# will output
+::1 - - [27/Nov/2024:06:21:46 +0000] "GET /common HTTP/1.1" 200 2
+```
+
+##### dev
+
+Concise output colored by response status for development use. The `:status`
+token will be colored green for success codes, red for server error codes,
+yellow for client error codes, cyan for redirection codes, and uncolored
+for information codes.
+
+```
+:method :url :status :response-time ms - :res[content-length]
+# will output
+GET /dev 200 0.224 ms - 2
+```
+
+##### short
+
+Shorter than default, also including response time.
+
+```
+:remote-addr :remote-user :method :url HTTP/:http-version :status :res[content-length] - :response-time ms
+# will output
+::1 - GET /short HTTP/1.1 200 2 - 0.283 ms
+```
+
+##### tiny
+
+The minimal output.
+
+```
+:method :url :status :res[content-length] - :response-time ms
+# will output
+GET /tiny 200 2 - 0.188 ms
+```
+
+#### Tokens
+
+##### Creating new tokens
+
+To define a token, simply invoke `morgan.token()` with the name and a callback function.
+This callback function is expected to return a string value. The value returned is then
+available as ":type" in this case:
+
+
+
+```js
+morgan.token('type', function (req, res) {
+ return req.headers['content-type'];
+});
+```
+
+Calling `morgan.token()` using the same name as an existing token will overwrite that
+token definition.
+
+The token function is expected to be called with the arguments `req` and `res`, representing
+the HTTP request and HTTP response. Additionally, the token can accept further arguments of
+it's choosing to customize behavior.
+
+##### :date[format]
+
+The current date and time in UTC. The available formats are:
+
+- `clf` for the common log format (`"10/Oct/2000:13:55:36 +0000"`)
+- `iso` for the common ISO 8601 date time format (`2000-10-10T13:55:36.000Z`)
+- `web` for the common RFC 1123 date time format (`Tue, 10 Oct 2000 13:55:36 GMT`)
+
+If no format is given, then the default is `web`.
+
+##### :http-version
+
+The HTTP version of the request.
+
+##### :method
+
+The HTTP method of the request.
+
+##### :pid
+
+The process ID of the Node.js process handling the request.
+
+##### :referrer
+
+The Referrer header of the request. This will use the standard mis-spelled Referer header if exists, otherwise Referrer.
+
+##### :remote-addr
+
+The remote address of the request. This will use `req.ip`, otherwise the standard `req.connection.remoteAddress` value (socket address).
+
+##### :remote-user
+
+The user authenticated as part of Basic auth for the request.
+
+##### :req[header]
+
+The given `header` of the request. If the header is not present, the
+value will be displayed as `"-"` in the log.
+
+##### :res[header]
+
+The given `header` of the response. If the header is not present, the
+value will be displayed as `"-"` in the log.
+
+##### :response-time[digits]
+
+The time between the request coming into `morgan` and when the response
+headers are written, in milliseconds.
+
+The `digits` argument is a number that specifies the number of digits to
+include on the number, defaulting to `3`, which provides microsecond precision.
+
+##### :status
+
+The status code of the response.
+
+If the request/response cycle completes before a response was sent to the
+client (for example, the TCP socket closed prematurely by a client aborting
+the request), then the status will be empty (displayed as `"-"` in the log).
+
+##### :total-time[digits]
+
+The time between the request coming into `morgan` and when the response
+has finished being written out to the connection, in milliseconds.
+
+The `digits` argument is a number that specifies the number of digits to
+include on the number, defaulting to `3`, which provides microsecond precision.
+
+##### :url
+
+The URL of the request. This will use `req.originalUrl` if exists, otherwise `req.url`.
+
+##### :user-agent
+
+The contents of the User-Agent header of the request.
+
+### morgan.compile(format)
+
+Compile a format string into a `format` function for use by `morgan`. A format string
+is a string that represents a single log line and can utilize token syntax.
+Tokens are references by `:token-name`. If tokens accept arguments, they can
+be passed using `[]`, for example: `:token-name[pretty]` would pass the string
+`'pretty'` as an argument to the token `token-name`.
+
+The function returned from `morgan.compile` takes three arguments `tokens`, `req`, and
+`res`, where `tokens` is object with all defined tokens, `req` is the HTTP request and
+`res` is the HTTP response. The function will return a string that will be the log line,
+or `undefined` / `null` to skip logging.
+
+Normally formats are defined using `morgan.format(name, format)`, but for certain
+advanced uses, this compile function is directly available.
+
+## Examples
+
+### express/connect
+
+Sample app that will log all request in the Apache combined format to STDOUT
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+
+var app = express();
+
+app.use(morgan('combined'));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### vanilla http server
+
+Sample app that will log all request in the Apache combined format to STDOUT
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var morgan = require('morgan');
+
+// create "middleware"
+var logger = morgan('combined');
+
+http.createServer(function (req, res) {
+ var done = finalhandler(req, res);
+ logger(req, res, function (err) {
+ if (err) return done(err);
+
+ // respond to request
+ res.setHeader('content-type', 'text/plain');
+ res.end('hello, world!');
+ });
+});
+```
+
+### write logs to a file
+
+#### single file
+
+Sample app that will log all requests in the Apache combined format to the file
+`access.log`.
+
+```js
+var express = require('express');
+var fs = require('fs');
+var morgan = require('morgan');
+var path = require('path');
+
+var app = express();
+
+// create a write stream (in append mode)
+var accessLogStream = fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' });
+
+// setup the logger
+app.use(morgan('combined', { stream: accessLogStream }));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+#### log file rotation
+
+Sample app that will log all requests in the Apache combined format to one log
+file per day in the `log/` directory using the
+[rotating-file-stream module](https://www.npmjs.com/package/rotating-file-stream).
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+var path = require('path');
+var rfs = require('rotating-file-stream'); // version 2.x
+
+var app = express();
+
+// create a rotating write stream
+var accessLogStream = rfs.createStream('access.log', {
+ interval: '1d', // rotate daily
+ path: path.join(__dirname, 'log'),
+});
+
+// setup the logger
+app.use(morgan('combined', { stream: accessLogStream }));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### split / dual logging
+
+The `morgan` middleware can be used as many times as needed, enabling
+combinations like:
+
+- Log entry on request and one on response
+- Log all requests to file, but errors to console
+- ... and more!
+
+Sample app that will log all requests to a file using Apache format, but
+error responses are logged to the console:
+
+```js
+var express = require('express');
+var fs = require('fs');
+var morgan = require('morgan');
+var path = require('path');
+
+var app = express();
+
+// log only 4xx and 5xx responses to console
+app.use(
+ morgan('dev', {
+ skip: function (req, res) {
+ return res.statusCode < 400;
+ },
+ })
+);
+
+// log all requests to access.log
+app.use(
+ morgan('common', {
+ stream: fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' }),
+ })
+);
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### use custom token formats
+
+Sample app that will use custom token formats. This adds an ID to all requests and displays it using the `:id` token.
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+var uuid = require('node-uuid');
+
+morgan.token('id', function getId(req) {
+ return req.id;
+});
+
+var app = express();
+
+app.use(assignId);
+app.use(morgan(':id :method :url :response-time'));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+
+function assignId(req, res, next) {
+ req.id = uuid.v4();
+ next();
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/morgan/master?label=ci
+[ci-url]: https://github.com/expressjs/morgan/actions/workflows/ci.yml
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/morgan/master
+[coveralls-url]: https://coveralls.io/r/expressjs/morgan?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/morgan
+[npm-url]: https://npmjs.org/package/morgan
+[npm-version-image]: https://badgen.net/npm/v/morgan
diff --git a/astro/src/content/resources/zh-cn/middleware/multer.md b/astro/src/content/resources/zh-cn/middleware/multer.md
new file mode 100644
index 0000000000..326786ab3d
--- /dev/null
+++ b/astro/src/content/resources/zh-cn/middleware/multer.md
@@ -0,0 +1,352 @@
+---
+title: Express multer middleware
+module: multer
+---
+
+# Multer [![NPM Version][npm-version-image]][npm-url] [![NPM Downloads][npm-downloads-image]][npm-url] [![Build Status][ci-image]][ci-url] [![Test Coverage][test-image]][test-url] [![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+
+Multer is a node.js middleware for handling `multipart/form-data`, which is primarily used for uploading files. It is written
+on top of [busboy](https://github.com/mscdex/busboy) for maximum efficiency.
+
+**NOTE**: Multer will not process any form which is not multipart (`multipart/form-data`).
+
+## Translations
+
+This README is also available in other languages:
+
+| | |
+| ------------------------------------------------------------------------------ | --------------- |
+| [العربية](https://github.com/expressjs/multer/blob/main/doc/README-ar.md) | Arabic |
+| [简体中文](https://github.com/expressjs/multer/blob/main/doc/README-zh-cn.md) | Chinese |
+| [Français](https://github.com/expressjs/multer/blob/main/doc/README-fr.md) | French |
+| [한국어](https://github.com/expressjs/multer/blob/main/doc/README-ko.md) | Korean |
+| [Português](https://github.com/expressjs/multer/blob/main/doc/README-pt-br.md) | Portuguese (BR) |
+| [Русский язык](https://github.com/expressjs/multer/blob/main/doc/README-ru.md) | Russian |
+| [Español](https://github.com/expressjs/multer/blob/main/doc/README-es.md) | Spanish |
+| [O'zbek tili](https://github.com/expressjs/multer/blob/main/doc/README-uz.md) | Uzbek |
+| [Việt Nam](https://github.com/expressjs/multer/blob/main/doc/README-vi.md) | Vietnamese |
+
+## Installation
+
+```sh
+$ npm install multer
+```
+
+## Usage
+
+Multer adds a `body` object and a `file` or `files` object to the `request` object. The `body` object contains the values of the text fields of the form, the `file` or `files` object contains the files uploaded via the form.
+
+Basic usage example:
+
+Don't forget the `enctype="multipart/form-data"` in your form.
+
+```html
+
+```
+
+```javascript
+const express = require('express');
+const multer = require('multer');
+const upload = multer({ dest: 'uploads/' });
+
+const app = express();
+
+app.post('/profile', upload.single('avatar'), function (req, res, next) {
+ // req.file is the `avatar` file
+ // req.body will hold the text fields, if there were any
+});
+
+app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
+ // req.files is array of `photos` files
+ // req.body will contain the text fields, if there were any
+});
+
+const uploadMiddleware = upload.fields([
+ { name: 'avatar', maxCount: 1 },
+ { name: 'gallery', maxCount: 8 },
+]);
+app.post('/cool-profile', uploadMiddleware, function (req, res, next) {
+ // req.files is an object (String -> Array) where fieldname is the key, and the value is array of files
+ //
+ // e.g.
+ // req.files['avatar'][0] -> File
+ // req.files['gallery'] -> Array
+ //
+ // req.body will contain the text fields, if there were any
+});
+```
+
+In case you need to handle a text-only multipart form, you should use the `.none()` method:
+
+```javascript
+const express = require('express');
+const app = express();
+const multer = require('multer');
+const upload = multer();
+
+app.post('/profile', upload.none(), function (req, res, next) {
+ // req.body contains the text fields
+});
+```
+
+Here's an example on how multer is used in a HTML form. Take special note of the `enctype="multipart/form-data"` and `name="uploaded_file"` fields:
+
+```html
+
+```
+
+Then in your javascript file you would add these lines to access both the file and the body. It is important that you use the `name` field value from the form in your upload function. This tells multer which field on the request it should look for the files in. If these fields aren't the same in the HTML form and on your server, your upload will fail:
+
+```javascript
+const multer = require('multer');
+const upload = multer({ dest: './public/data/uploads/' });
+app.post('/stats', upload.single('uploaded_file'), function (req, res) {
+ // req.file is the name of your file in the form above, here 'uploaded_file'
+ // req.body will hold the text fields, if there were any
+ console.log(req.file, req.body);
+});
+```
+
+## API
+
+### File information
+
+Each file contains the following information:
+
+| Key | Description | Note |
+| -------------- | --------------------------------------------- | --------------- |
+| `fieldname` | Field name specified in the form |
+| `originalname` | Name of the file on the user's computer |
+| `encoding` | Encoding type of the file |
+| `mimetype` | Mime type of the file |
+| `size` | Size of the file in bytes |
+| `destination` | The folder to which the file has been saved | `DiskStorage` |
+| `filename` | The name of the file within the `destination` | `DiskStorage` |
+| `path` | The full path to the uploaded file | `DiskStorage` |
+| `buffer` | A `Buffer` of the entire file | `MemoryStorage` |
+
+### `multer(opts)`
+
+Multer accepts an options object, the most basic of which is the `dest`
+property, which tells Multer where to upload the files. In case you omit the
+options object, the files will be kept in memory and never written to disk.
+
+By default, Multer will rename the files so as to avoid naming conflicts. The
+renaming function can be customized according to your needs.
+
+The following are the options that can be passed to Multer.
+
+| Key | Description |
+| ------------------- | --------------------------------------------------------- |
+| `dest` or `storage` | Where to store the files |
+| `fileFilter` | Function to control which files are accepted |
+| `limits` | Limits of the uploaded data |
+| `preservePath` | Keep the full path of files instead of just the base name |
+
+In an average web app, only `dest` might be required, and configured as shown in
+the following example.
+
+```javascript
+const upload = multer({ dest: 'uploads/' });
+```
+
+If you want more control over your uploads, you'll want to use the `storage`
+option instead of `dest`. Multer ships with storage engines `DiskStorage`
+and `MemoryStorage`; More engines are available from third parties.
+
+#### `.single(fieldname)`
+
+Accept a single file with the name `fieldname`. The single file will be stored
+in `req.file`.
+
+#### `.array(fieldname[, maxCount])`
+
+Accept an array of files, all with the name `fieldname`. Optionally error out if
+more than `maxCount` files are uploaded. The array of files will be stored in
+`req.files`.
+
+#### `.fields(fields)`
+
+Accept a mix of files, specified by `fields`. An object with arrays of files
+will be stored in `req.files`.
+
+`fields` should be an array of objects with `name` and optionally a `maxCount`.
+Example:
+
+```javascript
+[
+ { name: 'avatar', maxCount: 1 },
+ { name: 'gallery', maxCount: 8 },
+];
+```
+
+#### `.none()`
+
+Accept only text fields. If any file upload is made, error with code
+"LIMIT_UNEXPECTED_FILE" will be issued.
+
+#### `.any()`
+
+Accepts all files that comes over the wire. An array of files will be stored in
+`req.files`.
+
+**WARNING:** Make sure that you always handle the files that a user uploads.
+Never add multer as a global middleware since a malicious user could upload
+files to a route that you didn't anticipate. Only use this function on routes
+where you are handling the uploaded files.
+
+### `storage`
+
+#### `DiskStorage`
+
+The disk storage engine gives you full control on storing files to disk.
+
+```javascript
+const storage = multer.diskStorage({
+ destination: function (req, file, cb) {
+ cb(null, '/tmp/my-uploads');
+ },
+ filename: function (req, file, cb) {
+ const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
+ cb(null, file.fieldname + '-' + uniqueSuffix);
+ },
+});
+
+const upload = multer({ storage: storage });
+```
+
+There are two options available, `destination` and `filename`. They are both
+functions that determine where the file should be stored.
+
+`destination` is used to determine within which folder the uploaded files should
+be stored. This can also be given as a `string` (e.g. `'/tmp/uploads'`). If no
+`destination` is given, the operating system's default directory for temporary
+files is used.
+
+**Note:** You are responsible for creating the directory when providing
+`destination` as a function. When passing a string, multer will make sure that
+the directory is created for you.
+
+`filename` is used to determine what the file should be named inside the folder.
+If no `filename` is given, each file will be given a random name that doesn't
+include any file extension.
+
+**Note:** Multer will not append any file extension for you, your function
+should return a filename complete with a file extension.
+
+Each function gets passed both the request (`req`) and some information about
+the file (`file`) to aid with the decision.
+
+Note that `req.body` might not have been fully populated yet. It depends on the
+order that the client transmits fields and files to the server.
+
+For understanding the calling convention used in the callback (needing to pass
+null as the first param), refer to
+[Node.js error handling](https://web.archive.org/web/20220417042018/https://www.joyent.com/node-js/production/design/errors)
+
+#### `MemoryStorage`
+
+The memory storage engine stores the files in memory as `Buffer` objects. It
+doesn't have any options.
+
+```javascript
+const storage = multer.memoryStorage();
+const upload = multer({ storage: storage });
+```
+
+When using memory storage, the file info will contain a field called
+`buffer` that contains the entire file.
+
+**WARNING**: Uploading very large files, or relatively small files in large
+numbers very quickly, can cause your application to run out of memory when
+memory storage is used.
+
+### `limits`
+
+An object specifying the size limits of the following optional properties. Multer passes this object into busboy directly, and the details of the properties can be found on [busboy's page](https://github.com/mscdex/busboy#busboy-methods).
+
+The following integer values are available:
+
+| Key | Description | Default |
+| --------------- | ----------------------------------------------------------------------- | --------- |
+| `fieldNameSize` | Max field name size | 100 bytes |
+| `fieldSize` | Max field value size (in bytes) | 1MB |
+| `fields` | Max number of non-file fields | Infinity |
+| `fileSize` | For multipart forms, the max file size (in bytes) | Infinity |
+| `files` | For multipart forms, the max number of file fields | Infinity |
+| `parts` | For multipart forms, the max number of parts (fields + files) | Infinity |
+| `headerPairs` | For multipart forms, the max number of header key=>value pairs to parse | 2000 |
+
+Specifying the limits can help protect your site against denial of service (DoS) attacks.
+
+### `fileFilter`
+
+Set this to a function to control which files should be uploaded and which
+should be skipped. The function should look like this:
+
+```javascript
+function fileFilter(req, file, cb) {
+ // The function should call `cb` with a boolean
+ // to indicate if the file should be accepted
+
+ // To reject this file pass `false`, like so:
+ cb(null, false);
+
+ // To accept the file pass `true`, like so:
+ cb(null, true);
+
+ // You can always pass an error if something goes wrong:
+ cb(new Error("I don't have a clue!"));
+}
+```
+
+## Error handling
+
+When encountering an error, Multer will delegate the error to Express. You can
+display a nice error page using [the standard express way](http://expressjs.com/guide/error-handling.html).
+
+If you want to catch errors specifically from Multer, you can call the
+middleware function by yourself. Also, if you want to catch only [the Multer errors](https://github.com/expressjs/multer/blob/main/lib/multer-error.js), you can use the `MulterError` class that is attached to the `multer` object itself (e.g. `err instanceof multer.MulterError`).
+
+```javascript
+const multer = require('multer');
+const upload = multer().single('avatar');
+
+app.post('/profile', function (req, res) {
+ upload(req, res, function (err) {
+ if (err instanceof multer.MulterError) {
+ // A Multer error occurred when uploading.
+ } else if (err) {
+ // An unknown error occurred when uploading.
+ }
+
+ // Everything went fine.
+ });
+});
+```
+
+## Custom storage engine
+
+For information on how to build your own storage engine, see [Multer Storage Engine](https://github.com/expressjs/multer/blob/main/StorageEngine.md).
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://github.com/expressjs/multer/actions/workflows/ci.yml/badge.svg
+[ci-url]: https://github.com/expressjs/multer/actions/workflows/ci.yml
+[test-url]: https://coveralls.io/r/expressjs/multer?branch=main
+[test-image]: https://badgen.net/coveralls/c/github/expressjs/multer/main
+[npm-downloads-image]: https://badgen.net/npm/dm/multer
+[npm-url]: https://npmjs.org/package/multer
+[npm-version-image]: https://badgen.net/npm/v/multer
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/multer/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer
diff --git a/astro/src/content/resources/zh-cn/middleware/overview.md b/astro/src/content/resources/zh-cn/middleware/overview.md
new file mode 100755
index 0000000000..46217759e7
--- /dev/null
+++ b/astro/src/content/resources/zh-cn/middleware/overview.md
@@ -0,0 +1,40 @@
+---
+title: Express middleware
+description: Explore a list of Express.js middleware modules maintained by the Express team and the community, including built-in middleware and popular third-party modules.
+module: mw-home
+---
+
+## Express middleware
+
+The Express middleware modules listed here are maintained by the
+[Expressjs team](https://github.com/orgs/expressjs/people).
+
+| Middleware module | Description |
+| ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
+| [body-parser](/en/resources/middleware/body-parser) | Parse HTTP request body. |
+| [compression](/en/resources/middleware/compression) | Compress HTTP responses. |
+| [cookie-parser](/en/resources/middleware/cookie-parser) | Parse cookie header and populate `req.cookies`. See also [cookies](https://github.com/jed/cookies). |
+| [cookie-session](/en/resources/middleware/cookie-session) | Establish cookie-based sessions. |
+| [cors](/en/resources/middleware/cors) | Enable cross-origin resource sharing (CORS) with various options. |
+| [errorhandler](/en/resources/middleware/errorhandler) | Development error-handling/debugging. |
+| [method-override](/en/resources/middleware/method-override) | Override HTTP methods using header. |
+| [morgan](/en/resources/middleware/morgan) | HTTP request logger. |
+| [multer](/en/resources/middleware/multer) | Handle multi-part form data. |
+| [response-time](/en/resources/middleware/response-time) | Record HTTP response time. |
+| [serve-favicon](/en/resources/middleware/serve-favicon) | Serve a favicon. |
+| [serve-index](/en/resources/middleware/serve-index) | Serve directory listing for a given path. |
+| [serve-static](/en/resources/middleware/serve-static) | Serve static files. |
+| [session](/en/resources/middleware/session) | Establish server-based sessions (development only). |
+| [timeout](/en/resources/middleware/timeout) | Set a timeout perioHTTP request processing. |
+| [vhost](/en/resources/middleware/vhost) | Create virtual domains. |
+
+## Additional middleware modules
+
+These are some additional popular middleware modules.
+
+{% include community-caveat.html %}
+
+| Middleware module | Description |
+| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
+| [helmet](https://github.com/helmetjs/helmet) | Helps secure your apps by setting various HTTP headers. |
+| [passport](https://github.com/jaredhanson/passport) | Authentication using "strategies" such as OAuth, OpenID and many others. See [passportjs.org](https://passportjs.org/) for more information. |
diff --git a/astro/src/content/resources/zh-cn/middleware/response-time.md b/astro/src/content/resources/zh-cn/middleware/response-time.md
new file mode 100644
index 0000000000..f911f480f5
--- /dev/null
+++ b/astro/src/content/resources/zh-cn/middleware/response-time.md
@@ -0,0 +1,314 @@
+---
+title: Express response-time middleware
+module: response-time
+---
+
+# compression
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+[![Funding][funding-image]][funding-url]
+
+Node.js compression middleware.
+
+The following compression codings are supported:
+
+- deflate
+- gzip
+- br (brotli)
+
+**Note** Brotli is supported only since Node.js versions v11.7.0 and v10.16.0.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```bash
+$ npm install compression
+```
+
+## API
+
+```js
+var compression = require('compression');
+```
+
+### compression([options])
+
+Returns the compression middleware using the given `options`. The middleware
+will attempt to compress response bodies for all requests that traverse through
+the middleware, based on the given `options`.
+
+This middleware will never compress responses that include a `Cache-Control`
+header with the [`no-transform` directive](https://tools.ietf.org/html/rfc7234#section-5.2.2.4),
+as compressing will transform the body.
+
+#### Options
+
+`compression()` accepts these properties in the options object. In addition to
+those listed below, [zlib](https://nodejs.org/api/zlib.html) options may be
+passed in to the options object or
+[brotli](https://nodejs.org/api/zlib.html#zlib_class_brotlioptions) options.
+
+##### chunkSize
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_CHUNK`, or `16384`.
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### filter
+
+Type: `Function`
+
+A function to decide if the response should be considered for compression.
+This function is called as `filter(req, res)` and is expected to return
+`true` to consider the response for compression, or `false` to not compress
+the response.
+
+The default filter function uses the [compressible](https://www.npmjs.com/package/compressible)
+module to determine if `res.getHeader('Content-Type')` is compressible.
+
+##### level
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_COMPRESSION`, or `-1`
+
+The level of zlib compression to apply to responses. A higher level will result
+in better compression, but will take longer to complete. A lower level will
+result in less compression, but will be much faster.
+
+This is an integer in the range of `0` (no compression) to `9` (maximum
+compression). The special value `-1` can be used to mean the "default
+compression level", which is a default compromise between speed and
+compression (currently equivalent to level 6).
+
+- `-1` Default compression level (also `zlib.constants.Z_DEFAULT_COMPRESSION`).
+- `0` No compression (also `zlib.constants.Z_NO_COMPRESSION`).
+- `1` Fastest compression (also `zlib.constants.Z_BEST_SPEED`).
+- `2`
+- `3`
+- `4`
+- `5`
+- `6` (currently what `zlib.constants.Z_DEFAULT_COMPRESSION` points to).
+- `7`
+- `8`
+- `9` Best compression (also `zlib.constants.Z_BEST_COMPRESSION`).
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### memLevel
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_MEMLEVEL`, or `8`
+
+This specifies how much memory should be allocated for the internal compression
+state and is an integer in the range of `1` (minimum level) and `9` (maximum
+level).
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### brotli
+
+Type: `Object`
+
+This specifies the options for configuring Brotli. See [Node.js documentation](https://nodejs.org/api/zlib.html#class-brotlioptions) for a complete list of available options.
+
+##### strategy
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_STRATEGY`
+
+This is used to tune the compression algorithm. This value only affects the
+compression ratio, not the correctness of the compressed output, even if it
+is not set appropriately.
+
+- `zlib.constants.Z_DEFAULT_STRATEGY` Use for normal data.
+- `zlib.constants.Z_FILTERED` Use for data produced by a filter (or predictor).
+ Filtered data consists mostly of small values with a somewhat random
+ distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect is to force more Huffman coding and less
+ string matching; it is somewhat intermediate between `zlib.constants.Z_DEFAULT_STRATEGY`
+ and `zlib.constants.Z_HUFFMAN_ONLY`.
+- `zlib.constants.Z_FIXED` Use to prevent the use of dynamic Huffman codes, allowing
+ for a simpler decoder for special applications.
+- `zlib.constants.Z_HUFFMAN_ONLY` Use to force Huffman encoding only (no string match).
+- `zlib.constants.Z_RLE` Use to limit match distances to one (run-length encoding).
+ This is designed to be almost as fast as `zlib.constants.Z_HUFFMAN_ONLY`, but give
+ better compression for PNG image data.
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### threshold
+
+Type: `Number` or `String`
+Default: `1kb`
+
+The byte threshold for the response body size before compression is considered
+for the response. This is a number of bytes or any string
+accepted by the [bytes](https://www.npmjs.com/package/bytes) module.
+
+**Note** this is only an advisory setting; if the response size cannot be determined
+at the time the response headers are written, then it is assumed the response is
+_over_ the threshold. To guarantee the response size can be determined, be sure
+set a `Content-Length` response header.
+
+##### windowBits
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_WINDOWBITS`, or `15`
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### enforceEncoding
+
+Type: `String`
+Default: `identity`
+
+This is the default encoding to use when the client does not specify an encoding in the request's [Accept-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) header.
+
+#### .filter
+
+The default `filter` function. This is used to construct a custom filter
+function that is an extension of the default function.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+app.use(compression({ filter: shouldCompress }));
+
+function shouldCompress(req, res) {
+ if (req.headers['x-no-compression']) {
+ // don't compress responses with this request header
+ return false;
+ }
+
+ // fallback to standard filter function
+ return compression.filter(req, res);
+}
+```
+
+### res.flush
+
+This module adds a `res.flush()` method to force the partially-compressed
+response to be flushed to the client.
+
+## Examples
+
+### express
+
+When using this module with express, simply `app.use` the module as
+high as you like. Requests that pass through the middleware will be compressed.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress all responses
+app.use(compression());
+
+// add all routes
+```
+
+### Node.js HTTP server
+
+```js
+var compression = require('compression')({ threshold: 0 });
+var http = require('http');
+
+function createServer(fn) {
+ return http.createServer(function (req, res) {
+ compression(req, res, function (err) {
+ if (err) {
+ res.statusCode = err.status || 500;
+ res.end(err.message);
+ return;
+ }
+
+ fn(req, res);
+ });
+ });
+}
+
+var server = createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello world!');
+});
+
+server.listen(3000, () => {
+ console.log('> Listening at http://localhost:3000');
+});
+```
+
+### Server-Sent Events
+
+Because of the nature of compression this module does not work out of the box
+with server-sent events. To compress content, a window of the output needs to
+be buffered up in order to get good compression. Typically when using server-sent
+events, there are certain block of data that need to reach the client.
+
+You can achieve this by calling `res.flush()` when you need the data written to
+actually make it to the client.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress responses
+app.use(compression());
+
+// server-sent event stream
+app.get('/events', function (req, res) {
+ res.setHeader('Content-Type', 'text/event-stream');
+ res.setHeader('Cache-Control', 'no-cache');
+
+ // send a ping approx every 2 seconds
+ var timer = setInterval(function () {
+ res.write('data: ping\n\n');
+
+ // !!! this is the important part
+ res.flush();
+ }, 2000);
+
+ res.on('close', function () {
+ clearInterval(timer);
+ });
+});
+```
+
+## Contributing
+
+The Express.js project welcomes all constructive contributions. Contributions take many forms,
+from code for bug fixes and enhancements, to additions and fixes to documentation, additional
+tests, triaging incoming pull requests and issues, and more!
+
+See the [Contributing Guide](https://github.com/expressjs/express/blob/master/Contributing.md) for more technical details on contributing.
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://badgen.net/npm/v/compression
+[npm-url]: https://npmjs.org/package/compression
+[downloads-image]: https://badgen.net/npm/dm/compression
+[downloads-url]: https://npmcharts.com/compare/compression?minimal=true
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/compression/master?label=CI
+[github-actions-ci-url]: https://github.com/expressjs/compression/actions?query=workflow%3Aci
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/compression/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/compression
+[funding-url]: https://opencollective.com/express
+[funding-image]: https://badgen.net/badge/icon/sponsor/pink?icon=github&label=Open%20Collective
diff --git a/astro/src/content/resources/zh-cn/middleware/serve-favicon.md b/astro/src/content/resources/zh-cn/middleware/serve-favicon.md
new file mode 100644
index 0000000000..7a77865c6b
--- /dev/null
+++ b/astro/src/content/resources/zh-cn/middleware/serve-favicon.md
@@ -0,0 +1,156 @@
+---
+title: Express serve-favicon middleware
+module: serve-favicon
+---
+
+# serve-index
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Linux Build Status][ci-image]][ci-url]
+[![Windows Build][appveyor-image]][appveyor-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+Serves pages that contain directory listings for a given path.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-index
+```
+
+## API
+
+```js
+var serveIndex = require('serve-index');
+```
+
+### serveIndex(path, options)
+
+Returns middlware that serves an index of the directory in the given `path`.
+
+The `path` is based off the `req.url` value, so a `req.url` of `'/some/dir`
+with a `path` of `'public'` will look at `'public/some/dir'`. If you are using
+something like `express`, you can change the URL "base" with `app.use` (see
+the express example).
+
+#### Options
+
+Serve index accepts these properties in the options object.
+
+##### filter
+
+Apply this filter function to files. Defaults to `false`. The `filter` function
+is called for each file, with the signature `filter(filename, index, files, dir)`
+where `filename` is the name of the file, `index` is the array index, `files` is
+the array of files and `dir` is the absolute path the file is located (and thus,
+the directory the listing is for).
+
+##### hidden
+
+Display hidden (dot) files. Defaults to `false`.
+
+##### icons
+
+Display icons. Defaults to `false`.
+
+##### stylesheet
+
+Optional path to a CSS stylesheet. Defaults to a built-in stylesheet.
+
+##### template
+
+Optional path to an HTML template or a function that will render a HTML
+string. Defaults to a built-in template.
+
+When given a string, the string is used as a file path to load and then the
+following tokens are replaced in templates:
+
+- `{directory}` with the name of the directory.
+- `{files}` with the HTML of an unordered list of file links.
+- `{linked-path}` with the HTML of a link to the directory.
+- `{style}` with the specified stylesheet and embedded images.
+
+When given as a function, the function is called as `template(locals, callback)`
+and it needs to invoke `callback(error, htmlString)`. The following are the
+provided locals:
+
+- `directory` is the directory being displayed (where `/` is the root).
+- `displayIcons` is a Boolean for if icons should be rendered or not.
+- `fileList` is a sorted array of files in the directory. The array contains
+ objects with the following properties:
+ - `name` is the relative name for the file.
+ - `stat` is a `fs.Stats` object for the file.
+- `path` is the full filesystem path to `directory`.
+- `style` is the default stylesheet or the contents of the `stylesheet` option.
+- `viewName` is the view name provided by the `view` option.
+
+##### view
+
+Display mode. `tiles` and `details` are available. Defaults to `tiles`.
+
+## Examples
+
+### Serve directory indexes with vanilla node.js http server
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var serveIndex = require('serve-index');
+var serveStatic = require('serve-static');
+
+// Serve directory indexes for public/ftp folder (with icons)
+var index = serveIndex('public/ftp', { icons: true });
+
+// Serve up public/ftp folder files
+var serve = serveStatic('public/ftp');
+
+// Create server
+var server = http.createServer(function onRequest(req, res) {
+ var done = finalhandler(req, res);
+ serve(req, res, function onNext(err) {
+ if (err) return done(err);
+ index(req, res, done);
+ });
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve directory indexes with express
+
+```js
+var express = require('express');
+var serveIndex = require('serve-index');
+
+var app = express();
+
+// Serve URLs like /ftp/thing as public/ftp/thing
+// The express.static serves the file contents
+// The serveIndex is this module serving the directory
+app.use('/ftp', express.static('public/ftp'), serveIndex('public/ftp', { icons: true }));
+
+// Listen
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE). The [Silk](http://www.famfamfam.com/lab/icons/silk/) icons
+are created by/copyright of [FAMFAMFAM](http://www.famfamfam.com/).
+
+[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/serve-index/master.svg?label=windows
+[appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index
+[ci-image]: https://badgen.net/github/checks/expressjs/serve-index/master?label=ci
+[ci-url]: https://github.com/expressjs/serve-index/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/serve-index/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-index?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/serve-index.svg
+[downloads-url]: https://npmjs.org/package/serve-index
+[npm-image]: https://img.shields.io/npm/v/serve-index.svg
+[npm-url]: https://npmjs.org/package/serve-index
diff --git a/astro/src/content/resources/zh-cn/middleware/serve-index.md b/astro/src/content/resources/zh-cn/middleware/serve-index.md
new file mode 100644
index 0000000000..da03cf94b2
--- /dev/null
+++ b/astro/src/content/resources/zh-cn/middleware/serve-index.md
@@ -0,0 +1,156 @@
+---
+title: Express serve-index middleware
+module: serve-index
+---
+
+# serve-index
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Linux Build Status][ci-image]][ci-url]
+[![Windows Build][appveyor-image]][appveyor-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+Serves pages that contain directory listings for a given path.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-index
+```
+
+## API
+
+```js
+var serveIndex = require('serve-index');
+```
+
+### serveIndex(path, options)
+
+Returns middlware that serves an index of the directory in the given `path`.
+
+The `path` is based off the `req.url` value, so a `req.url` of `'/some/dir`
+with a `path` of `'public'` will look at `'public/some/dir'`. If you are using
+something like `express`, you can change the URL "base" with `app.use` (see
+the express example).
+
+#### Options
+
+Serve index accepts these properties in the options object.
+
+##### filter
+
+Apply this filter function to files. Defaults to `false`. The `filter` function
+is called for each file, with the signature `filter(filename, index, files, dir)`
+where `filename` is the name of the file, `index` is the array index, `files` is
+the array of files and `dir` is the absolute path the file is located (and thus,
+the directory the listing is for).
+
+##### hidden
+
+Display hidden (dot) files. Defaults to `false`.
+
+##### icons
+
+Display icons. Defaults to `false`.
+
+##### stylesheet
+
+Optional path to a CSS stylesheet. Defaults to a built-in stylesheet.
+
+##### template
+
+Optional path to an HTML template or a function that will render a HTML
+string. Defaults to a built-in template.
+
+When given a string, the string is used as a file path to load and then the
+following tokens are replaced in templates:
+
+- `{directory}` with the name of the directory.
+- `{files}` with the HTML of an unordered list of file links.
+- `{linked-path}` with the HTML of a link to the directory.
+- `{style}` with the specified stylesheet and embedded images.
+
+When given as a function, the function is called as `template(locals, callback)`
+and it needs to invoke `callback(error, htmlString)`. The following are the
+provided locals:
+
+- `directory` is the directory being displayed (where `/` is the root).
+- `displayIcons` is a Boolean for if icons should be rendered or not.
+- `fileList` is a sorted array of files in the directory. The array contains
+ objects with the following properties:
+ - `name` is the relative name for the file.
+ - `stat` is a `fs.Stats` object for the file.
+- `path` is the full filesystem path to `directory`.
+- `style` is the default stylesheet or the contents of the `stylesheet` option.
+- `viewName` is the view name provided by the `view` option.
+
+##### view
+
+Display mode. `tiles` and `details` are available. Defaults to `tiles`.
+
+## Examples
+
+### Serve directory indexes with vanilla node.js http server
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var serveIndex = require('serve-index');
+var serveStatic = require('serve-static');
+
+// Serve directory indexes for public/ftp folder (with icons)
+var index = serveIndex('public/ftp', { icons: true });
+
+// Serve up public/ftp folder files
+var serve = serveStatic('public/ftp');
+
+// Create server
+var server = http.createServer(function onRequest(req, res) {
+ var done = finalhandler(req, res);
+ serve(req, res, function onNext(err) {
+ if (err) return done(err);
+ index(req, res, done);
+ });
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve directory indexes with express
+
+```js
+var express = require('express');
+var serveIndex = require('serve-index');
+
+var app = express();
+
+// Serve URLs like /ftp/thing as public/ftp/thing
+// The express.static serves the file contents
+// The serveIndex is this module serving the directory
+app.use('/ftp', express.static('public/ftp'), serveIndex('public/ftp', { icons: true }));
+
+// Listen
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE). The [Silk](http://www.famfamfam.com/lab/icons/silk/) icons
+are created by/copyright of [FAMFAMFAM](http://www.famfamfam.com/).
+
+[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/serve-index/master.svg?label=windows
+[appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index
+[ci-image]: https://badgen.net/github/checks/expressjs/serve-index/master?label=ci
+[ci-url]: https://github.com/expressjs/serve-index/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/serve-index/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-index?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/serve-index.svg
+[downloads-url]: https://npmjs.org/package/serve-index
+[npm-image]: https://img.shields.io/npm/v/serve-index.svg
+[npm-url]: https://npmjs.org/package/serve-index
diff --git a/astro/src/content/resources/zh-cn/middleware/serve-static.md b/astro/src/content/resources/zh-cn/middleware/serve-static.md
new file mode 100644
index 0000000000..b048165d7b
--- /dev/null
+++ b/astro/src/content/resources/zh-cn/middleware/serve-static.md
@@ -0,0 +1,260 @@
+---
+title: Express serve-static middleware
+module: serve-static
+---
+
+# serve-static
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![CI][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-static
+```
+
+## API
+
+```js
+const serveStatic = require('serve-static');
+```
+
+### serveStatic(root, options)
+
+Create a new middleware function to serve files from within a given root
+directory. The file to serve will be determined by combining `req.url`
+with the provided root directory. When a file is not found, instead of
+sending a 404 response, this module will instead call `next()` to move on
+to the next middleware, allowing for stacking and fall-backs.
+
+#### Options
+
+##### acceptRanges
+
+Enable or disable accepting ranged requests, defaults to true.
+Disabling this will not send `Accept-Ranges` and ignore the contents
+of the `Range` request header.
+
+##### cacheControl
+
+Enable or disable setting `Cache-Control` response header, defaults to
+true. Disabling this will ignore the `immutable` and `maxAge` options.
+
+##### dotfiles
+
+Set how "dotfiles" are treated when encountered. A dotfile is a file
+or directory that begins with a dot ("."). Note this check is done on
+the path itself without checking if the path actually exists on the
+disk. If `root` is specified, only the dotfiles above the root are
+checked (i.e. the root itself can be within a dotfile when set
+to "deny").
+
+- `'allow'` No special treatment for dotfiles.
+- `'deny'` Deny a request for a dotfile and 403/`next()`.
+- `'ignore'` Pretend like the dotfile does not exist and 404/`next()`.
+
+The default value is `'ignore'`.
+
+##### etag
+
+Enable or disable etag generation, defaults to true.
+
+##### extensions
+
+Set file extension fallbacks. When set, if a file is not found, the given
+extensions will be added to the file name and search for. The first that
+exists will be served. Example: `['html', 'htm']`.
+
+The default value is `false`.
+
+##### fallthrough
+
+Set the middleware to have client errors fall-through as just unhandled
+requests, otherwise forward a client error. The difference is that client
+errors like a bad request or a request to a non-existent file will cause
+this middleware to simply `next()` to your next middleware when this value
+is `true`. When this value is `false`, these errors (even 404s), will invoke
+`next(err)`.
+
+Typically `true` is desired such that multiple physical directories can be
+mapped to the same web address or for routes to fill in non-existent files.
+
+The value `false` can be used if this middleware is mounted at a path that
+is designed to be strictly a single file system directory, which allows for
+short-circuiting 404s for less overhead. This middleware will also reply to
+all methods.
+
+The default value is `true`.
+
+##### immutable
+
+Enable or disable the `immutable` directive in the `Cache-Control` response
+header, defaults to `false`. If set to `true`, the `maxAge` option should
+also be specified to enable caching. The `immutable` directive will prevent
+supported clients from making conditional requests during the life of the
+`maxAge` option to check if the file has changed.
+
+##### index
+
+By default this module will send "index.html" files in response to a request
+on a directory. To disable this set `false` or to supply a new index pass a
+string or an array in preferred order.
+
+##### lastModified
+
+Enable or disable `Last-Modified` header, defaults to true. Uses the file
+system's last modified value.
+
+##### maxAge
+
+Provide a max-age in milliseconds for http caching, defaults to 0. This
+can also be a string accepted by the [ms](https://www.npmjs.org/package/ms#readme)
+module.
+
+##### redirect
+
+Redirect to trailing "/" when the pathname is a dir. Defaults to `true`.
+
+##### setHeaders
+
+Function to set custom headers on response. Alterations to the headers need to
+occur synchronously. The function is called as `fn(res, path, stat)`, where
+the arguments are:
+
+- `res` the response object
+- `path` the file path that is being sent
+- `stat` the stat object of the file that is being sent
+
+## Examples
+
+### Serve files with vanilla node.js http server
+
+```js
+const finalhandler = require('finalhandler');
+const http = require('http');
+const serveStatic = require('serve-static');
+
+// Serve up public/ftp folder
+const serve = serveStatic('public/ftp', { index: ['index.html', 'index.htm'] });
+
+// Create server
+const server = http.createServer((req, res) => {
+ serve(req, res, finalhandler(req, res));
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve all files as downloads
+
+```js
+const contentDisposition = require('content-disposition');
+const finalhandler = require('finalhandler');
+const http = require('http');
+const serveStatic = require('serve-static');
+
+// Serve up public/ftp folder
+const serve = serveStatic('public/ftp', {
+ index: false,
+ setHeaders: setHeaders,
+});
+
+// Set header to force download
+function setHeaders(res, path) {
+ res.setHeader('Content-Disposition', contentDisposition(path));
+}
+
+// Create server
+const server = http.createServer((req, res) => {
+ serve(req, res, finalhandler(req, res));
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serving using express
+
+#### Simple
+
+This is a simple example of using Express.
+
+```js
+const express = require('express');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(serveStatic('public/ftp', { index: ['default.html', 'default.htm'] }));
+app.listen(3000);
+```
+
+#### Multiple roots
+
+This example shows a simple way to search through multiple directories.
+Files are searched for in `public-optimized/` first, then `public/` second
+as a fallback.
+
+```js
+const express = require('express');
+const path = require('path');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(serveStatic(path.join(__dirname, 'public-optimized')));
+app.use(serveStatic(path.join(__dirname, 'public')));
+app.listen(3000);
+```
+
+#### Different settings for paths
+
+This example shows how to set a different max age depending on the served
+file. In this example, HTML files are not cached, while everything else
+is for 1 day.
+
+```js
+const express = require('express');
+const path = require('path');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(
+ serveStatic(path.join(__dirname, 'public'), {
+ maxAge: '1d',
+ setHeaders: setCustomCacheControl,
+ })
+);
+
+app.listen(3000);
+
+function setCustomCacheControl(res, file) {
+ if (path.extname(file) === '.html') {
+ // Custom Cache-Control for HTML files
+ res.setHeader('Cache-Control', 'public, max-age=0');
+ }
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/serve-static/master
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-static?branch=master
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/serve-static/master?label=linux
+[github-actions-ci-url]: https://github.com/expressjs/serve-static/actions/workflows/ci.yml
+[node-image]: https://badgen.net/npm/node/serve-static
+[node-url]: https://nodejs.org/en/download/
+[npm-downloads-image]: https://badgen.net/npm/dm/serve-static
+[npm-url]: https://npmjs.org/package/serve-static
+[npm-version-image]: https://badgen.net/npm/v/serve-static
diff --git a/astro/src/content/resources/zh-cn/middleware/session.md b/astro/src/content/resources/zh-cn/middleware/session.md
new file mode 100644
index 0000000000..90f3837a42
--- /dev/null
+++ b/astro/src/content/resources/zh-cn/middleware/session.md
@@ -0,0 +1,1046 @@
+---
+title: Express session middleware
+module: session
+---
+
+# express-session
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][node-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install express-session
+```
+
+## API
+
+```js
+var session = require('express-session');
+```
+
+### session(options)
+
+Create a session middleware with the given `options`.
+
+**Note** Session data is _not_ saved in the cookie itself, just the session ID.
+Session data is stored server-side.
+
+**Note** Since version 1.5.0, the [`cookie-parser` middleware](https://www.npmjs.com/package/cookie-parser)
+no longer needs to be used for this module to work. This module now directly reads
+and writes cookies on `req`/`res`. Using `cookie-parser` may result in issues
+if the `secret` is not the same between this module and `cookie-parser`.
+
+**Warning** The default server-side session storage, `MemoryStore`, is _purposely_
+not designed for a production environment. It will leak memory under most
+conditions, does not scale past a single process, and is meant for debugging and
+developing.
+
+For a list of stores, see [compatible session stores](#compatible-session-stores).
+
+#### Options
+
+`express-session` accepts these properties in the options object.
+
+##### cookie
+
+Settings object for the session ID cookie. The default value is
+`{ path: '/', httpOnly: true, secure: false, maxAge: null }`.
+
+The following are options that can be set in this object.
+
+##### cookie.domain
+
+Specifies the value for the `Domain` `Set-Cookie` attribute. By default, no domain
+is set, and most clients will consider the cookie to apply to only the current
+domain.
+
+##### cookie.expires
+
+Specifies the `Date` object to be the value for the `Expires` `Set-Cookie` attribute.
+By default, no expiration is set, and most clients will consider this a
+"non-persistent cookie" and will delete it on a condition like exiting a web browser
+application.
+
+**Note** If both `expires` and `maxAge` are set in the options, then the last one
+defined in the object is what is used.
+
+**Note** The `expires` option should not be set directly; instead only use the `maxAge`
+option.
+
+##### cookie.httpOnly
+
+Specifies the `boolean` value for the `HttpOnly` `Set-Cookie` attribute. When truthy,
+the `HttpOnly` attribute is set, otherwise it is not. By default, the `HttpOnly`
+attribute is set.
+
+**Note** be careful when setting this to `true`, as compliant clients will not allow
+client-side JavaScript to see the cookie in `document.cookie`.
+
+##### cookie.maxAge
+
+Specifies the `number` (in milliseconds) to use when calculating the `Expires`
+`Set-Cookie` attribute. This is done by taking the current server time and adding
+`maxAge` milliseconds to the value to calculate an `Expires` datetime. By default,
+no maximum age is set.
+
+**Note** If both `expires` and `maxAge` are set in the options, then the last one
+defined in the object is what is used.
+
+##### cookie.partitioned
+
+Specifies the `boolean` value for the [`Partitioned` `Set-Cookie`](rfc-cutler-httpbis-partitioned-cookies)
+attribute. When truthy, the `Partitioned` attribute is set, otherwise it is not.
+By default, the `Partitioned` attribute is not set.
+
+**Note** This is an attribute that has not yet been fully standardized, and may
+change in the future. This also means many clients may ignore this attribute until
+they understand it.
+
+More information about can be found in [the proposal](https://github.com/privacycg/CHIPS).
+
+##### cookie.path
+
+Specifies the value for the `Path` `Set-Cookie`. By default, this is set to `'/'`, which
+is the root path of the domain.
+
+##### cookie.priority
+
+Specifies the `string` to be the value for the [`Priority` `Set-Cookie` attribute][rfc-west-cookie-priority-00-4.1].
+
+- `'low'` will set the `Priority` attribute to `Low`.
+- `'medium'` will set the `Priority` attribute to `Medium`, the default priority when not set.
+- `'high'` will set the `Priority` attribute to `High`.
+
+More information about the different priority levels can be found in
+[the specification][rfc-west-cookie-priority-00-4.1].
+
+**Note** This is an attribute that has not yet been fully standardized, and may change in the future.
+This also means many clients may ignore this attribute until they understand it.
+
+##### cookie.sameSite
+
+Specifies the `boolean` or `string` to be the value for the `SameSite` `Set-Cookie` attribute.
+By default, this is `false`.
+
+- `true` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
+- `false` will not set the `SameSite` attribute.
+- `'lax'` will set the `SameSite` attribute to `Lax` for lax same site enforcement.
+- `'none'` will set the `SameSite` attribute to `None` for an explicit cross-site cookie.
+- `'strict'` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
+
+More information about the different enforcement levels can be found in
+[the specification][rfc-6265bis-03-4.1.2.7].
+
+**Note** This is an attribute that has not yet been fully standardized, and may change in
+the future. This also means many clients may ignore this attribute until they understand it.
+
+**Note** There is a [draft spec](https://tools.ietf.org/html/draft-west-cookie-incrementalism-01)
+that requires that the `Secure` attribute be set to `true` when the `SameSite` attribute has been
+set to `'none'`. Some web browsers or other clients may be adopting this specification.
+
+##### cookie.secure
+
+Specifies the `boolean` value for the `Secure` `Set-Cookie` attribute. When truthy,
+the `Secure` attribute is set, otherwise it is not. By default, the `Secure`
+attribute is not set.
+
+**Note** be careful when setting this to `true`, as compliant clients will not send
+the cookie back to the server in the future if the browser does not have an HTTPS
+connection.
+
+Please note that `secure: true` is a **recommended** option. However, it requires
+an https-enabled website, i.e., HTTPS is necessary for secure cookies. If `secure`
+is set, and you access your site over HTTP, the cookie will not be set. If you
+have your node.js behind a proxy and are using `secure: true`, you need to set
+"trust proxy" in express:
+
+```js
+var app = express();
+app.set('trust proxy', 1); // trust first proxy
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ cookie: { secure: true },
+ })
+);
+```
+
+For using secure cookies in production, but allowing for testing in development,
+the following is an example of enabling this setup based on `NODE_ENV` in express:
+
+```js
+var app = express();
+var sess = {
+ secret: 'keyboard cat',
+ cookie: {},
+};
+
+if (app.get('env') === 'production') {
+ app.set('trust proxy', 1); // trust first proxy
+ sess.cookie.secure = true; // serve secure cookies
+}
+
+app.use(session(sess));
+```
+
+The `cookie.secure` option can also be set to the special value `'auto'` to have
+this setting automatically match the determined security of the connection. Be
+careful when using this setting if the site is available both as HTTP and HTTPS,
+as once the cookie is set on HTTPS, it will no longer be visible over HTTP. This
+is useful when the Express `"trust proxy"` setting is properly setup to simplify
+development vs production configuration.
+
+##### genid
+
+Function to call to generate a new session ID. Provide a function that returns
+a string that will be used as a session ID. The function is given `req` as the
+first argument if you want to use some value attached to `req` when generating
+the ID.
+
+The default value is a function which uses the `uid-safe` library to generate IDs.
+
+**NOTE** be careful to generate unique IDs so your sessions do not conflict.
+
+```js
+app.use(
+ session({
+ genid: function (req) {
+ return genuuid(); // use UUIDs for session IDs
+ },
+ secret: 'keyboard cat',
+ })
+);
+```
+
+##### name
+
+The name of the session ID cookie to set in the response (and read from in the
+request).
+
+The default value is `'connect.sid'`.
+
+**Note** if you have multiple apps running on the same hostname (this is just
+the name, i.e. `localhost` or `127.0.0.1`; different schemes and ports do not
+name a different hostname), then you need to separate the session cookies from
+each other. The simplest method is to simply set different `name`s per app.
+
+##### proxy
+
+Trust the reverse proxy when setting secure cookies (via the "X-Forwarded-Proto"
+header).
+
+The default value is `undefined`.
+
+- `true` The "X-Forwarded-Proto" header will be used.
+- `false` All headers are ignored and the connection is considered secure only
+ if there is a direct TLS/SSL connection.
+- `undefined` Uses the "trust proxy" setting from express
+
+##### resave
+
+Forces the session to be saved back to the session store, even if the session
+was never modified during the request. Depending on your store this may be
+necessary, but it can also create race conditions where a client makes two
+parallel requests to your server and changes made to the session in one
+request may get overwritten when the other request ends, even if it made no
+changes (this behavior also depends on what store you're using).
+
+The default value is `true`, but using the default has been deprecated,
+as the default will change in the future. Please research into this setting
+and choose what is appropriate to your use-case. Typically, you'll want
+`false`.
+
+How do I know if this is necessary for my store? The best way to know is to
+check with your store if it implements the `touch` method. If it does, then
+you can safely set `resave: false`. If it does not implement the `touch`
+method and your store sets an expiration date on stored sessions, then you
+likely need `resave: true`.
+
+##### rolling
+
+Force the session identifier cookie to be set on every response. The expiration
+is reset to the original [`maxAge`](#cookiemaxage), resetting the expiration
+countdown.
+
+The default value is `false`.
+
+With this enabled, the session identifier cookie will expire in
+[`maxAge`](#cookiemaxage) since the last response was sent instead of in
+[`maxAge`](#cookiemaxage) since the session was last modified by the server.
+
+This is typically used in conjunction with short, non-session-length
+[`maxAge`](#cookiemaxage) values to provide a quick timeout of the session data
+with reduced potential of it occurring during on going server interactions.
+
+**Note** When this option is set to `true` but the `saveUninitialized` option is
+set to `false`, the cookie will not be set on a response with an uninitialized
+session. This option only modifies the behavior when an existing session was
+loaded for the request.
+
+##### saveUninitialized
+
+Forces a session that is "uninitialized" to be saved to the store. A session is
+uninitialized when it is new but not modified. Choosing `false` is useful for
+implementing login sessions, reducing server storage usage, or complying with
+laws that require permission before setting a cookie. Choosing `false` will also
+help with race conditions where a client makes multiple parallel requests
+without a session.
+
+The default value is `true`, but using the default has been deprecated, as the
+default will change in the future. Please research into this setting and
+choose what is appropriate to your use-case.
+
+**Note** if you are using Session in conjunction with PassportJS, Passport
+will add an empty Passport object to the session for use after a user is
+authenticated, which will be treated as a modification to the session, causing
+it to be saved. _This has been fixed in PassportJS 0.3.0_
+
+##### secret
+
+**Required option**
+
+This is the secret used to sign the session ID cookie. The secret can be any type
+of value that is supported by Node.js `crypto.createHmac` (like a string or a
+`Buffer`). This can be either a single secret, or an array of multiple secrets. If
+an array of secrets is provided, only the first element will be used to sign the
+session ID cookie, while all the elements will be considered when verifying the
+signature in requests. The secret itself should be not easily parsed by a human and
+would best be a random set of characters. A best practice may include:
+
+- The use of environment variables to store the secret, ensuring the secret itself
+ does not exist in your repository.
+- Periodic updates of the secret, while ensuring the previous secret is in the
+ array.
+
+Using a secret that cannot be guessed will reduce the ability to hijack a session to
+only guessing the session ID (as determined by the `genid` option).
+
+Changing the secret value will invalidate all existing sessions. In order to rotate
+the secret without invalidating sessions, provide an array of secrets, with the new
+secret as first element of the array, and including previous secrets as the later
+elements.
+
+**Note** HMAC-256 is used to sign the session ID. For this reason, the secret should
+contain at least 32 bytes of entropy.
+
+##### store
+
+The session store instance, defaults to a new `MemoryStore` instance.
+
+##### unset
+
+Control the result of unsetting `req.session` (through `delete`, setting to `null`,
+etc.).
+
+The default value is `'keep'`.
+
+- `'destroy'` The session will be destroyed (deleted) when the response ends.
+- `'keep'` The session in the store will be kept, but modifications made during
+ the request are ignored and not saved.
+
+### req.session
+
+To store or access session data, simply use the request property `req.session`,
+which is (generally) serialized as JSON by the store, so nested objects
+are typically fine. For example below is a user-specific view counter:
+
+```js
+// Use the session middleware
+app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 } }));
+
+// Access the session as req.session
+app.get('/', function (req, res, next) {
+ if (req.session.views) {
+ req.session.views++;
+ res.setHeader('Content-Type', 'text/html');
+ res.write('views: ' + req.session.views + '
');
+ res.write('expires in: ' + req.session.cookie.maxAge / 1000 + 's
');
+ res.end();
+ } else {
+ req.session.views = 1;
+ res.end('welcome to the session demo. refresh!');
+ }
+});
+```
+
+#### Session.regenerate(callback)
+
+To regenerate the session simply invoke the method. Once complete,
+a new SID and `Session` instance will be initialized at `req.session`
+and the `callback` will be invoked.
+
+```js
+req.session.regenerate(function (err) {
+ // will have a new session here
+});
+```
+
+#### Session.destroy(callback)
+
+Destroys the session and will unset the `req.session` property.
+Once complete, the `callback` will be invoked.
+
+```js
+req.session.destroy(function (err) {
+ // cannot access session here
+});
+```
+
+#### Session.reload(callback)
+
+Reloads the session data from the store and re-populates the
+`req.session` object. Once complete, the `callback` will be invoked.
+
+```js
+req.session.reload(function (err) {
+ // session updated
+});
+```
+
+#### Session.save(callback)
+
+Save the session back to the store, replacing the contents on the store with the
+contents in memory (though a store may do something else--consult the store's
+documentation for exact behavior).
+
+This method is automatically called at the end of the HTTP response if the
+session data has been altered (though this behavior can be altered with various
+options in the middleware constructor). Because of this, typically this method
+does not need to be called.
+
+There are some cases where it is useful to call this method, for example,
+redirects, long-lived requests or in WebSockets.
+
+```js
+req.session.save(function (err) {
+ // session saved
+});
+```
+
+#### Session.touch()
+
+Updates the `.maxAge` property. Typically this is
+not necessary to call, as the session middleware does this for you.
+
+### req.session.id
+
+Each session has a unique ID associated with it. This property is an
+alias of [`req.sessionID`](#reqsessionid-1) and cannot be modified.
+It has been added to make the session ID accessible from the `session`
+object.
+
+### req.session.cookie
+
+Each session has a unique cookie object accompany it. This allows
+you to alter the session cookie per visitor. For example we can
+set `req.session.cookie.expires` to `false` to enable the cookie
+to remain for only the duration of the user-agent.
+
+#### Cookie.maxAge
+
+Alternatively `req.session.cookie.maxAge` will return the time
+remaining in milliseconds, which we may also re-assign a new value
+to adjust the `.expires` property appropriately. The following
+are essentially equivalent
+
+```js
+var hour = 3600000;
+req.session.cookie.expires = new Date(Date.now() + hour);
+req.session.cookie.maxAge = hour;
+```
+
+For example when `maxAge` is set to `60000` (one minute), and 30 seconds
+has elapsed it will return `30000` until the current request has completed,
+at which time `req.session.touch()` is called to reset
+`req.session.cookie.maxAge` to its original value.
+
+```js
+req.session.cookie.maxAge; // => 30000
+```
+
+#### Cookie.originalMaxAge
+
+The `req.session.cookie.originalMaxAge` property returns the original
+`maxAge` (time-to-live), in milliseconds, of the session cookie.
+
+### req.sessionID
+
+To get the ID of the loaded session, access the request property
+`req.sessionID`. This is simply a read-only value set when a session
+is loaded/created.
+
+## Session Store Implementation
+
+Every session store _must_ be an `EventEmitter` and implement specific
+methods. The following methods are the list of **required**, **recommended**,
+and **optional**.
+
+- Required methods are ones that this module will always call on the store.
+- Recommended methods are ones that this module will call on the store if
+ available.
+- Optional methods are ones this module does not call at all, but helps
+ present uniform stores to users.
+
+For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo.
+
+### store.all(callback)
+
+**Optional**
+
+This optional method is used to get all sessions in the store as an array. The
+`callback` should be called as `callback(error, sessions)`.
+
+### store.destroy(sid, callback)
+
+**Required**
+
+This required method is used to destroy/delete a session from the store given
+a session ID (`sid`). The `callback` should be called as `callback(error)` once
+the session is destroyed.
+
+### store.clear(callback)
+
+**Optional**
+
+This optional method is used to delete all sessions from the store. The
+`callback` should be called as `callback(error)` once the store is cleared.
+
+### store.length(callback)
+
+**Optional**
+
+This optional method is used to get the count of all sessions in the store.
+The `callback` should be called as `callback(error, len)`.
+
+### store.get(sid, callback)
+
+**Required**
+
+This required method is used to get a session from the store given a session
+ID (`sid`). The `callback` should be called as `callback(error, session)`.
+
+The `session` argument should be a session if found, otherwise `null` or
+`undefined` if the session was not found (and there was no error). A special
+case is made when `error.code === 'ENOENT'` to act like `callback(null, null)`.
+
+### store.set(sid, session, callback)
+
+**Required**
+
+This required method is used to upsert a session into the store given a
+session ID (`sid`) and session (`session`) object. The callback should be
+called as `callback(error)` once the session has been set in the store.
+
+### store.touch(sid, session, callback)
+
+**Recommended**
+
+This recommended method is used to "touch" a given session given a
+session ID (`sid`) and session (`session`) object. The `callback` should be
+called as `callback(error)` once the session has been touched.
+
+This is primarily used when the store will automatically delete idle sessions
+and this method is used to signal to the store the given session is active,
+potentially resetting the idle timer.
+
+## Compatible Session Stores
+
+The following modules implement a session store that is compatible with this
+module. Please make a PR to add additional modules :)
+
+[![★][aerospike-session-store-image] aerospike-session-store][aerospike-session-store-url] A session store using [Aerospike](http://www.aerospike.com/).
+
+[aerospike-session-store-url]: https://www.npmjs.com/package/aerospike-session-store
+[aerospike-session-store-image]: https://badgen.net/github/stars/aerospike/aerospike-session-store-expressjs?label=%E2%98%85
+
+[![★][better-sqlite3-session-store-image] better-sqlite3-session-store][better-sqlite3-session-store-url] A session store based on [better-sqlite3](https://github.com/JoshuaWise/better-sqlite3).
+
+[better-sqlite3-session-store-url]: https://www.npmjs.com/package/better-sqlite3-session-store
+[better-sqlite3-session-store-image]: https://badgen.net/github/stars/timdaub/better-sqlite3-session-store?label=%E2%98%85
+
+[![★][cassandra-store-image] cassandra-store][cassandra-store-url] An Apache Cassandra-based session store.
+
+[cassandra-store-url]: https://www.npmjs.com/package/cassandra-store
+[cassandra-store-image]: https://badgen.net/github/stars/webcc/cassandra-store?label=%E2%98%85
+
+[![★][cluster-store-image] cluster-store][cluster-store-url] A wrapper for using in-process / embedded
+stores - such as SQLite (via knex), leveldb, files, or memory - with node cluster (desirable for Raspberry Pi 2
+and other multi-core embedded devices).
+
+[cluster-store-url]: https://www.npmjs.com/package/cluster-store
+[cluster-store-image]: https://badgen.net/github/stars/coolaj86/cluster-store?label=%E2%98%85
+
+[![★][connect-arango-image] connect-arango][connect-arango-url] An ArangoDB-based session store.
+
+[connect-arango-url]: https://www.npmjs.com/package/connect-arango
+[connect-arango-image]: https://badgen.net/github/stars/AlexanderArvidsson/connect-arango?label=%E2%98%85
+
+[![★][connect-azuretables-image] connect-azuretables][connect-azuretables-url] An [Azure Table Storage](https://azure.microsoft.com/en-gb/services/storage/tables/)-based session store.
+
+[connect-azuretables-url]: https://www.npmjs.com/package/connect-azuretables
+[connect-azuretables-image]: https://badgen.net/github/stars/mike-goodwin/connect-azuretables?label=%E2%98%85
+
+[![★][connect-cloudant-store-image] connect-cloudant-store][connect-cloudant-store-url] An [IBM Cloudant](https://cloudant.com/)-based session store.
+
+[connect-cloudant-store-url]: https://www.npmjs.com/package/connect-cloudant-store
+[connect-cloudant-store-image]: https://badgen.net/github/stars/adriantanasa/connect-cloudant-store?label=%E2%98%85
+
+[![★][connect-cosmosdb-image] connect-cosmosdb][connect-cosmosdb-url] An Azure [Cosmos DB](https://azure.microsoft.com/en-us/products/cosmos-db/)-based session store.
+
+[connect-cosmosdb-url]: https://www.npmjs.com/package/connect-cosmosdb
+[connect-cosmosdb-image]: https://badgen.net/github/stars/thekillingspree/connect-cosmosdb?label=%E2%98%85
+
+[![★][connect-couchbase-image] connect-couchbase][connect-couchbase-url] A [couchbase](http://www.couchbase.com/)-based session store.
+
+[connect-couchbase-url]: https://www.npmjs.com/package/connect-couchbase
+[connect-couchbase-image]: https://badgen.net/github/stars/christophermina/connect-couchbase?label=%E2%98%85
+
+[![★][connect-datacache-image] connect-datacache][connect-datacache-url] An [IBM Bluemix Data Cache](http://www.ibm.com/cloud-computing/bluemix/)-based session store.
+
+[connect-datacache-url]: https://www.npmjs.com/package/connect-datacache
+[connect-datacache-image]: https://badgen.net/github/stars/adriantanasa/connect-datacache?label=%E2%98%85
+
+[![★][@google-cloud/connect-datastore-image] @google-cloud/connect-datastore][@google-cloud/connect-datastore-url] A [Google Cloud Datastore](https://cloud.google.com/datastore/docs/concepts/overview)-based session store.
+
+[@google-cloud/connect-datastore-url]: https://www.npmjs.com/package/@google-cloud/connect-datastore
+[@google-cloud/connect-datastore-image]: https://badgen.net/github/stars/GoogleCloudPlatform/cloud-datastore-session-node?label=%E2%98%85
+
+[![★][connect-db2-image] connect-db2][connect-db2-url] An IBM DB2-based session store built using [ibm_db](https://www.npmjs.com/package/ibm_db) module.
+
+[connect-db2-url]: https://www.npmjs.com/package/connect-db2
+[connect-db2-image]: https://badgen.net/github/stars/wallali/connect-db2?label=%E2%98%85
+
+[![★][connect-dynamodb-image] connect-dynamodb][connect-dynamodb-url] A DynamoDB-based session store.
+
+[connect-dynamodb-url]: https://www.npmjs.com/package/connect-dynamodb
+[connect-dynamodb-image]: https://badgen.net/github/stars/ca98am79/connect-dynamodb?label=%E2%98%85
+
+[![★][@google-cloud/connect-firestore-image] @google-cloud/connect-firestore][@google-cloud/connect-firestore-url] A [Google Cloud Firestore](https://cloud.google.com/firestore/docs/overview)-based session store.
+
+[@google-cloud/connect-firestore-url]: https://www.npmjs.com/package/@google-cloud/connect-firestore
+[@google-cloud/connect-firestore-image]: https://badgen.net/github/stars/googleapis/nodejs-firestore-session?label=%E2%98%85
+
+[![★][connect-hazelcast-image] connect-hazelcast][connect-hazelcast-url] Hazelcast session store for Connect and Express.
+
+[connect-hazelcast-url]: https://www.npmjs.com/package/connect-hazelcast
+[connect-hazelcast-image]: https://badgen.net/github/stars/huseyinbabal/connect-hazelcast?label=%E2%98%85
+
+[![★][connect-loki-image] connect-loki][connect-loki-url] A Loki.js-based session store.
+
+[connect-loki-url]: https://www.npmjs.com/package/connect-loki
+[connect-loki-image]: https://badgen.net/github/stars/Requarks/connect-loki?label=%E2%98%85
+
+[![★][connect-lowdb-image] connect-lowdb][connect-lowdb-url] A lowdb-based session store.
+
+[connect-lowdb-url]: https://www.npmjs.com/package/connect-lowdb
+[connect-lowdb-image]: https://badgen.net/github/stars/travishorn/connect-lowdb?label=%E2%98%85
+
+[![★][connect-memcached-image] connect-memcached][connect-memcached-url] A memcached-based session store.
+
+[connect-memcached-url]: https://www.npmjs.com/package/connect-memcached
+[connect-memcached-image]: https://badgen.net/github/stars/balor/connect-memcached?label=%E2%98%85
+
+[![★][connect-memjs-image] connect-memjs][connect-memjs-url] A memcached-based session store using
+[memjs](https://www.npmjs.com/package/memjs) as the memcached client.
+
+[connect-memjs-url]: https://www.npmjs.com/package/connect-memjs
+[connect-memjs-image]: https://badgen.net/github/stars/liamdon/connect-memjs?label=%E2%98%85
+
+[![★][connect-ml-image] connect-ml][connect-ml-url] A MarkLogic Server-based session store.
+
+[connect-ml-url]: https://www.npmjs.com/package/connect-ml
+[connect-ml-image]: https://badgen.net/github/stars/bluetorch/connect-ml?label=%E2%98%85
+
+[![★][connect-monetdb-image] connect-monetdb][connect-monetdb-url] A MonetDB-based session store.
+
+[connect-monetdb-url]: https://www.npmjs.com/package/connect-monetdb
+[connect-monetdb-image]: https://badgen.net/github/stars/MonetDB/npm-connect-monetdb?label=%E2%98%85
+
+[![★][connect-mongo-image] connect-mongo][connect-mongo-url] A MongoDB-based session store.
+
+[connect-mongo-url]: https://www.npmjs.com/package/connect-mongo
+[connect-mongo-image]: https://badgen.net/github/stars/kcbanner/connect-mongo?label=%E2%98%85
+
+[![★][connect-mongodb-session-image] connect-mongodb-session][connect-mongodb-session-url] Lightweight MongoDB-based session store built and maintained by MongoDB.
+
+[connect-mongodb-session-url]: https://www.npmjs.com/package/connect-mongodb-session
+[connect-mongodb-session-image]: https://badgen.net/github/stars/mongodb-js/connect-mongodb-session?label=%E2%98%85
+
+[![★][connect-mssql-v2-image] connect-mssql-v2][connect-mssql-v2-url] A Microsoft SQL Server-based session store based on [connect-mssql](https://www.npmjs.com/package/connect-mssql).
+
+[connect-mssql-v2-url]: https://www.npmjs.com/package/connect-mssql-v2
+[connect-mssql-v2-image]: https://badgen.net/github/stars/jluboff/connect-mssql-v2?label=%E2%98%85
+
+[![★][connect-neo4j-image] connect-neo4j][connect-neo4j-url] A [Neo4j](https://neo4j.com)-based session store.
+
+[connect-neo4j-url]: https://www.npmjs.com/package/connect-neo4j
+[connect-neo4j-image]: https://badgen.net/github/stars/MaxAndersson/connect-neo4j?label=%E2%98%85
+
+[![★][connect-ottoman-image] connect-ottoman][connect-ottoman-url] A [couchbase ottoman](http://www.couchbase.com/)-based session store.
+
+[connect-ottoman-url]: https://www.npmjs.com/package/connect-ottoman
+[connect-ottoman-image]: https://badgen.net/github/stars/noiissyboy/connect-ottoman?label=%E2%98%85
+
+[![★][connect-pg-simple-image] connect-pg-simple][connect-pg-simple-url] A PostgreSQL-based session store.
+
+[connect-pg-simple-url]: https://www.npmjs.com/package/connect-pg-simple
+[connect-pg-simple-image]: https://badgen.net/github/stars/voxpelli/node-connect-pg-simple?label=%E2%98%85
+
+[![★][connect-redis-image] connect-redis][connect-redis-url] A Redis-based session store.
+
+[connect-redis-url]: https://www.npmjs.com/package/connect-redis
+[connect-redis-image]: https://badgen.net/github/stars/tj/connect-redis?label=%E2%98%85
+
+[![★][connect-session-firebase-image] connect-session-firebase][connect-session-firebase-url] A session store based on the [Firebase Realtime Database](https://firebase.google.com/docs/database/)
+
+[connect-session-firebase-url]: https://www.npmjs.com/package/connect-session-firebase
+[connect-session-firebase-image]: https://badgen.net/github/stars/benweier/connect-session-firebase?label=%E2%98%85
+
+[![★][connect-session-knex-image] connect-session-knex][connect-session-knex-url] A session store using
+[Knex.js](http://knexjs.org/), which is a SQL query builder for PostgreSQL, MySQL, MariaDB, SQLite3, and Oracle.
+
+[connect-session-knex-url]: https://www.npmjs.com/package/connect-session-knex
+[connect-session-knex-image]: https://badgen.net/github/stars/llambda/connect-session-knex?label=%E2%98%85
+
+[![★][connect-session-sequelize-image] connect-session-sequelize][connect-session-sequelize-url] A session store using
+[Sequelize.js](http://sequelizejs.com/), which is a Node.js / io.js ORM for PostgreSQL, MySQL, SQLite and MSSQL.
+
+[connect-session-sequelize-url]: https://www.npmjs.com/package/connect-session-sequelize
+[connect-session-sequelize-image]: https://badgen.net/github/stars/mweibel/connect-session-sequelize?label=%E2%98%85
+
+[![★][connect-sqlite3-image] connect-sqlite3][connect-sqlite3-url] A [SQLite3](https://github.com/mapbox/node-sqlite3) session store modeled after the TJ's `connect-redis` store.
+
+[connect-sqlite3-url]: https://www.npmjs.com/package/connect-sqlite3
+[connect-sqlite3-image]: https://badgen.net/github/stars/rawberg/connect-sqlite3?label=%E2%98%85
+
+[![★][connect-typeorm-image] connect-typeorm][connect-typeorm-url] A [TypeORM](https://github.com/typeorm/typeorm)-based session store.
+
+[connect-typeorm-url]: https://www.npmjs.com/package/connect-typeorm
+[connect-typeorm-image]: https://badgen.net/github/stars/makepost/connect-typeorm?label=%E2%98%85
+
+[![★][couchdb-expression-image] couchdb-expression][couchdb-expression-url] A [CouchDB](https://couchdb.apache.org/)-based session store.
+
+[couchdb-expression-url]: https://www.npmjs.com/package/couchdb-expression
+[couchdb-expression-image]: https://badgen.net/github/stars/tkshnwesper/couchdb-expression?label=%E2%98%85
+
+[![★][dynamodb-store-image] dynamodb-store][dynamodb-store-url] A DynamoDB-based session store.
+
+[dynamodb-store-url]: https://www.npmjs.com/package/dynamodb-store
+[dynamodb-store-image]: https://badgen.net/github/stars/rafaelrpinto/dynamodb-store?label=%E2%98%85
+
+[![★][dynamodb-store-v3-image] dynamodb-store-v3][dynamodb-store-v3-url] Implementation of a session store using DynamoDB backed by the [AWS SDK for JavaScript v3](https://github.com/aws/aws-sdk-js-v3).
+
+[dynamodb-store-v3-url]: https://www.npmjs.com/package/dynamodb-store-v3
+[dynamodb-store-v3-image]: https://badgen.net/github/stars/FryDay/dynamodb-store-v3?label=%E2%98%85
+
+[![★][express-etcd-image] express-etcd][express-etcd-url] An [etcd](https://github.com/stianeikeland/node-etcd) based session store.
+
+[express-etcd-url]: https://www.npmjs.com/package/express-etcd
+[express-etcd-image]: https://badgen.net/github/stars/gildean/express-etcd?label=%E2%98%85
+
+[![★][express-mysql-session-image] express-mysql-session][express-mysql-session-url] A session store using native
+[MySQL](https://www.mysql.com/) via the [node-mysql](https://github.com/felixge/node-mysql) module.
+
+[express-mysql-session-url]: https://www.npmjs.com/package/express-mysql-session
+[express-mysql-session-image]: https://badgen.net/github/stars/chill117/express-mysql-session?label=%E2%98%85
+
+[![★][express-nedb-session-image] express-nedb-session][express-nedb-session-url] A NeDB-based session store.
+
+[express-nedb-session-url]: https://www.npmjs.com/package/express-nedb-session
+[express-nedb-session-image]: https://badgen.net/github/stars/louischatriot/express-nedb-session?label=%E2%98%85
+
+[![★][express-oracle-session-image] express-oracle-session][express-oracle-session-url] A session store using native
+[oracle](https://www.oracle.com/) via the [node-oracledb](https://www.npmjs.com/package/oracledb) module.
+
+[express-oracle-session-url]: https://www.npmjs.com/package/express-oracle-session
+[express-oracle-session-image]: https://badgen.net/github/stars/slumber86/express-oracle-session?label=%E2%98%85
+
+[![★][express-session-cache-manager-image] express-session-cache-manager][express-session-cache-manager-url]
+A store that implements [cache-manager](https://www.npmjs.com/package/cache-manager), which supports
+a [variety of storage types](https://www.npmjs.com/package/cache-manager#store-engines).
+
+[express-session-cache-manager-url]: https://www.npmjs.com/package/express-session-cache-manager
+[express-session-cache-manager-image]: https://badgen.net/github/stars/theogravity/express-session-cache-manager?label=%E2%98%85
+
+[![★][express-session-etcd3-image] express-session-etcd3][express-session-etcd3-url] An [etcd3](https://github.com/mixer/etcd3) based session store.
+
+[express-session-etcd3-url]: https://www.npmjs.com/package/express-session-etcd3
+[express-session-etcd3-image]: https://badgen.net/github/stars/willgm/express-session-etcd3?label=%E2%98%85
+
+[![★][express-session-level-image] express-session-level][express-session-level-url] A [LevelDB](https://github.com/Level/levelup) based session store.
+
+[express-session-level-url]: https://www.npmjs.com/package/express-session-level
+[express-session-level-image]: https://badgen.net/github/stars/tgohn/express-session-level?label=%E2%98%85
+
+[![★][express-session-rsdb-image] express-session-rsdb][express-session-rsdb-url] Session store based on Rocket-Store: A very simple, super fast and yet powerful, flat file database.
+
+[express-session-rsdb-url]: https://www.npmjs.com/package/express-session-rsdb
+[express-session-rsdb-image]: https://badgen.net/github/stars/paragi/express-session-rsdb?label=%E2%98%85
+
+[![★][express-sessions-image] express-sessions][express-sessions-url] A session store supporting both MongoDB and Redis.
+
+[express-sessions-url]: https://www.npmjs.com/package/express-sessions
+[express-sessions-image]: https://badgen.net/github/stars/konteck/express-sessions?label=%E2%98%85
+
+[![★][firestore-store-image] firestore-store][firestore-store-url] A [Firestore](https://github.com/hendrysadrak/firestore-store)-based session store.
+
+[firestore-store-url]: https://www.npmjs.com/package/firestore-store
+[firestore-store-image]: https://badgen.net/github/stars/hendrysadrak/firestore-store?label=%E2%98%85
+
+[![★][fortune-session-image] fortune-session][fortune-session-url] A [Fortune.js](https://github.com/fortunejs/fortune)
+based session store. Supports all backends supported by Fortune (MongoDB, Redis, Postgres, NeDB).
+
+[fortune-session-url]: https://www.npmjs.com/package/fortune-session
+[fortune-session-image]: https://badgen.net/github/stars/aliceklipper/fortune-session?label=%E2%98%85
+
+[![★][hazelcast-store-image] hazelcast-store][hazelcast-store-url] A Hazelcast-based session store built on the [Hazelcast Node Client](https://www.npmjs.com/package/hazelcast-client).
+
+[hazelcast-store-url]: https://www.npmjs.com/package/hazelcast-store
+[hazelcast-store-image]: https://badgen.net/github/stars/jackspaniel/hazelcast-store?label=%E2%98%85
+
+[![★][level-session-store-image] level-session-store][level-session-store-url] A LevelDB-based session store.
+
+[level-session-store-url]: https://www.npmjs.com/package/level-session-store
+[level-session-store-image]: https://badgen.net/github/stars/toddself/level-session-store?label=%E2%98%85
+
+[![★][lowdb-session-store-image] lowdb-session-store][lowdb-session-store-url] A [lowdb](https://www.npmjs.com/package/lowdb)-based session store.
+
+[lowdb-session-store-url]: https://www.npmjs.com/package/lowdb-session-store
+[lowdb-session-store-image]: https://badgen.net/github/stars/fhellwig/lowdb-session-store?label=%E2%98%85
+
+[![★][medea-session-store-image] medea-session-store][medea-session-store-url] A Medea-based session store.
+
+[medea-session-store-url]: https://www.npmjs.com/package/medea-session-store
+[medea-session-store-image]: https://badgen.net/github/stars/BenjaminVadant/medea-session-store?label=%E2%98%85
+
+[![★][memorystore-image] memorystore][memorystore-url] A memory session store made for production.
+
+[memorystore-url]: https://www.npmjs.com/package/memorystore
+[memorystore-image]: https://badgen.net/github/stars/roccomuso/memorystore?label=%E2%98%85
+
+[![★][mssql-session-store-image] mssql-session-store][mssql-session-store-url] A SQL Server-based session store.
+
+[mssql-session-store-url]: https://www.npmjs.com/package/mssql-session-store
+[mssql-session-store-image]: https://badgen.net/github/stars/jwathen/mssql-session-store?label=%E2%98%85
+
+[![★][nedb-session-store-image] nedb-session-store][nedb-session-store-url] An alternate NeDB-based (either in-memory or file-persisted) session store.
+
+[nedb-session-store-url]: https://www.npmjs.com/package/nedb-session-store
+[nedb-session-store-image]: https://badgen.net/github/stars/JamesMGreene/nedb-session-store?label=%E2%98%85
+
+[![★][@quixo3/prisma-session-store-image] @quixo3/prisma-session-store][@quixo3/prisma-session-store-url] A session store for the [Prisma Framework](https://www.prisma.io).
+
+[@quixo3/prisma-session-store-url]: https://www.npmjs.com/package/@quixo3/prisma-session-store
+[@quixo3/prisma-session-store-image]: https://badgen.net/github/stars/kleydon/prisma-session-store?label=%E2%98%85
+
+[![★][restsession-image] restsession][restsession-url] Store sessions utilizing a RESTful API
+
+[restsession-url]: https://www.npmjs.com/package/restsession
+[restsession-image]: https://badgen.net/github/stars/jankal/restsession?label=%E2%98%85
+
+[![★][sequelstore-connect-image] sequelstore-connect][sequelstore-connect-url] A session store using [Sequelize.js](http://sequelizejs.com/).
+
+[sequelstore-connect-url]: https://www.npmjs.com/package/sequelstore-connect
+[sequelstore-connect-image]: https://badgen.net/github/stars/MattMcFarland/sequelstore-connect?label=%E2%98%85
+
+[![★][session-file-store-image] session-file-store][session-file-store-url] A file system-based session store.
+
+[session-file-store-url]: https://www.npmjs.com/package/session-file-store
+[session-file-store-image]: https://badgen.net/github/stars/valery-barysok/session-file-store?label=%E2%98%85
+
+[![★][session-pouchdb-store-image] session-pouchdb-store][session-pouchdb-store-url] Session store for PouchDB / CouchDB. Accepts embedded, custom, or remote PouchDB instance and realtime synchronization.
+
+[session-pouchdb-store-url]: https://www.npmjs.com/package/session-pouchdb-store
+[session-pouchdb-store-image]: https://badgen.net/github/stars/solzimer/session-pouchdb-store?label=%E2%98%85
+
+[![★][@cyclic.sh/session-store-image] @cyclic.sh/session-store][@cyclic.sh/session-store-url] A DynamoDB-based session store for [Cyclic.sh](https://www.cyclic.sh/) apps.
+
+[@cyclic.sh/session-store-url]: https://www.npmjs.com/package/@cyclic.sh/session-store
+[@cyclic.sh/session-store-image]: https://badgen.net/github/stars/cyclic-software/session-store?label=%E2%98%85
+
+[![★][@databunker/session-store-image] @databunker/session-store][@databunker/session-store-url] A [Databunker](https://databunker.org/)-based encrypted session store.
+
+[@databunker/session-store-url]: https://www.npmjs.com/package/@databunker/session-store
+[@databunker/session-store-image]: https://badgen.net/github/stars/securitybunker/databunker-session-store?label=%E2%98%85
+
+[![★][sessionstore-image] sessionstore][sessionstore-url] A session store that works with various databases.
+
+[sessionstore-url]: https://www.npmjs.com/package/sessionstore
+[sessionstore-image]: https://badgen.net/github/stars/adrai/sessionstore?label=%E2%98%85
+
+[![★][tch-nedb-session-image] tch-nedb-session][tch-nedb-session-url] A file system session store based on NeDB.
+
+[tch-nedb-session-url]: https://www.npmjs.com/package/tch-nedb-session
+[tch-nedb-session-image]: https://badgen.net/github/stars/tomaschyly/NeDBSession?label=%E2%98%85
+
+## Examples
+
+### View counter
+
+A simple example using `express-session` to store page views for a user.
+
+```js
+var express = require('express');
+var parseurl = require('parseurl');
+var session = require('express-session');
+
+var app = express();
+
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ })
+);
+
+app.use(function (req, res, next) {
+ if (!req.session.views) {
+ req.session.views = {};
+ }
+
+ // get the url pathname
+ var pathname = parseurl(req).pathname;
+
+ // count the views
+ req.session.views[pathname] = (req.session.views[pathname] || 0) + 1;
+
+ next();
+});
+
+app.get('/foo', function (req, res, next) {
+ res.send('you viewed this page ' + req.session.views['/foo'] + ' times');
+});
+
+app.get('/bar', function (req, res, next) {
+ res.send('you viewed this page ' + req.session.views['/bar'] + ' times');
+});
+
+app.listen(3000);
+```
+
+### User login
+
+A simple example using `express-session` to keep a user log in session.
+
+```js
+var escapeHtml = require('escape-html');
+var express = require('express');
+var session = require('express-session');
+
+var app = express();
+
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ })
+);
+
+// middleware to test if authenticated
+function isAuthenticated(req, res, next) {
+ if (req.session.user) next();
+ else next('route');
+}
+
+app.get('/', isAuthenticated, function (req, res) {
+ // this is only called when there is an authentication user due to isAuthenticated
+ res.send('hello, ' + escapeHtml(req.session.user) + '!' + ' Logout ');
+});
+
+app.get('/', function (req, res) {
+ res.send(
+ ''
+ );
+});
+
+app.post('/login', express.urlencoded({ extended: false }), function (req, res) {
+ // login logic to validate req.body.user and req.body.pass
+ // would be implemented here. for this example any combo works
+
+ // regenerate the session, which is good practice to help
+ // guard against forms of session fixation
+ req.session.regenerate(function (err) {
+ if (err) next(err);
+
+ // store user information in session, typically a user id
+ req.session.user = req.body.user;
+
+ // save the session before redirection to ensure page
+ // load does not happen before session is saved
+ req.session.save(function (err) {
+ if (err) return next(err);
+ res.redirect('/');
+ });
+ });
+});
+
+app.get('/logout', function (req, res, next) {
+ // logout logic
+
+ // clear the user from the session object and save.
+ // this will ensure that re-using the old session id
+ // does not have a logged in user
+ req.session.user = null;
+ req.session.save(function (err) {
+ if (err) next(err);
+
+ // regenerate the session, which is good practice to help
+ // guard against forms of session fixation
+ req.session.regenerate(function (err) {
+ if (err) next(err);
+ res.redirect('/');
+ });
+ });
+});
+
+app.listen(3000);
+```
+
+## Debugging
+
+This module uses the [debug](https://www.npmjs.com/package/debug) module
+internally to log information about session operations.
+
+To see all the internal logs, set the `DEBUG` environment variable to
+`express-session` when launching your app (`npm start`, in this example):
+
+```sh
+$ DEBUG=express-session npm start
+```
+
+On Windows, use the corresponding command;
+
+```sh
+> set DEBUG=express-session & npm start
+```
+
+## License
+
+[MIT](LICENSE)
+
+[rfc-6265bis-03-4.1.2.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7
+[rfc-cutler-httpbis-partitioned-cookies]: https://tools.ietf.org/html/draft-cutler-httpbis-partitioned-cookies/
+[rfc-west-cookie-priority-00-4.1]: https://tools.ietf.org/html/draft-west-cookie-priority-00#section-4.1
+[ci-image]: https://badgen.net/github/checks/expressjs/session/master?label=ci
+[ci-url]: https://github.com/expressjs/session/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/session/master
+[coveralls-url]: https://coveralls.io/r/expressjs/session?branch=master
+[node-url]: https://nodejs.org/en/download
+[npm-downloads-image]: https://badgen.net/npm/dm/express-session
+[npm-url]: https://npmjs.org/package/express-session
+[npm-version-image]: https://badgen.net/npm/v/express-session
diff --git a/astro/src/content/resources/zh-cn/middleware/timeout.md b/astro/src/content/resources/zh-cn/middleware/timeout.md
new file mode 100644
index 0000000000..f6057aedfd
--- /dev/null
+++ b/astro/src/content/resources/zh-cn/middleware/timeout.md
@@ -0,0 +1,176 @@
+---
+title: Express timeout middleware
+module: timeout
+---
+
+# connect-timeout
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][travis-image]][travis-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Times out a request in the Connect/Express application framework.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install connect-timeout
+```
+
+## API
+
+**NOTE** This module is not recommend as a "top-level" middleware (i.e.
+`app.use(timeout('5s'))`) unless you take precautions to halt your own
+middleware processing. See [as top-level middleware](#as-top-level-middleware)
+for how to use as a top-level middleware.
+
+While the library will emit a 'timeout' event when requests exceed the given
+timeout, node will continue processing the slow request until it terminates.
+Slow requests will continue to use CPU and memory, even if you are returning
+a HTTP response in the timeout callback. For better control over CPU/memory,
+you may need to find the events that are taking a long time (3rd party HTTP
+requests, disk I/O, database calls) and find a way to cancel them, and/or
+close the attached sockets.
+
+### timeout(time, [options])
+
+Returns middleware that times out in `time` milliseconds. `time` can also
+be a string accepted by the [ms](https://www.npmjs.org/package/ms#readme)
+module. On timeout, `req` will emit `"timeout"`.
+
+#### Options
+
+The `timeout` function takes an optional `options` object that may contain
+any of the following keys:
+
+##### respond
+
+Controls if this module will "respond" in the form of forwarding an error.
+If `true`, the timeout error is passed to `next()` so that you may customize
+the response behavior. This error has a `.timeout` property as well as
+`.status == 503`. This defaults to `true`.
+
+### req.clearTimeout()
+
+Clears the timeout on the request. The timeout is completely removed and
+will not fire for this request in the future.
+
+### req.timedout
+
+`true` if timeout fired; `false` otherwise.
+
+## Examples
+
+### as top-level middleware
+
+Because of the way middleware processing works, once this module
+passes the request to the next middleware (which it has to do in order
+for you to do work), it can no longer stop the flow, so you must take
+care to check if the request has timedout before you continue to act
+on the request.
+
+```javascript
+var bodyParser = require('body-parser');
+var cookieParser = require('cookie-parser');
+var express = require('express');
+var timeout = require('connect-timeout');
+
+// example of using this top-level; note the use of haltOnTimedout
+// after every middleware; it will stop the request flow on a timeout
+var app = express();
+app.use(timeout('5s'));
+app.use(bodyParser());
+app.use(haltOnTimedout);
+app.use(cookieParser());
+app.use(haltOnTimedout);
+
+// Add your routes here, etc.
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+app.listen(3000);
+```
+
+### express 3.x
+
+```javascript
+var express = require('express');
+var bodyParser = require('body-parser');
+var timeout = require('connect-timeout');
+
+var app = express();
+app.post('/save', timeout('5s'), bodyParser.json(), haltOnTimedout, function (req, res, next) {
+ savePost(req.body, function (err, id) {
+ if (err) return next(err);
+ if (req.timedout) return;
+ res.send('saved as id ' + id);
+ });
+});
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+function savePost(post, cb) {
+ setTimeout(
+ function () {
+ cb(null, (Math.random() * 40000) >>> 0);
+ },
+ (Math.random() * 7000) >>> 0
+ );
+}
+
+app.listen(3000);
+```
+
+### connect
+
+```javascript
+var bodyParser = require('body-parser');
+var connect = require('connect');
+var timeout = require('connect-timeout');
+
+var app = connect();
+app.use('/save', timeout('5s'), bodyParser.json(), haltOnTimedout, function (req, res, next) {
+ savePost(req.body, function (err, id) {
+ if (err) return next(err);
+ if (req.timedout) return;
+ res.send('saved as id ' + id);
+ });
+});
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+function savePost(post, cb) {
+ setTimeout(
+ function () {
+ cb(null, (Math.random() * 40000) >>> 0);
+ },
+ (Math.random() * 7000) >>> 0
+ );
+}
+
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/connect-timeout.svg
+[npm-url]: https://npmjs.org/package/connect-timeout
+[travis-image]: https://img.shields.io/travis/expressjs/timeout/master.svg
+[travis-url]: https://travis-ci.org/expressjs/timeout
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/timeout/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/timeout?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/connect-timeout.svg
+[downloads-url]: https://npmjs.org/package/connect-timeout
diff --git a/astro/src/content/resources/zh-cn/middleware/vhost.md b/astro/src/content/resources/zh-cn/middleware/vhost.md
new file mode 100644
index 0000000000..72f49d7f93
--- /dev/null
+++ b/astro/src/content/resources/zh-cn/middleware/vhost.md
@@ -0,0 +1,174 @@
+---
+title: Express vhost middleware
+module: vhost
+---
+
+# vhost
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Install
+
+```sh
+$ npm install vhost
+```
+
+## API
+
+```js
+var vhost = require('vhost');
+```
+
+### vhost(hostname, handle)
+
+Create a new middleware function to hand off request to `handle` when the incoming
+host for the request matches `hostname`. The function is called as
+`handle(req, res, next)`, like a standard middleware.
+
+`hostname` can be a string or a RegExp object. When `hostname` is a string it can
+contain `*` to match 1 or more characters in that section of the hostname. When
+`hostname` is a RegExp, it will be forced to case-insensitive (since hostnames are)
+and will be forced to match based on the start and end of the hostname.
+
+When host is matched and the request is sent down to a vhost handler, the `req.vhost`
+property will be populated with an object. This object will have numeric properties
+corresponding to each wildcard (or capture group if RegExp object provided) and the
+`hostname` that was matched.
+
+```js
+var connect = require('connect');
+var vhost = require('vhost');
+var app = connect();
+
+app.use(
+ vhost('*.*.example.com', function handle(req, res, next) {
+ // for match of "foo.bar.example.com:8080" against "*.*.example.com":
+ console.dir(req.vhost.host); // => 'foo.bar.example.com:8080'
+ console.dir(req.vhost.hostname); // => 'foo.bar.example.com'
+ console.dir(req.vhost.length); // => 2
+ console.dir(req.vhost[0]); // => 'foo'
+ console.dir(req.vhost[1]); // => 'bar'
+ })
+);
+```
+
+## Examples
+
+### using with connect for static serving
+
+```js
+var connect = require('connect');
+var serveStatic = require('serve-static');
+var vhost = require('vhost');
+
+var mailapp = connect();
+
+// add middlewares to mailapp for mail.example.com
+
+// create app to serve static files on subdomain
+var staticapp = connect();
+staticapp.use(serveStatic('public'));
+
+// create main app
+var app = connect();
+
+// add vhost routing to main app for mail
+app.use(vhost('mail.example.com', mailapp));
+
+// route static assets for "assets-*" subdomain to get
+// around max host connections limit on browsers
+app.use(vhost('assets-*.example.com', staticapp));
+
+// add middlewares and main usage to app
+
+app.listen(3000);
+```
+
+### using with connect for user subdomains
+
+```js
+var connect = require('connect');
+var serveStatic = require('serve-static');
+var vhost = require('vhost');
+
+var mainapp = connect();
+
+// add middlewares to mainapp for the main web site
+
+// create app that will server user content from public/{username}/
+var userapp = connect();
+
+userapp.use(function (req, res, next) {
+ var username = req.vhost[0]; // username is the "*"
+
+ // pretend request was for /{username}/* for file serving
+ req.originalUrl = req.url;
+ req.url = '/' + username + req.url;
+
+ next();
+});
+userapp.use(serveStatic('public'));
+
+// create main app
+var app = connect();
+
+// add vhost routing for main app
+app.use(vhost('userpages.local', mainapp));
+app.use(vhost('www.userpages.local', mainapp));
+
+// listen on all subdomains for user pages
+app.use(vhost('*.userpages.local', userapp));
+
+app.listen(3000);
+```
+
+### using with any generic request handler
+
+```js
+var connect = require('connect');
+var http = require('http');
+var vhost = require('vhost');
+
+// create main app
+var app = connect();
+
+app.use(
+ vhost('mail.example.com', function (req, res) {
+ // handle req + res belonging to mail.example.com
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello from mail!');
+ })
+);
+
+// an external api server in any framework
+var httpServer = http.createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello from the api!');
+});
+
+app.use(
+ vhost('api.example.com', function (req, res) {
+ // handle req + res belonging to api.example.com
+ // pass the request to a standard Node.js HTTP server
+ httpServer.emit('request', req, res);
+ })
+);
+
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/vhost.svg
+[npm-url]: https://npmjs.org/package/vhost
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/vhost/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/vhost
+[downloads-image]: https://img.shields.io/npm/dm/vhost.svg
+[downloads-url]: https://npmjs.org/package/vhost
+[github-actions-ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/vhost/ci.yml?branch=master&label=ci
+[github-actions-ci-url]: https://github.com/expressjs/vhost/actions/workflows/ci.yml
diff --git a/astro/src/content/resources/zh-cn/utils.md b/astro/src/content/resources/zh-cn/utils.md
new file mode 100644
index 0000000000..546b2f09b4
--- /dev/null
+++ b/astro/src/content/resources/zh-cn/utils.md
@@ -0,0 +1,22 @@
+---
+title: Express utilities
+description: Discover utility modules related to Express.js and Node.js, including tools for cookies, CSRF protection, URL parsing, routing, and more to enhance your applications.
+---
+
+## Express utility functions
+
+The [pillarjs](https://github.com/pillarjs) GitHub organization contains a number of modules
+for utility functions that may be generally useful.
+
+| Utility modules | Description |
+| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| [cookies](https://www.npmjs.com/package/cookies) | Get and set HTTP(S) cookies that can be signed to prevent tampering, using Keygrip. Can be used with the Node.js HTTP library or as Express middleware. |
+| [csrf](https://www.npmjs.com/package/csrf) | Contains the logic behind CSRF token creation and verification. Use this module to create custom CSRF middleware. |
+| [finalhandler](https://www.npmjs.com/package/finalhandler) | Function to invoke as the final step to respond to HTTP request. |
+| [parseurl](https://www.npmjs.com/package/parseurl) | Parse a URL with caching. |
+| [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) | Turn an Express-style path string such as ``/user/:name` into a regular expression. |
+| [resolve-path](https://www.npmjs.com/package/resolve-path) | Resolves a relative path against a root path with validation. |
+| [router](https://www.npmjs.com/package/router) | Simple middleware-style router. |
+| [send](https://www.npmjs.com/package/send) | Library for streaming files as a HTTP response, with support for partial responses (ranges), conditional-GET negotiation, and granular events. |
+
+For additional low-level HTTP-related modules, see [jshttp](https://github.com/jshttp).
diff --git a/astro/src/content/resources/zh-tw/community.md b/astro/src/content/resources/zh-tw/community.md
new file mode 100755
index 0000000000..e40d97e421
--- /dev/null
+++ b/astro/src/content/resources/zh-tw/community.md
@@ -0,0 +1,70 @@
+---
+title: Express community
+description: Connect with the Express.js community, learn about the technical committee, find resources, explore community-contributed modules, and get involved in discussions.
+---
+
+# Community
+
+## Technical committee
+
+The Express technical committee meets online every two weeks (as needed) to discuss development and maintenance of Express,
+and other issues relevant to the Express project. Each meeting is typically announced in an
+[expressjs/discussions issue](https://github.com/expressjs/discussions/issues) with a link to join or view the meeting, which is
+open to all observers.
+
+The meetings are recorded; for a list of the recordings, see the [Express.js YouTube channel](https://www.youtube.com/channel/UCYjxjAeH6TRik9Iwy5nXw7g).
+
+Members of the Express technical committee are:
+
+**Active:**
+
+- [@blakeembrey](https://github.com/blakeembrey) - Blake Embrey
+- [@crandmck](https://github.com/crandmck) - Rand McKinney
+- [@LinusU](https://github.com/LinusU) - Linus Unnebäck
+- [@ulisesgascon](https://github.com/ulisesGascon) - Ulises Gascón
+- [@sheplu](https://github.com/sheplu) - Jean Burellier
+- [@wesleytodd](https://github.com/wesleytodd) - Wes Todd
+- [@jonchurch](https://github.com/jonchurch) - Jon Church
+- [@ctcpip](https://github.com/ctcpip/) - Chris de Almeida
+
+**Inactive:**
+
+- [@dougwilson](https://github.com/dougwilson) - Douglas Wilson
+- [@hacksparrow](https://github.com/hacksparrow) - Hage Yaapa
+- [@jonathanong](https://github.com/jonathanong) - jongleberry
+- [@niftylettuce](https://github.com/niftylettuce) - niftylettuce
+- [@troygoode](https://github.com/troygoode) - Troy Goode
+
+## Express is made of many modules
+
+Our vibrant community has created a large variety of extensions,
+[middleware modules](/en/resources/middleware) and higher-level frameworks.
+
+Additionally, the Express community maintains modules in these two GitHub orgs:
+
+- [jshttp](https://github.com/jshttp) modules providing useful utility functions; see [Utility modules](/en/resources/utils).
+- [pillarjs](https://github.com/pillarjs): low-level modules that Express uses internally.
+
+To keep up with what is going on in the whole community, check out the [ExpressJS StatusBoard](https://expressjs.github.io/statusboard/).
+
+## Issues
+
+If you've come across what you think is a bug, or just want to make
+a feature request open a ticket in the [issue queue](https://github.com/expressjs/express/issues).
+
+## Examples
+
+View dozens of Express application [examples](https://github.com/expressjs/express/tree/master/examples)
+in the repository covering everything from API design and authentication to template engine integration.
+
+## Github Discussions
+
+The [GitHub Discussions](https://github.com/expressjs/discussions) section is an excellent space to engage in conversations about the development and maintenance of Express, as well as to share ideas and discuss topics related to its usage.
+
+# Branding of Express.js
+
+## Express.js Logo
+
+Express is a project of the OpenJS Foundation. Please review the [trademark policy](https://trademark-policy.openjsf.org/) for information about permissible use of Express.js logos and marks.
+
+
diff --git a/astro/src/content/resources/zh-tw/contributing.md b/astro/src/content/resources/zh-tw/contributing.md
new file mode 100644
index 0000000000..82c6b8fed7
--- /dev/null
+++ b/astro/src/content/resources/zh-tw/contributing.md
@@ -0,0 +1,482 @@
+---
+title: Contributing to Express
+description: Find out how to contribute to Express.js, including guidelines for reporting issues, submitting pull requests, becoming a collaborator, and understanding security policies.
+---
+
+# Contributing to Express
+
+### Looking to contribute to Expressjs.com? Click [here](#expressjs-website-contributing).
+
+Express and the other projects in the [expressjs organization on GitHub](https://github.com/expressjs) are projects of the [OpenJs Foundation](https://openjsf.org/).
+These projects are governed under the general policies and guidelines of the Node.js Foundation along with the additional guidelines below.
+
+- [Technical committee](#technical-committee)
+- [Community contributing guide](#community-contributing-guide)
+- [Collaborator's guide](#collaborators-guide)
+- [Security policies and procedures](#security-policies-and-procedures)
+
+## Technical committee
+
+The Express technical committee consists of active project members, and guides development and maintenance of the Express project. For more information, see [Express Community - Technical committee](/en/resources/community/#technical-committee).
+
+## Community contributing guide
+
+
+
+The goal of this document is to create a contribution process that:
+
+- Encourages new contributions.
+- Encourages contributors to remain involved.
+- Avoids unnecessary processes and bureaucracy whenever possible.
+- Creates a transparent decision making process that makes it clear how
+ contributors can be involved in decision making.
+
+### Vocabulary
+
+- A **Contributor** is any individual creating or commenting on an issue or pull request.
+- A **Committer** is a subset of contributors who have been given write access to the repository.
+- A **Project Captain** is the lead maintainer of a repository.
+- A **TC (Technical Committee)** is a group of committers representing the required technical
+ expertise to resolve rare disputes.
+- A **Triager** is a subset of contributors who have been given triage access to the repository.
+
+### Logging Issues
+
+Log an issue for any question or problem you might have. When in doubt, log an issue, and
+any additional policies about what to include will be provided in the responses. The only
+exception is security disclosures which should be sent privately.
+
+Committers may direct you to another repository, ask for additional clarifications, and
+add appropriate metadata before the issue is addressed.
+
+Please be courteous and respectful. Every participant is expected to follow the
+project's Code of Conduct.
+
+### Contributions
+
+Any change to resources in this repository must be through pull requests. This applies to all changes
+to documentation, code, binary files, etc. Even long term committers and TC members must use
+pull requests.
+
+No pull request can be merged without being reviewed.
+
+For non-trivial contributions, pull requests should sit for at least 36 hours to ensure that
+contributors in other timezones have time to review. Consideration should also be given to
+weekends and other holiday periods to ensure active committers all have reasonable time to
+become involved in the discussion and review process if they wish.
+
+The default for each contribution is that it is accepted once no committer has an objection.
+During a review, committers may also request that a specific contributor who is most versed in a
+particular area gives a "LGTM" before the PR can be merged. There is no additional "sign off"
+process for contributions to land. Once all issues brought by committers are addressed it can
+be landed by any committer.
+
+In the case of an objection being raised in a pull request by another committer, all involved
+committers should seek to arrive at a consensus by way of addressing concerns being expressed
+by discussion, compromise on the proposed change, or withdrawal of the proposed change.
+
+If a contribution is controversial and committers cannot agree about how to get it to land
+or if it should land then it should be escalated to the TC. TC members should regularly
+discuss pending contributions in order to find a resolution. It is expected that only a
+small minority of issues be brought to the TC for resolution and that discussion and
+compromise among committers be the default resolution mechanism.
+
+### Becoming a Triager
+
+Anyone can become a triager! Read more about the process of being a triager in
+[the triage process document](https://github.com/expressjs/discussions/blob/master/Triager-Guide.md).
+
+Currently, any existing [organization member](https://github.com/orgs/expressjs/people) can nominate
+a new triager. If you are interested in becoming a triager, our best advice is to actively participate
+in the community by helping triaging issues and pull requests. As well we recommend
+to engage in other community activities like attending the TC meetings, and participating in the Slack
+discussions. If you feel ready and have been helping triage some issues, reach out to an active member of the organization to ask if they'd
+be willing to support you. If they agree, they can create a pull request to formalize your nomination. In the case of an objection to the nomination, the triage team is responsible for working with the individuals involved and finding a resolution.
+
+You can also reach out to any of the [organization members](https://github.com/orgs/expressjs/people)
+if you have questions or need guidance.
+
+### Becoming a Committer
+
+All contributors who have landed significant and valuable contributions should be onboarded in a timely manner,
+and added as a committer, and be given write access to the repository.
+
+Committers are expected to follow this policy and continue to send pull requests, go through
+proper review, and have other committers merge their pull requests.
+
+### TC Process
+
+The TC uses a "consensus seeking" process for issues that are escalated to the TC.
+The group tries to find a resolution that has no open objections among TC members.
+If a consensus cannot be reached that has no objections then a majority wins vote
+is called. It is also expected that the majority of decisions made by the TC are via
+a consensus seeking process and that voting is only used as a last-resort.
+
+Resolution may involve returning the issue to project captains with suggestions on
+how to move forward towards a consensus. It is not expected that a meeting of the TC
+will resolve all issues on its agenda during that meeting and may prefer to continue
+the discussion happening among the project captains.
+
+Members can be added to the TC at any time. Any TC member can nominate another committer
+to the TC and the TC uses its standard consensus seeking process to evaluate whether or
+not to add this new member. The TC will consist of a minimum of 3 active members and a
+maximum of 10. If the TC should drop below 5 members the active TC members should nominate
+someone new. If a TC member is stepping down, they are encouraged (but not required) to
+nominate someone to take their place.
+
+TC members will be added as admin's on the Github orgs, npm orgs, and other resources as
+necessary to be effective in the role.
+
+To remain "active" a TC member should have participation within the last 12 months and miss
+no more than six consecutive TC meetings. Our goal is to increase participation, not punish
+people for any lack of participation, this guideline should be only be used as such
+(replace an inactive member with a new active one, for example). Members who do not meet this
+are expected to step down. If A TC member does not step down, an issue can be opened in the
+discussions repo to move them to inactive status. TC members who step down or are removed due
+to inactivity will be moved into inactive status.
+
+Inactive status members can become active members by self nomination if the TC is not already
+larger than the maximum of 10. They will also be given preference if, while at max size, an
+active member steps down.
+
+### Project Captains
+
+The Express TC can designate captains for individual projects/repos in the
+organizations. These captains are responsible for being the primary
+day-to-day maintainers of the repo on a technical and community front.
+Repo captains are empowered with repo ownership and package publication rights.
+When there are conflicts, especially on topics that effect the Express project
+at large, captains are responsible to raise it up to the TC and drive
+those conflicts to resolution. Captains are also responsible for making sure
+community members follow the community guidelines, maintaining the repo
+and the published package, as well as in providing user support.
+
+Like TC members, Repo captains are a subset of committers.
+
+To become a captain for a project the candidate is expected to participate in that
+project for at least 6 months as a committer prior to the request. They should have
+helped with code contributions as well as triaging issues. They are also required to
+have 2FA enabled on both their GitHub and npm accounts.
+
+Any TC member or an existing captain on the **same** repo can nominate another committer
+to the captain role. To do so, they should submit a PR to this document, updating the
+**Active Project Captains** section (while maintaining the sort order) with the project
+name, the nominee's GitHub handle, and their npm username (if different).
+
+- Repos can have as many captains as make sense for the scope of work.
+- A TC member or an existing repo captain **on the same project** can nominate a new captain.
+ Repo captains from other projects should not nominate captains for a different project.
+
+The PR will require at least 2 approvals from TC members and 2 weeks hold time to allow
+for comment and/or dissent. When the PR is merged, a TC member will add them to the
+proper GitHub/npm groups.
+
+#### Active Projects and Captains
+
+The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members)
+
+#### Current Initiative Captains
+
+The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains)
+
+### Inactivity and Emeritus Policy for Any Role
+
+To support the health and continuity of the project, all individuals holding a role within the community (such as Triager, Committer, WG member, Project Captain, or TC member) are encouraged to maintain active participation.
+
+Inactivity is defined as the absence of meaningful involvement in the project—such as contributions, code reviews, triage, meeting attendance, or discussion participation—for a continuous period of 6 months.
+
+#### Exceptions
+
+Anyone may request a temporary leave from active participation due to personal or professional reasons. In such cases, the individual should inform the relevant team or the Technical Committee (TC). During this time, the inactivity policy is paused, and the individual will not be flagged as inactive.
+
+#### Inactivity Process
+
+- If someone is deemed inactive, the individual may be transitioned to an emeritus role that reflects their past contributions. A best effort will be made to inform them that this has occurred. They may request to be reinstated when they are ready to be active again.
+- The emeritus status helps preserve a clear record of contributors who have meaningfully shaped the project over time.
+
+#### Accountability
+
+- The Technical Committee (TC) and the respective captains of each package/team are responsible for assessing activity levels and enacting this policy fairly and transparently, in coordination with other relevant teams.
+- In case of disagreement, the situation can be discussed and resolved by consensus within the TC or appropriate team.
+
+### Developer's Certificate of Origin 1.1
+
+```text
+By making a contribution to this project, I certify that:
+
+ (a) The contribution was created in whole or in part by me and I
+ have the right to submit it under the open source license
+ indicated in the file; or
+
+ (b) The contribution is based upon previous work that, to the best
+ of my knowledge, is covered under an appropriate open source
+ license and I have the right under that license to submit that
+ work with modifications, whether created in whole or in part
+ by me, under the same open source license (unless I am
+ permitted to submit under a different license), as indicated
+ in the file; or
+
+ (c) The contribution was provided directly to me by some other
+ person who certified (a), (b) or (c) and I have not modified
+ it.
+
+ (d) I understand and agree that this project and the contribution
+ are public and that a record of the contribution (including all
+ personal information I submit with it, including my sign-off) is
+ maintained indefinitely and may be redistributed consistent with
+ this project or the open source license(s) involved.
+```
+
+## Collaborator's guide
+
+
+
+### Website Issues
+
+Open issues for the expressjs.com website in https://github.com/expressjs/expressjs.com.
+
+For issues in other Express managed repos (everything in `expressjs`, `pillarjs` or `jshttp` other than `expressjs/express`), be sure to check their contributing guide and open issues and PRs in the appropriate repository.
+
+### PRs and Code contributions
+
+- Tests must pass.
+- Follow the [JavaScript Standard Style](https://standardjs.com/) and `npm run lint`.
+- If you fix a bug, add a test.
+
+### Branches
+
+Use the `master` branch for bug fixes or minor work that is intended for the
+current release stream.
+
+Use the correspondingly named branch, e.g. `6.x`, for anything intended for
+a future release of Express.
+
+### Steps for contributing
+
+1. Create an issue for the
+ bug you want to fix or the feature that you want to add.
+2. Create your own fork on GitHub, then
+ checkout your fork.
+3. Write your code in your local copy. It's good practice to create a branch for
+ each new issue you work on, although not compulsory.
+4. To run the test suite, first install the dependencies by running `npm install`,
+ then run `npm test`.
+5. Ensure your code is linted by running `npm run lint` -- fix any issue you
+ see listed.
+6. If the tests pass, you can commit your changes to your fork and then create
+ a pull request from there. Make sure to reference your issue from the pull
+ request comments by including the issue number e.g. `#123`.
+
+### Issues which are questions
+
+We will typically close any vague issues or questions that are specific to some
+app you are writing. Please double check the docs and other references before
+being trigger happy with posting a question issue.
+
+Things that will help get your question issue looked at:
+
+- Full and runnable JS code.
+- Clear description of the problem or unexpected behavior.
+- Clear description of the expected result.
+- Steps you have taken to debug it yourself.
+
+If you post a question and do not outline the above items or make it easy for
+us to understand and reproduce your issue, it will be closed.
+
+If your question meets all of the above requirements but you do not believe it needs to be looked at
+by the maintainers
+(for example, if you are just looking for community input) please open it as a discussion topic instead
+of an issue. If you
+are unsure and open an issue, we may move it to discussions if we triage them and decide they do
+not need high
+visibility or maintainer input.
+
+## Security Policies and Procedures
+
+
+
+This document outlines security procedures and general policies for the Express
+project.
+
+- [Reporting a Bug](#reporting-a-bug)
+- [Disclosure Policy](#disclosure-policy)
+- [Comments on this Policy](#comments-on-this-policy)
+
+### Reporting a Bug
+
+The Express team and community take all security bugs in Express seriously.
+Thank you for improving the security of Express. We appreciate your efforts and
+responsible disclosure and will make every effort to acknowledge your
+contributions.
+
+Report security bugs by emailing `express-security@lists.openjsf.org`.
+
+To ensure the timely response to your report, please ensure that the entirety
+of the report is contained within the email body and not solely behind a web
+link or an attachment.
+
+The lead maintainer will acknowledge your email within 48 hours, and will send a
+more detailed response within 48 hours indicating the next steps in handling
+your report. After the initial reply to your report, the security team will
+endeavor to keep you informed of the progress towards a fix and full
+announcement, and may ask for additional information or guidance.
+
+Report security bugs in third-party modules to the person or team maintaining
+the module.
+
+### Pre-release Versions
+
+Alpha and Beta releases are unstable and **not suitable for production use**.
+Vulnerabilities found in pre-releases should be reported according to the [Reporting a Bug](#reporting-a-bug) section.
+Due to the unstable nature of the branch it is not guaranteed that any fixes will be released in the next pre-release.
+
+### Disclosure Policy
+
+When the security team receives a security bug report, they will assign it to a
+primary handler. This person will coordinate the fix and release process,
+involving the following steps:
+
+- Confirm the problem and determine the affected versions.
+- Audit code to find any potential similar problems.
+- Prepare fixes for all releases still under maintenance. These fixes will be
+ released as fast as possible to npm.
+
+### The Express Threat Model
+
+We are currently working on a new version of the security model, the most updated version can be found [here](https://github.com/expressjs/security-wg/blob/main/docs/ThreatModel.md)
+
+### Comments on this Policy
+
+If you have suggestions on how this process could be improved please submit a
+pull request.
+
+---
+
+# Contributing to Expressjs.com {#expressjs-website-contributing}
+
+
+
+### The Official Documentation of the Express.js Framework
+
+This is the contribution documentation for the [expressjs.com](https://github.com/expressjs/expressjs.com) website.
+
+#### Need some ideas? These are some typical issues.
+
+1. **Website issues**: If you see anything on the site that could use a tune-up, think about how to fix it.
+ - Display or screen sizing problems
+ - Mobile responsiveness issues
+ - Missing or broken accessibility features
+ - Website outages
+ - Broken links
+ - Page structure or user interface enhancements
+
+2. **Content Issues**: Fix anything related to site content or typos.
+ - Spelling errors
+ - Incorrect/outdated Express.js documentation
+ - Missing content
+
+3. **Translation Issues**: Fix any translation errors or contribute new content.
+ - Fix spelling errors
+ - Fix incorrect/poorly translated words
+ - Check out the [Contributing translations](#contributing-translations) section below for a contributing guide.
+
+#### Want to work on a backlog issue?
+
+We often have bugs or enhancements that need work. You can find these under our repo's [Issues tab](https://github.com/expressjs/expressjs.com/issues). Check out the tags to find something that's a good match for you.
+
+#### Have an idea? Found a bug?
+
+If you've found a bug or a typo, or if you have an idea for an enhancement, you can:
+
+- Submit a [new issue](https://github.com/expressjs/expressjs.com/issues/new/choose) on our repo. Do this for larger proposals, or if you'd like to discuss or get feedback first.
+
+- Make a [GitHub pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). If you have already done work, and it's ready to go, feel free to send it our way.
+
+## Getting Started
+
+The steps below will guide you through the Expressjs.com contribution process.
+
+#### Step 1: (OPTIONAL) Open a New Issue
+
+So you've found a problem that you want to fix, or have a site enhancement you want to make.
+
+1. If you want to get feedback or discuss, open a discussion [issue](https://github.com/expressjs/expressjs.com/issues/new/choose) prior to starting work. This is not required, but encouraged for larger proposals.
+ - While we highly encourage this step, it is only for submissions proposing significant change. It helps us to clarify and focus the work, and ensure it aligns with overall project priorities.
+ - For submissions proposing minor improvements or corrections, this is not needed. You can skip this step.
+ - When opening an issue please give it a title and fill in the description section. The more details you provide, the more feedback we can give.
+
+2. After receiving your issue the Express.js documentation team will respond with feedback. We read every submission and always try to respond quickly with feedback.
+ - For submissions proposing significant change, we encourage you to follow the review process before starting work.
+
+#### Step 2: Get the Application Code Base
+
+Clone the repo and get the code:
+
+```sh
+git clone https://github.com/expressjs/expressjs.com.git
+```
+
+After you've got the code you're ready to start making your changes!
+
+But just in case you need a little extra explanation, this section below outlines the main sections of the code base, where most changes are likely to be made.
+
+**Markdown Page Files**:
+
+- These files render to html and make up the individual pages of the site. Most of the site's documentation text content is written in `md` files.
+- Change these to make changes to individual pages' content/text or markup.
+- Each language has its own complete set of pages, located under their respective language directories - all the Spanish markdown content is found in the `es` directory, for example.
+
+**Includes Partials and Layout Templates**
+
+- `_includes` are partials that are imported and reused across multiple pages.
+ - These are used to import text content for reuse across pages, such as the API documentation, e.g., `_includes > api > en > 5x`, which is included in every language.
+ - These are used to include the page components that make up site-wide user interface and periphery structure, e.g., Header, Footer, etc.
+- `_layouts` are the templates used to wrap the site's individual pages.
+ - These are used to display the structure of the site's periphery, such as the header and footer, and for injecting and displaying individual markdown pages inside the `content` tag.
+
+**Blog Markdown Files**
+
+- These files make up the individual blog posts. If you want to contribute a blog post please
+ follow the specific instructions for [How to write a blog post.](https://expressjs.com/en/blog/write-post)
+- Located under the `_posts` directory.
+
+**CSS or Javascript**
+
+- All css and js files are kept in `css` and `js` folders on the project root.
+
+The Express.js website is built using [Jekyll](https://jekyllrb.com/) and is hosted on [GitHub Pages](https://pages.github.com/).
+
+#### Step 3: Running the Application
+
+Now you'll need a way to see your changes, which means you'll need a running version of the application. You have two options.
+
+1. **Run Locally**: This gets the local version of the application up and running on your machine. Follow our [Local Setup Guide](https://github.com/expressjs/expressjs.com?tab=readme-ov-file#build-the-website-locally) to use this option.
+ - This is the recommended option for moderate to complex work.
+
+2. **Run using Deploy Preview**: Use this option if you don't want to bother with a local installation. Part of our continuous integration pipeline includes [Netlify Deploy Preview](https://docs.netlify.com/deploy/deploy-types/deploy-previews/).
+ 1. To use this you'll need to get your changes online - after you've made your first commit on your feature branch, make a _draft_ pull request.
+ 2. After the build steps are complete, you'll have access to a **Deploy Preview** tab that will run your changes on the web, rebuilding after each commit is pushed.
+ 3. After you are completely done your work, and it's ready for review, remove the draft status on your pull request and submit your work.
+
+## Contributing translations
+
+We use Crowdin to manage our translations in multiple languages and achieve automatic translation with artificial intelligence. Since these translations can be inefficient in some cases, we need help from the community to provide accurate and helpful translations.
+
+The documentation is translated into these languages:
+
+- Chinese Simplified (`zh-cn`)
+- Chinese Traditional (`zh-tw`)
+- English (`en`)
+- French (`fr`)
+- German (`de`)
+- Italian (`it`)
+- Japanese (`ja`)
+- Korean (`ko`)
+- Brazilian Portuguese (`pt-br`)
+- Spanish (`es`)
+
+### How to translate
+
+1. Request to join the Express.js Website project on [Crowdin](https://express.crowdin.com/website)
+2. [Select the language you want to translate](https://support.crowdin.com/for-translators/#starting-translation)
+3. [Start translating](https://support.crowdin.com/online-editor/)
diff --git a/astro/src/content/resources/zh-tw/glossary.md b/astro/src/content/resources/zh-tw/glossary.md
new file mode 100755
index 0000000000..8b45bf01eb
--- /dev/null
+++ b/astro/src/content/resources/zh-tw/glossary.md
@@ -0,0 +1,62 @@
+---
+title: Express glossary
+description: A comprehensive glossary of terms related to Express.js, Node.js, middleware, routing, and other key concepts to help you understand and use Express effectively.
+---
+
+# Glossary
+
+### application
+
+In general, one or more programs that are designed to carry out operations for a specific purpose. In the context of Express, a program that uses the Express API running on the Node.js platform. Might also refer to an [app object](/en/api#express).
+
+### API
+
+Application programming interface. Spell out the abbreviation when it is first used.
+
+### Express
+
+A fast, un-opinionated, minimalist web framework for Node.js applications. In general, "Express" is preferred to "Express.js," though the latter is acceptable.
+
+### libuv
+
+A multi-platform support library which focuses on asynchronous I/O, primarily developed for use by Node.js.
+
+### middleware
+
+A function that is invoked by the Express routing layer before the final request handler, and thus sits in the middle between a raw request and the final intended route. A few fine points of terminology around middleware:
+
+- `var foo = require('middleware')` is called _requiring_ or _using_ a Node.js module. Then the statement `var mw = foo()` typically returns the middleware.
+- `app.use(mw)` is called _adding the middleware to the global processing stack_.
+- `app.get('/foo', mw, function (req, res) { ... })` is called _adding the middleware to the "GET /foo" processing stack_.
+
+### Node.js
+
+A software platform that is used to build scalable network applications. Node.js uses JavaScript as its scripting language, and achieves high throughput via non-blocking I/O and a single-threaded event loop. See [nodejs.org](https://nodejs.org/en/). **Usage note**: Initially, "Node.js," thereafter "Node".
+
+### open-source, open source
+
+When used as an adjective, hyphenate; for example: "This is open-source software." See [Open-source software on Wikipedia](http://en.wikipedia.org/wiki/Open-source_software).
+
+{% capture english-rules %}
+
+Although it is common not to hyphenate this term, we are using the standard English rules for hyphenating a compound adjective.
+
+{% endcapture %}
+
+{% include admonitions/note.html content=english-rules %}
+
+### request
+
+An HTTP request. A client submits an HTTP request message to a server, which returns a response. The request must use one of several [request methods](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods) such as GET, POST, and so on.
+
+### response
+
+An HTTP response. A server returns an HTTP response message to the client. The response contains completion status information about the request and might also contain requested content in its message body.
+
+### route
+
+Part of a URL that identifies a resource. For example, in `http://foo.com/products/id`, "/products/id" is the route.
+
+### router
+
+See [router](/en/api#router) in the API reference.
diff --git a/astro/src/content/resources/zh-tw/middleware/body-parser.md b/astro/src/content/resources/zh-tw/middleware/body-parser.md
new file mode 100644
index 0000000000..e82649a95c
--- /dev/null
+++ b/astro/src/content/resources/zh-tw/middleware/body-parser.md
@@ -0,0 +1,498 @@
+---
+title: Express body-parser middleware
+module: body-parser
+---
+
+# body-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+
+Node.js body parsing middleware.
+
+Parse incoming request bodies in a middleware before your handlers, available
+under the `req.body` property.
+
+**Note** As `req.body`'s shape is based on user-controlled input, all
+properties and values in this object are untrusted and should be validated
+before trusting. For example, `req.body.foo.toString()` may fail in multiple
+ways, for example the `foo` property may not be there or may not be a string,
+and `toString` may not be a function and instead a string or other user input.
+
+[Learn about the anatomy of an HTTP transaction in Node.js](https://nodejs.org/en/learn/http/anatomy-of-an-http-transaction).
+
+_This does not handle multipart bodies_, due to their complex and typically
+large nature. For multipart bodies, you may be interested in the following
+modules:
+
+- [busboy](https://www.npmjs.com/package/busboy#readme) and
+ [connect-busboy](https://www.npmjs.com/package/connect-busboy#readme)
+- [multiparty](https://www.npmjs.com/package/multiparty#readme) and
+ [connect-multiparty](https://www.npmjs.com/package/connect-multiparty#readme)
+- [formidable](https://www.npmjs.com/package/formidable#readme)
+- [multer](https://www.npmjs.com/package/multer#readme)
+
+This module provides the following parsers:
+
+- [JSON body parser](#bodyparserjsonoptions)
+- [Raw body parser](#bodyparserrawoptions)
+- [Text body parser](#bodyparsertextoptions)
+- [URL-encoded form body parser](#bodyparserurlencodedoptions)
+
+Other body parsers you might be interested in:
+
+- [body](https://www.npmjs.com/package/body#readme)
+- [co-body](https://www.npmjs.com/package/co-body#readme)
+
+## Installation
+
+```sh
+$ npm install body-parser
+```
+
+## API
+
+```js
+const bodyParser = require('body-parser');
+```
+
+The `bodyParser` object exposes various factories to create middlewares. All
+middlewares will populate the `req.body` property with the parsed body when
+the `Content-Type` request header matches the `type` option.
+
+The various errors returned by this module are described in the
+[errors section](#errors).
+
+### bodyParser.json([options])
+
+Returns middleware that only parses `json` and only looks at requests where
+the `Content-Type` header matches the `type` option. This parser accepts any
+Unicode encoding of the body and supports automatic inflation of `gzip`,
+`br` (brotli) and `deflate` encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`).
+
+#### Options
+
+The `json` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### defaultCharset
+
+Specify the default character set for the json content if the charset is not
+specified in the `Content-Type` header of the request. Defaults to `utf-8`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### reviver
+
+The `reviver` option is passed directly to `JSON.parse` as the second
+argument. You can find more information on this argument
+[in the MDN documentation about JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Example.3A_Using_the_reviver_parameter).
+
+##### strict
+
+When set to `true`, will only accept arrays and objects; when `false` will
+accept anything `JSON.parse` accepts. Defaults to `true`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not a
+function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `json`), a mime type (like `application/json`), or
+a mime type with a wildcard (like `*/*` or `*/json`). If a function, the `type`
+option is called as `fn(req)` and the request is parsed if it returns a truthy
+value. Defaults to `application/json`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.raw([options])
+
+Returns middleware that parses all bodies as a `Buffer` and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser supports automatic inflation of `gzip`, `br` (brotli) and `deflate`
+encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This will be a `Buffer` object
+of the body.
+
+#### Options
+
+The `raw` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function.
+If not a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this
+can be an extension name (like `bin`), a mime type (like
+`application/octet-stream`), or a mime type with a wildcard (like `*/*` or
+`application/*`). If a function, the `type` option is called as `fn(req)`
+and the request is parsed if it returns a truthy value. Defaults to
+`application/octet-stream`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.text([options])
+
+Returns middleware that parses all bodies as a string and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser supports automatic inflation of `gzip`, `br` (brotli) and `deflate`
+encodings.
+
+A new `body` string containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This will be a string of the
+body.
+
+#### Options
+
+The `text` function takes an optional `options` object that may contain any of
+the following keys:
+
+##### defaultCharset
+
+Specify the default character set for the text content if the charset is not
+specified in the `Content-Type` header of the request. Defaults to `utf-8`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not
+a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `txt`), a mime type (like `text/plain`), or a mime
+type with a wildcard (like `*/*` or `text/*`). If a function, the `type`
+option is called as `fn(req)` and the request is parsed if it returns a
+truthy value. Defaults to `text/plain`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+### bodyParser.urlencoded([options])
+
+Returns middleware that only parses `urlencoded` bodies and only looks at
+requests where the `Content-Type` header matches the `type` option. This
+parser accepts only UTF-8 encoding of the body and supports automatic
+inflation of `gzip`, `br` (brotli) and `deflate` encodings.
+
+A new `body` object containing the parsed data is populated on the `request`
+object after the middleware (i.e. `req.body`). This object will contain
+key-value pairs, where the value can be a string or array (when `extended` is
+`false`), or any type (when `extended` is `true`).
+
+#### Options
+
+The `urlencoded` function takes an optional `options` object that may contain
+any of the following keys:
+
+##### extended
+
+The "extended" syntax allows for rich objects and arrays to be encoded into the
+URL-encoded format, allowing for a JSON-like experience with URL-encoded. For
+more information, please [see the qs
+library](https://www.npmjs.com/package/qs#readme).
+
+Defaults to `false`.
+
+##### inflate
+
+When set to `true`, then deflated (compressed) bodies will be inflated; when
+`false`, deflated bodies are rejected. Defaults to `true`.
+
+##### limit
+
+Controls the maximum request body size. If this is a number, then the value
+specifies the number of bytes; if it is a string, the value is passed to the
+[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
+to `'100kb'`.
+
+##### parameterLimit
+
+The `parameterLimit` option controls the maximum number of parameters that
+are allowed in the URL-encoded data. If a request contains more parameters
+than this value, a 413 will be returned to the client. Defaults to `1000`.
+
+##### type
+
+The `type` option is used to determine what media type the middleware will
+parse. This option can be a string, array of strings, or a function. If not
+a function, `type` option is passed directly to the
+[type-is](https://www.npmjs.com/package/type-is#readme) library and this can
+be an extension name (like `urlencoded`), a mime type (like
+`application/x-www-form-urlencoded`), or a mime type with a wildcard (like
+`*/x-www-form-urlencoded`). If a function, the `type` option is called as
+`fn(req)` and the request is parsed if it returns a truthy value. Defaults
+to `application/x-www-form-urlencoded`.
+
+##### verify
+
+The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
+where `buf` is a `Buffer` of the raw request body and `encoding` is the
+encoding of the request. The parsing can be aborted by throwing an error.
+
+##### defaultCharset
+
+The default charset to parse as, if not specified in content-type. Must be
+either `utf-8` or `iso-8859-1`. Defaults to `utf-8`.
+
+##### charsetSentinel
+
+Whether to let the value of the `utf8` parameter take precedence as the charset
+selector. It requires the form to contain a parameter named `utf8` with a value
+of `✓`. Defaults to `false`.
+
+##### interpretNumericEntities
+
+Whether to decode numeric entities such as `☺` when parsing an iso-8859-1
+form. Defaults to `false`.
+
+##### depth
+
+The `depth` option is used to configure the maximum depth of the `qs` library when `extended` is `true`. This allows you to limit the amount of keys that are parsed and can be useful to prevent certain types of abuse. Defaults to `32`. It is recommended to keep this value as low as possible.
+
+## Errors
+
+The middlewares provided by this module create errors using the
+[`http-errors` module](https://www.npmjs.com/package/http-errors). The errors
+will typically have a `status`/`statusCode` property that contains the suggested
+HTTP response code, an `expose` property to determine if the `message` property
+should be displayed to the client, a `type` property to determine the type of
+error without matching against the `message`, and a `body` property containing
+the read body, if available.
+
+The following are the common errors created, though any error can come through
+for various reasons.
+
+### content encoding unsupported
+
+This error will occur when the request had a `Content-Encoding` header that
+contained an encoding but the "inflation" option was set to `false`. The
+`status` property is set to `415`, the `type` property is set to
+`'encoding.unsupported'`, and the `charset` property will be set to the
+encoding that is unsupported.
+
+### entity parse failed
+
+This error will occur when the request contained an entity that could not be
+parsed by the middleware. The `status` property is set to `400`, the `type`
+property is set to `'entity.parse.failed'`, and the `body` property is set to
+the entity value that failed parsing.
+
+### entity verify failed
+
+This error will occur when the request contained an entity that could not be
+failed verification by the defined `verify` option. The `status` property is
+set to `403`, the `type` property is set to `'entity.verify.failed'`, and the
+`body` property is set to the entity value that failed verification.
+
+### request aborted
+
+This error will occur when the request is aborted by the client before reading
+the body has finished. The `received` property will be set to the number of
+bytes received before the request was aborted and the `expected` property is
+set to the number of expected bytes. The `status` property is set to `400`
+and `type` property is set to `'request.aborted'`.
+
+### request entity too large
+
+This error will occur when the request body's size is larger than the "limit"
+option. The `limit` property will be set to the byte limit and the `length`
+property will be set to the request body's length. The `status` property is
+set to `413` and the `type` property is set to `'entity.too.large'`.
+
+### request size did not match content length
+
+This error will occur when the request's length did not match the length from
+the `Content-Length` header. This typically occurs when the request is malformed,
+typically when the `Content-Length` header was calculated based on characters
+instead of bytes. The `status` property is set to `400` and the `type` property
+is set to `'request.size.invalid'`.
+
+### stream encoding should not be set
+
+This error will occur when something called the `req.setEncoding` method prior
+to this middleware. This module operates directly on bytes only and you cannot
+call `req.setEncoding` when using this module. The `status` property is set to
+`500` and the `type` property is set to `'stream.encoding.set'`.
+
+### stream is not readable
+
+This error will occur when the request is no longer readable when this middleware
+attempts to read it. This typically means something other than a middleware from
+this module read the request body already and the middleware was also configured to
+read the same request. The `status` property is set to `500` and the `type`
+property is set to `'stream.not.readable'`.
+
+### too many parameters
+
+This error will occur when the content of the request exceeds the configured
+`parameterLimit` for the `urlencoded` parser. The `status` property is set to
+`413` and the `type` property is set to `'parameters.too.many'`.
+
+### unsupported charset "BOGUS"
+
+This error will occur when the request had a charset parameter in the
+`Content-Type` header, but the `iconv-lite` module does not support it OR the
+parser does not support it. The charset is contained in the message as well
+as in the `charset` property. The `status` property is set to `415`, the
+`type` property is set to `'charset.unsupported'`, and the `charset` property
+is set to the charset that is unsupported.
+
+### unsupported content encoding "bogus"
+
+This error will occur when the request had a `Content-Encoding` header that
+contained an unsupported encoding. The encoding is contained in the message
+as well as in the `encoding` property. The `status` property is set to `415`,
+the `type` property is set to `'encoding.unsupported'`, and the `encoding`
+property is set to the encoding that is unsupported.
+
+### The input exceeded the depth
+
+This error occurs when using `bodyParser.urlencoded` with the `extended` property set to `true` and the input exceeds the configured `depth` option. The `status` property is set to `400`. It is recommended to review the `depth` option and evaluate if it requires a higher value. When the `depth` option is set to `32` (default value), the error will not be thrown.
+
+## Examples
+
+### Express/Connect top-level generic
+
+This example demonstrates adding a generic JSON and URL-encoded parser as a
+top-level middleware, which will parse the bodies of all incoming requests.
+This is the simplest setup.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// parse application/x-www-form-urlencoded
+app.use(bodyParser.urlencoded());
+
+// parse application/json
+app.use(bodyParser.json());
+
+app.use(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.write('you posted:\n');
+ res.end(String(JSON.stringify(req.body, null, 2)));
+});
+```
+
+### Express route-specific
+
+This example demonstrates adding body parsers specifically to the routes that
+need them. In general, this is the most recommended way to use body-parser with
+Express.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// create application/json parser
+const jsonParser = bodyParser.json();
+
+// create application/x-www-form-urlencoded parser
+const urlencodedParser = bodyParser.urlencoded();
+
+// POST /login gets urlencoded bodies
+app.post('/login', urlencodedParser, function (req, res) {
+ if (!req.body || !req.body.username) res.sendStatus(400);
+ res.send('welcome, ' + req.body.username);
+});
+
+// POST /api/users gets JSON bodies
+app.post('/api/users', jsonParser, function (req, res) {
+ if (!req.body) res.sendStatus(400);
+ // create user in req.body
+});
+```
+
+### Change accepted type for parsers
+
+All the parsers accept a `type` option which allows you to change the
+`Content-Type` that the middleware will parse.
+
+```js
+const express = require('express');
+const bodyParser = require('body-parser');
+
+const app = express();
+
+// parse various different custom JSON types as JSON
+app.use(bodyParser.json({ type: 'application/*+json' }));
+
+// parse some custom thing into a Buffer
+app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }));
+
+// parse an HTML body into a string
+app.use(bodyParser.text({ type: 'text/html' }));
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/body-parser/ci.yml?branch=master&label=ci
+[ci-url]: https://github.com/expressjs/body-parser/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coverallsCoverage/github/expressjs/body-parser?branch=master
+[coveralls-url]: https://coveralls.io/r/expressjs/body-parser?branch=master
+[npm-downloads-image]: https://img.shields.io/npm/dm/body-parser
+[npm-url]: https://npmjs.com/package/body-parser
+[npm-version-image]: https://img.shields.io/npm/v/body-parser
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/body-parser/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/body-parser
diff --git a/astro/src/content/resources/zh-tw/middleware/compression.md b/astro/src/content/resources/zh-tw/middleware/compression.md
new file mode 100644
index 0000000000..6ac63fcb7a
--- /dev/null
+++ b/astro/src/content/resources/zh-tw/middleware/compression.md
@@ -0,0 +1,314 @@
+---
+title: Express compression middleware
+module: compression
+---
+
+# compression
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+[![Funding][funding-image]][funding-url]
+
+Node.js compression middleware.
+
+The following compression codings are supported:
+
+- deflate
+- gzip
+- br (brotli)
+
+**Note** Brotli is supported only since Node.js versions v11.7.0 and v10.16.0.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```bash
+$ npm install compression
+```
+
+## API
+
+```js
+var compression = require('compression');
+```
+
+### compression([options])
+
+Returns the compression middleware using the given `options`. The middleware
+will attempt to compress response bodies for all requests that traverse through
+the middleware, based on the given `options`.
+
+This middleware will never compress responses that include a `Cache-Control`
+header with the [`no-transform` directive](https://tools.ietf.org/html/rfc7234#section-5.2.2.4),
+as compressing will transform the body.
+
+#### Options
+
+`compression()` accepts these properties in the options object. In addition to
+those listed below, [zlib](https://nodejs.org/api/zlib.html) options may be
+passed in to the options object or
+[brotli](https://nodejs.org/api/zlib.html#zlib_class_brotlioptions) options.
+
+##### chunkSize
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_CHUNK`, or `16384`.
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### filter
+
+Type: `Function`
+
+A function to decide if the response should be considered for compression.
+This function is called as `filter(req, res)` and is expected to return
+`true` to consider the response for compression, or `false` to not compress
+the response.
+
+The default filter function uses the [compressible](https://www.npmjs.com/package/compressible)
+module to determine if `res.getHeader('Content-Type')` is compressible.
+
+##### level
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_COMPRESSION`, or `-1`
+
+The level of zlib compression to apply to responses. A higher level will result
+in better compression, but will take longer to complete. A lower level will
+result in less compression, but will be much faster.
+
+This is an integer in the range of `0` (no compression) to `9` (maximum
+compression). The special value `-1` can be used to mean the "default
+compression level", which is a default compromise between speed and
+compression (currently equivalent to level 6).
+
+- `-1` Default compression level (also `zlib.constants.Z_DEFAULT_COMPRESSION`).
+- `0` No compression (also `zlib.constants.Z_NO_COMPRESSION`).
+- `1` Fastest compression (also `zlib.constants.Z_BEST_SPEED`).
+- `2`
+- `3`
+- `4`
+- `5`
+- `6` (currently what `zlib.constants.Z_DEFAULT_COMPRESSION` points to).
+- `7`
+- `8`
+- `9` Best compression (also `zlib.constants.Z_BEST_COMPRESSION`).
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### memLevel
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_MEMLEVEL`, or `8`
+
+This specifies how much memory should be allocated for the internal compression
+state and is an integer in the range of `1` (minimum level) and `9` (maximum
+level).
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### brotli
+
+Type: `Object`
+
+This specifies the options for configuring Brotli. See [Node.js documentation](https://nodejs.org/api/zlib.html#class-brotlioptions) for a complete list of available options.
+
+##### strategy
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_STRATEGY`
+
+This is used to tune the compression algorithm. This value only affects the
+compression ratio, not the correctness of the compressed output, even if it
+is not set appropriately.
+
+- `zlib.constants.Z_DEFAULT_STRATEGY` Use for normal data.
+- `zlib.constants.Z_FILTERED` Use for data produced by a filter (or predictor).
+ Filtered data consists mostly of small values with a somewhat random
+ distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect is to force more Huffman coding and less
+ string matching; it is somewhat intermediate between `zlib.constants.Z_DEFAULT_STRATEGY`
+ and `zlib.constants.Z_HUFFMAN_ONLY`.
+- `zlib.constants.Z_FIXED` Use to prevent the use of dynamic Huffman codes, allowing
+ for a simpler decoder for special applications.
+- `zlib.constants.Z_HUFFMAN_ONLY` Use to force Huffman encoding only (no string match).
+- `zlib.constants.Z_RLE` Use to limit match distances to one (run-length encoding).
+ This is designed to be almost as fast as `zlib.constants.Z_HUFFMAN_ONLY`, but give
+ better compression for PNG image data.
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### threshold
+
+Type: `Number` or `String`
+Default: `1kb`
+
+The byte threshold for the response body size before compression is considered
+for the response. This is a number of bytes or any string
+accepted by the [bytes](https://www.npmjs.com/package/bytes) module.
+
+**Note** this is only an advisory setting; if the response size cannot be determined
+at the time the response headers are written, then it is assumed the response is
+_over_ the threshold. To guarantee the response size can be determined, be sure
+set a `Content-Length` response header.
+
+##### windowBits
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_WINDOWBITS`, or `15`
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### enforceEncoding
+
+Type: `String`
+Default: `identity`
+
+This is the default encoding to use when the client does not specify an encoding in the request's [Accept-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) header.
+
+#### .filter
+
+The default `filter` function. This is used to construct a custom filter
+function that is an extension of the default function.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+app.use(compression({ filter: shouldCompress }));
+
+function shouldCompress(req, res) {
+ if (req.headers['x-no-compression']) {
+ // don't compress responses with this request header
+ return false;
+ }
+
+ // fallback to standard filter function
+ return compression.filter(req, res);
+}
+```
+
+### res.flush
+
+This module adds a `res.flush()` method to force the partially-compressed
+response to be flushed to the client.
+
+## Examples
+
+### express
+
+When using this module with express, simply `app.use` the module as
+high as you like. Requests that pass through the middleware will be compressed.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress all responses
+app.use(compression());
+
+// add all routes
+```
+
+### Node.js HTTP server
+
+```js
+var compression = require('compression')({ threshold: 0 });
+var http = require('http');
+
+function createServer(fn) {
+ return http.createServer(function (req, res) {
+ compression(req, res, function (err) {
+ if (err) {
+ res.statusCode = err.status || 500;
+ res.end(err.message);
+ return;
+ }
+
+ fn(req, res);
+ });
+ });
+}
+
+var server = createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello world!');
+});
+
+server.listen(3000, () => {
+ console.log('> Listening at http://localhost:3000');
+});
+```
+
+### Server-Sent Events
+
+Because of the nature of compression this module does not work out of the box
+with server-sent events. To compress content, a window of the output needs to
+be buffered up in order to get good compression. Typically when using server-sent
+events, there are certain block of data that need to reach the client.
+
+You can achieve this by calling `res.flush()` when you need the data written to
+actually make it to the client.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress responses
+app.use(compression());
+
+// server-sent event stream
+app.get('/events', function (req, res) {
+ res.setHeader('Content-Type', 'text/event-stream');
+ res.setHeader('Cache-Control', 'no-cache');
+
+ // send a ping approx every 2 seconds
+ var timer = setInterval(function () {
+ res.write('data: ping\n\n');
+
+ // !!! this is the important part
+ res.flush();
+ }, 2000);
+
+ res.on('close', function () {
+ clearInterval(timer);
+ });
+});
+```
+
+## Contributing
+
+The Express.js project welcomes all constructive contributions. Contributions take many forms,
+from code for bug fixes and enhancements, to additions and fixes to documentation, additional
+tests, triaging incoming pull requests and issues, and more!
+
+See the [Contributing Guide](https://github.com/expressjs/express/blob/master/Contributing.md) for more technical details on contributing.
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://badgen.net/npm/v/compression
+[npm-url]: https://npmjs.org/package/compression
+[downloads-image]: https://badgen.net/npm/dm/compression
+[downloads-url]: https://npmcharts.com/compare/compression?minimal=true
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/compression/master?label=CI
+[github-actions-ci-url]: https://github.com/expressjs/compression/actions?query=workflow%3Aci
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/compression/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/compression
+[funding-url]: https://opencollective.com/express
+[funding-image]: https://badgen.net/badge/icon/sponsor/pink?icon=github&label=Open%20Collective
diff --git a/astro/src/content/resources/zh-tw/middleware/cookie-parser.md b/astro/src/content/resources/zh-tw/middleware/cookie-parser.md
new file mode 100644
index 0000000000..2a59496387
--- /dev/null
+++ b/astro/src/content/resources/zh-tw/middleware/cookie-parser.md
@@ -0,0 +1,124 @@
+---
+title: Express cookie-parser middleware
+module: cookie-parser
+---
+
+# cookie-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Parse `Cookie` header and populate `req.cookies` with an object keyed by the
+cookie names. Optionally you may enable signed cookie support by passing a
+`secret` string, which assigns `req.secret` so it may be used by other
+middleware.
+
+## Installation
+
+```sh
+$ npm install cookie-parser
+```
+
+## API
+
+```js
+var cookieParser = require('cookie-parser');
+```
+
+### cookieParser(secret, options)
+
+Create a new cookie parser middleware function using the given `secret` and
+`options`.
+
+- `secret` a string or array used for signing cookies. This is optional and if
+ not specified, will not parse signed cookies. If a string is provided, this
+ is used as the secret. If an array is provided, an attempt will be made to
+ unsign the cookie with each secret in order.
+- `options` an object that is passed to `cookie.parse` as the second option. See
+ [cookie](https://www.npmjs.org/package/cookie) for more information.
+ - `decode` a function to decode the value of the cookie
+
+The middleware will parse the `Cookie` header on the request and expose the
+cookie data as the property `req.cookies` and, if a `secret` was provided, as
+the property `req.signedCookies`. These properties are name value pairs of the
+cookie name to cookie value.
+
+When `secret` is provided, this module will unsign and validate any signed cookie
+values and move those name value pairs from `req.cookies` into `req.signedCookies`.
+A signed cookie is a cookie that has a value prefixed with `s:`. Signed cookies
+that fail signature validation will have the value `false` instead of the tampered
+value.
+
+In addition, this module supports special "JSON cookies". These are cookie where
+the value is prefixed with `j:`. When these values are encountered, the value will
+be exposed as the result of `JSON.parse`. If parsing fails, the original value will
+remain.
+
+### cookieParser.JSONCookie(str)
+
+Parse a cookie value as a JSON cookie. This will return the parsed JSON value
+if it was a JSON cookie, otherwise, it will return the passed value.
+
+### cookieParser.JSONCookies(cookies)
+
+Given an object, this will iterate over the keys and call `JSONCookie` on each
+value, replacing the original value with the parsed value. This returns the
+same object that was passed in.
+
+### cookieParser.signedCookie(str, secret)
+
+Parse a cookie value as a signed cookie. This will return the parsed unsigned
+value if it was a signed cookie and the signature was valid. If the value was
+not signed, the original value is returned. If the value was signed but the
+signature could not be validated, `false` is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+### cookieParser.signedCookies(cookies, secret)
+
+Given an object, this will iterate over the keys and check if any value is a
+signed cookie. If it is a signed cookie and the signature is valid, the key
+will be deleted from the object and added to the new object that is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+## Example
+
+```js
+var express = require('express');
+var cookieParser = require('cookie-parser');
+
+var app = express();
+app.use(cookieParser());
+
+app.get('/', function (req, res) {
+ // Cookies that have not been signed
+ console.log('Cookies: ', req.cookies);
+
+ // Cookies that have been signed
+ console.log('Signed Cookies: ', req.signedCookies);
+});
+
+app.listen(8080);
+
+// curl command that sends an HTTP request with two cookies
+// curl http://127.0.0.1:8080 --cookie "Cho=Kim;Greet=Hello"
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/cookie-parser/master?label=ci
+[ci-url]: https://github.com/expressjs/cookie-parser/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/cookie-parser/master
+[coveralls-url]: https://coveralls.io/r/expressjs/cookie-parser?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/cookie-parser
+[npm-url]: https://npmjs.org/package/cookie-parser
+[npm-version-image]: https://badgen.net/npm/v/cookie-parser
diff --git a/astro/src/content/resources/zh-tw/middleware/cookie-session.md b/astro/src/content/resources/zh-tw/middleware/cookie-session.md
new file mode 100644
index 0000000000..2d6d1f885b
--- /dev/null
+++ b/astro/src/content/resources/zh-tw/middleware/cookie-session.md
@@ -0,0 +1,124 @@
+---
+title: Express cookie-session middleware
+module: cookie-session
+---
+
+# cookie-parser
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Parse `Cookie` header and populate `req.cookies` with an object keyed by the
+cookie names. Optionally you may enable signed cookie support by passing a
+`secret` string, which assigns `req.secret` so it may be used by other
+middleware.
+
+## Installation
+
+```sh
+$ npm install cookie-parser
+```
+
+## API
+
+```js
+var cookieParser = require('cookie-parser');
+```
+
+### cookieParser(secret, options)
+
+Create a new cookie parser middleware function using the given `secret` and
+`options`.
+
+- `secret` a string or array used for signing cookies. This is optional and if
+ not specified, will not parse signed cookies. If a string is provided, this
+ is used as the secret. If an array is provided, an attempt will be made to
+ unsign the cookie with each secret in order.
+- `options` an object that is passed to `cookie.parse` as the second option. See
+ [cookie](https://www.npmjs.org/package/cookie) for more information.
+ - `decode` a function to decode the value of the cookie
+
+The middleware will parse the `Cookie` header on the request and expose the
+cookie data as the property `req.cookies` and, if a `secret` was provided, as
+the property `req.signedCookies`. These properties are name value pairs of the
+cookie name to cookie value.
+
+When `secret` is provided, this module will unsign and validate any signed cookie
+values and move those name value pairs from `req.cookies` into `req.signedCookies`.
+A signed cookie is a cookie that has a value prefixed with `s:`. Signed cookies
+that fail signature validation will have the value `false` instead of the tampered
+value.
+
+In addition, this module supports special "JSON cookies". These are cookie where
+the value is prefixed with `j:`. When these values are encountered, the value will
+be exposed as the result of `JSON.parse`. If parsing fails, the original value will
+remain.
+
+### cookieParser.JSONCookie(str)
+
+Parse a cookie value as a JSON cookie. This will return the parsed JSON value
+if it was a JSON cookie, otherwise, it will return the passed value.
+
+### cookieParser.JSONCookies(cookies)
+
+Given an object, this will iterate over the keys and call `JSONCookie` on each
+value, replacing the original value with the parsed value. This returns the
+same object that was passed in.
+
+### cookieParser.signedCookie(str, secret)
+
+Parse a cookie value as a signed cookie. This will return the parsed unsigned
+value if it was a signed cookie and the signature was valid. If the value was
+not signed, the original value is returned. If the value was signed but the
+signature could not be validated, `false` is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+### cookieParser.signedCookies(cookies, secret)
+
+Given an object, this will iterate over the keys and check if any value is a
+signed cookie. If it is a signed cookie and the signature is valid, the key
+will be deleted from the object and added to the new object that is returned.
+
+The `secret` argument can be an array or string. If a string is provided, this
+is used as the secret. If an array is provided, an attempt will be made to
+unsign the cookie with each secret in order.
+
+## Example
+
+```js
+var express = require('express');
+var cookieParser = require('cookie-parser');
+
+var app = express();
+app.use(cookieParser());
+
+app.get('/', function (req, res) {
+ // Cookies that have not been signed
+ console.log('Cookies: ', req.cookies);
+
+ // Cookies that have been signed
+ console.log('Signed Cookies: ', req.signedCookies);
+});
+
+app.listen(8080);
+
+// curl command that sends an HTTP request with two cookies
+// curl http://127.0.0.1:8080 --cookie "Cho=Kim;Greet=Hello"
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/cookie-parser/master?label=ci
+[ci-url]: https://github.com/expressjs/cookie-parser/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/cookie-parser/master
+[coveralls-url]: https://coveralls.io/r/expressjs/cookie-parser?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/cookie-parser
+[npm-url]: https://npmjs.org/package/cookie-parser
+[npm-version-image]: https://badgen.net/npm/v/cookie-parser
diff --git a/astro/src/content/resources/zh-tw/middleware/cors.md b/astro/src/content/resources/zh-tw/middleware/cors.md
new file mode 100644
index 0000000000..55d70922cb
--- /dev/null
+++ b/astro/src/content/resources/zh-tw/middleware/cors.md
@@ -0,0 +1,261 @@
+---
+title: Express cors middleware
+module: cors
+---
+
+# cors
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+CORS is a [Node.js](https://nodejs.org/en/) package for providing a [Connect](https://github.com/senchalabs/connect)/[Express](https://expressjs.com/) middleware that can be used to enable [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS) with various options.
+
+- [Installation](#installation)
+- [Usage](#usage)
+ - [Simple Usage](#simple-usage-enable-all-cors-requests)
+ - [Enable CORS for a Single Route](#enable-cors-for-a-single-route)
+ - [Configuring CORS](#configuring-cors)
+ - [Configuring CORS w/ Dynamic Origin](#configuring-cors-w-dynamic-origin)
+ - [Enabling CORS Pre-Flight](#enabling-cors-pre-flight)
+ - [Customizing CORS Settings Dynamically per Request](#customizing-cors-settings-dynamically-per-request)
+- [Configuration Options](#configuration-options)
+- [License](#license)
+- [Original Author](#original-author)
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/downloading-and-installing-packages-locally):
+
+```sh
+$ npm install cors
+```
+
+## Usage
+
+### Simple Usage (Enable _All_ CORS Requests)
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.use(cors());
+
+app.get('/products/:id', function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for all origins!' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Enable CORS for a Single Route
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.get('/products/:id', cors(), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for a Single Route' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Configuring CORS
+
+See the [configuration options](#configuration-options) for details.
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+var corsOptions = {
+ origin: 'http://example.com',
+ optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
+};
+
+app.get('/products/:id', cors(corsOptions), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for only example.com.' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Configuring CORS w/ Dynamic Origin
+
+This module supports validating the origin dynamically using a function provided
+to the `origin` option. This function will be passed a string that is the origin
+(or `undefined` if the request has no origin), and a `callback` with the signature
+`callback(error, origin)`.
+
+The `origin` argument to the callback can be any value allowed for the `origin`
+option of the middleware, except a function. See the
+[configuration options](#configuration-options) section for more information on all
+the possible value types.
+
+This function is designed to allow the dynamic loading of allowed origin(s) from
+a backing datasource, like a database.
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+var corsOptions = {
+ origin: function (origin, callback) {
+ // db.loadOrigins is an example call to load
+ // a list of origins from a backing database
+ db.loadOrigins(function (error, origins) {
+ callback(error, origins);
+ });
+ },
+};
+
+app.get('/products/:id', cors(corsOptions), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for an allowed domain.' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+### Enabling CORS Pre-Flight
+
+Certain CORS requests are considered 'complex' and require an initial
+`OPTIONS` request (called the "pre-flight request"). An example of a
+'complex' CORS request is one that uses an HTTP verb other than
+GET/HEAD/POST (such as DELETE) or that uses custom headers. To enable
+pre-flighting, you must add a new OPTIONS handler for the route you want
+to support:
+
+```javascript
+var express = require('express');
+var cors = require('cors');
+var app = express();
+
+app.options('/products/:id', cors()); // enable pre-flight request for DELETE request
+app.del('/products/:id', cors(), function (req, res, next) {
+ res.json({ msg: 'This is CORS-enabled for all origins!' });
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+You can also enable pre-flight across-the-board like so:
+
+```javascript
+app.options('*', cors()); // include before other routes
+```
+
+NOTE: When using this middleware as an application level middleware (for
+example, `app.use(cors())`), pre-flight requests are already handled for all
+routes.
+
+### Customizing CORS Settings Dynamically per Request
+
+For APIs that require different CORS configurations for specific routes or requests, you can dynamically generate CORS options based on the incoming request. The `cors` middleware allows you to achieve this by passing a function instead of static options. This function is called for each incoming request and must use the callback pattern to return the appropriate CORS options.
+
+The function accepts:
+
+1. **`req`**:
+ - The incoming request object.
+
+2. **`callback(error, corsOptions)`**:
+ - A function used to return the computed CORS options.
+ - **Arguments**:
+ - **`error`**: Pass `null` if there’s no error, or an error object to indicate a failure.
+ - **`corsOptions`**: An object specifying the CORS policy for the current request.
+
+Here’s an example that handles both public routes and restricted, credential-sensitive routes:
+
+```javascript
+var dynamicCorsOptions = function (req, callback) {
+ var corsOptions;
+ if (req.path.startsWith('/auth/connect/')) {
+ corsOptions = {
+ origin: 'http://mydomain.com', // Allow only a specific origin
+ credentials: true, // Enable cookies and credentials
+ };
+ } else {
+ corsOptions = { origin: '*' }; // Allow all origins for other routes
+ }
+ callback(null, corsOptions);
+};
+
+app.use(cors(dynamicCorsOptions));
+
+app.get('/auth/connect/twitter', function (req, res) {
+ res.send('CORS dynamically applied for Twitter authentication.');
+});
+
+app.get('/public', function (req, res) {
+ res.send('Public data with open CORS.');
+});
+
+app.listen(80, function () {
+ console.log('CORS-enabled web server listening on port 80');
+});
+```
+
+## Configuration Options
+
+- `origin`: Configures the **Access-Control-Allow-Origin** CORS header. Possible values:
+ - `Boolean` - set `origin` to `true` to reflect the [request origin](https://datatracker.ietf.org/doc/html/draft-abarth-origin-09), as defined by `req.header('Origin')`, or set it to `false` to disable CORS.
+ - `String` - set `origin` to a specific origin. For example, if you set it to
+ - `"http://example.com"` only requests from "http://example.com" will be allowed.
+ - `"*"` for all domains to be allowed.
+ - `RegExp` - set `origin` to a regular expression pattern which will be used to test the request origin. If it's a match, the request origin will be reflected. For example the pattern `/example\.com$/` will reflect any request that is coming from an origin ending with "example.com".
+ - `Array` - set `origin` to an array of valid origins. Each origin can be a `String` or a `RegExp`. For example `["http://example1.com", /\.example2\.com$/]` will accept any request from "http://example1.com" or from a subdomain of "example2.com".
+ - `Function` - set `origin` to a function implementing some custom logic. The function takes the request origin as the first parameter and a callback (called as `callback(err, origin)`, where `origin` is a non-function value of the `origin` option) as the second.
+- `methods`: Configures the **Access-Control-Allow-Methods** CORS header. Expects a comma-delimited string (ex: 'GET,PUT,POST') or an array (ex: `['GET', 'PUT', 'POST']`).
+- `allowedHeaders`: Configures the **Access-Control-Allow-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Type,Authorization') or an array (ex: `['Content-Type', 'Authorization']`). If not specified, defaults to reflecting the headers specified in the request's **Access-Control-Request-Headers** header.
+- `exposedHeaders`: Configures the **Access-Control-Expose-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Range,X-Content-Range') or an array (ex: `['Content-Range', 'X-Content-Range']`). If not specified, no custom headers are exposed.
+- `credentials`: Configures the **Access-Control-Allow-Credentials** CORS header. Set to `true` to pass the header, otherwise it is omitted.
+- `maxAge`: Configures the **Access-Control-Max-Age** CORS header. Set to an integer to pass the header, otherwise it is omitted.
+- `preflightContinue`: Pass the CORS preflight response to the next handler.
+- `optionsSuccessStatus`: Provides a status code to use for successful `OPTIONS` requests, since some legacy browsers (IE11, various SmartTVs) choke on `204`.
+
+The default configuration is the equivalent of:
+
+```json
+{
+ "origin": "*",
+ "methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
+ "preflightContinue": false,
+ "optionsSuccessStatus": 204
+}
+```
+
+For details on the effect of each CORS header, read [this](https://web.dev/articles/cross-origin-resource-sharing) article.
+
+## License
+
+[MIT License](http://www.opensource.org/licenses/mit-license.php)
+
+## Original Author
+
+[Troy Goode](https://github.com/TroyGoode) ([troygoode@gmail.com](mailto:troygoode@gmail.com))
+
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/cors/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/cors?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/cors.svg
+[downloads-url]: https://npmjs.com/package/cors
+[github-actions-ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/cors/ci.yml?branch=master&label=ci
+[github-actions-ci-url]: https://github.com/expressjs/cors?query=workflow%3Aci
+[npm-image]: https://img.shields.io/npm/v/cors.svg
+[npm-url]: https://npmjs.com/package/cors
diff --git a/astro/src/content/resources/zh-tw/middleware/errorhandler.md b/astro/src/content/resources/zh-tw/middleware/errorhandler.md
new file mode 100644
index 0000000000..20df618320
--- /dev/null
+++ b/astro/src/content/resources/zh-tw/middleware/errorhandler.md
@@ -0,0 +1,133 @@
+---
+title: Express errorhandler middleware
+module: errorhandler
+---
+
+# errorhandler
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Development-only error handler middleware.
+
+This middleware is only intended to be used in a development environment, as
+the _full error stack traces and internal details of any object passed to this
+module_ will be sent back to the client when an error occurs.
+
+When an object is provided to Express as an error, this module will display
+as much about this object as possible, and will do so by using content negotiation
+for the response between HTML, JSON, and plain text.
+
+- When the object is a standard `Error` object, the string provided by the
+ `stack` property will be returned in HTML/text responses.
+- When the object is a non-`Error` object, the result of
+ [util.inspect](https://nodejs.org/api/util.html#util_util_inspect_object_options)
+ will be returned in HTML/text responses.
+- For JSON responses, the result will be an object with all enumerable properties
+ from the object in the response.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install errorhandler
+```
+
+## API
+
+
+
+```js
+var errorhandler = require('errorhandler');
+```
+
+### errorhandler(options)
+
+Create new middleware to handle errors and respond with content negotiation.
+
+#### Options
+
+Error handler accepts these properties in the options object.
+
+##### log
+
+Provide a function to be called with the error and a string representation of
+the error. Can be used to write the error to any desired location, or set to
+`false` to only send the error back in the response. Called as
+`log(err, str, req, res)` where `err` is the `Error` object, `str` is a string
+representation of the error, `req` is the request object and `res` is the
+response object (note, this function is invoked _after_ the response has been
+written).
+
+The default value for this option is `true` unless `process.env.NODE_ENV === 'test'`.
+
+Possible values:
+
+- `true`: Log errors using `console.error(str)`.
+- `false`: Only send the error back in the response.
+- A function: pass the error to a function for handling.
+
+## Examples
+
+### Simple example
+
+Basic example of adding this middleware as the error handler only in development
+with `connect` (`express` also can be used in this example).
+
+```js
+var connect = require('connect');
+var errorhandler = require('errorhandler');
+
+var app = connect();
+
+// assumes NODE_ENV is set by the user
+if (process.env.NODE_ENV === 'development') {
+ // only use in development
+ app.use(errorhandler());
+}
+```
+
+### Custom output location
+
+Sometimes you may want to output the errors to a different location than STDERR
+during development, like a system notification, for example.
+
+
+
+```js
+var connect = require('connect');
+var errorhandler = require('errorhandler');
+var notifier = require('node-notifier');
+
+var app = connect();
+
+// assumes NODE_ENV is set by the user
+if (process.env.NODE_ENV === 'development') {
+ // only use in development
+ app.use(errorhandler({ log: errorNotification }));
+}
+
+function errorNotification(err, str, req) {
+ var title = 'Error in ' + req.method + ' ' + req.url;
+
+ notifier.notify({
+ title: title,
+ message: str,
+ });
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/errorhandler/master
+[coveralls-url]: https://coveralls.io/r/expressjs/errorhandler?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/errorhandler
+[npm-url]: https://npmjs.org/package/errorhandler
+[npm-version-image]: https://badgen.net/npm/v/errorhandler
diff --git a/astro/src/content/resources/zh-tw/middleware/method-override.md b/astro/src/content/resources/zh-tw/middleware/method-override.md
new file mode 100644
index 0000000000..7b97ab855e
--- /dev/null
+++ b/astro/src/content/resources/zh-tw/middleware/method-override.md
@@ -0,0 +1,187 @@
+---
+title: Express method-override middleware
+module: method-override
+---
+
+# method-override
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][travis-image]][travis-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Lets you use HTTP verbs such as PUT or DELETE in places where the client doesn't support it.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install method-override
+```
+
+## API
+
+**NOTE** It is very important that this module is used **before** any module that
+needs to know the method of the request (for example, it _must_ be used prior to
+the `csurf` module).
+
+### methodOverride(getter, options)
+
+Create a new middleware function to override the `req.method` property with a new
+value. This value will be pulled from the provided `getter`.
+
+- `getter` - The getter to use to look up the overridden request method for the request. (default: `X-HTTP-Method-Override`)
+- `options.methods` - The allowed methods the original request must be in to check for a method override value. (default: `['POST']`)
+
+If the found method is supported by node.js core, then `req.method` will be set to
+this value, as if it has originally been that value. The previous `req.method`
+value will be stored in `req.originalMethod`.
+
+#### getter
+
+This is the method of getting the override value from the request. If a function is provided,
+the `req` is passed as the first argument, the `res` as the second argument and the method is
+expected to be returned. If a string is provided, the string is used to look up the method
+with the following rules:
+
+- If the string starts with `X-`, then it is treated as the name of a header and that header
+ is used for the method override. If the request contains the same header multiple times, the
+ first occurrence is used.
+- All other strings are treated as a key in the URL query string.
+
+#### options.methods
+
+This allows the specification of what methods(s) the request _MUST_ be in in order to check for
+the method override value. This defaults to only `POST` methods, which is the only method the
+override should arrive in. More methods may be specified here, but it may introduce security
+issues and cause weird behavior when requests travel through caches. This value is an array
+of methods in upper-case. `null` can be specified to allow all methods.
+
+## Examples
+
+### override using a header
+
+To use a header to override the method, specify the header name
+as a string argument to the `methodOverride` function. To then make
+the call, send a `POST` request to a URL with the overridden method
+as the value of that header. This method of using a header would
+typically be used in conjunction with `XMLHttpRequest` on implementations
+that do not support the method you are trying to use.
+
+```js
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// override with the X-HTTP-Method-Override header in the request
+app.use(methodOverride('X-HTTP-Method-Override'));
+```
+
+Example call with header override using `XMLHttpRequest`:
+
+
+
+```js
+const xhr = new XMLHttpRequest();
+xhr.onload = onload;
+xhr.open('post', '/resource', true);
+xhr.setRequestHeader('X-HTTP-Method-Override', 'DELETE');
+xhr.send();
+
+function onload() {
+ alert('got response: ' + this.responseText);
+}
+```
+
+### override using a query value
+
+To use a query string value to override the method, specify the query
+string key as a string argument to the `methodOverride` function. To
+then make the call, send a `POST` request to a URL with the overridden
+method as the value of that query string key. This method of using a
+query value would typically be used in conjunction with plain HTML
+`
+```
+
+### multiple format support
+
+```js
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// override with different headers; last one takes precedence
+app.use(methodOverride('X-HTTP-Method')); // Microsoft
+app.use(methodOverride('X-HTTP-Method-Override')); // Google/GData
+app.use(methodOverride('X-Method-Override')); // IBM
+```
+
+### custom logic
+
+You can implement any kind of custom logic with a function for the `getter`. The following
+implements the logic for looking in `req.body` that was in `method-override@1`:
+
+```js
+const bodyParser = require('body-parser');
+const express = require('express');
+const methodOverride = require('method-override');
+const app = express();
+
+// NOTE: when using req.body, you must fully parse the request body
+// before you call methodOverride() in your middleware stack,
+// otherwise req.body will not be populated.
+app.use(bodyParser.urlencoded());
+app.use(
+ methodOverride(function (req, res) {
+ if (req.body && typeof req.body === 'object' && '_method' in req.body) {
+ // look in urlencoded POST bodies and delete it
+ const method = req.body._method;
+ delete req.body._method;
+ return method;
+ }
+ })
+);
+```
+
+Example call with query override using HTML `
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/method-override.svg
+[npm-url]: https://npmjs.org/package/method-override
+[travis-image]: https://img.shields.io/travis/expressjs/method-override/master.svg
+[travis-url]: https://travis-ci.org/expressjs/method-override
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/method-override/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/method-override?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/method-override.svg
+[downloads-url]: https://npmjs.org/package/method-override
diff --git a/astro/src/content/resources/zh-tw/middleware/morgan.md b/astro/src/content/resources/zh-tw/middleware/morgan.md
new file mode 100644
index 0000000000..5319d93d57
--- /dev/null
+++ b/astro/src/content/resources/zh-tw/middleware/morgan.md
@@ -0,0 +1,458 @@
+---
+title: Express morgan middleware
+module: morgan
+---
+
+# morgan
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Build Status][ci-image]][ci-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+HTTP request logger middleware for node.js
+
+> Named after [Dexter](http://en.wikipedia.org/wiki/Dexter_Morgan), a show you should not watch until completion.
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install morgan
+```
+
+## API
+
+
+
+```js
+var morgan = require('morgan');
+```
+
+### morgan(format, options)
+
+Create a new morgan logger middleware function using the given `format` and `options`.
+The `format` argument may be a string of a predefined name (see below for the names),
+a string of a format string, or a function that will produce a log entry.
+
+The `format` function will be called with three arguments `tokens`, `req`, and `res`,
+where `tokens` is an object with all defined tokens, `req` is the HTTP request and `res`
+is the HTTP response. The function is expected to return a string that will be the log
+line, or `undefined` / `null` to skip logging.
+
+#### Using a predefined format string
+
+
+
+```js
+morgan('tiny');
+```
+
+#### Using format string of predefined tokens
+
+
+
+```js
+morgan(':method :url :status :res[content-length] - :response-time ms');
+```
+
+#### Using a custom format function
+
+
+
+```js
+morgan(function (tokens, req, res) {
+ return [
+ tokens.method(req, res),
+ tokens.url(req, res),
+ tokens.status(req, res),
+ tokens.res(req, res, 'content-length'),
+ '-',
+ tokens['response-time'](req, res),
+ 'ms',
+ ].join(' ');
+});
+```
+
+#### Options
+
+Morgan accepts these properties in the options object.
+
+##### immediate
+
+Write log line on request instead of response. This means that a requests will
+be logged even if the server crashes, _but data from the response (like the
+response code, content length, etc.) cannot be logged_.
+
+##### skip
+
+Function to determine if logging is skipped, defaults to `false`. This function
+will be called as `skip(req, res)`.
+
+
+
+```js
+// EXAMPLE: only log error responses
+morgan('combined', {
+ skip: function (req, res) {
+ return res.statusCode < 400;
+ },
+});
+```
+
+##### stream
+
+Output stream for writing log lines, defaults to `process.stdout`.
+
+#### Predefined Formats
+
+There are various pre-defined formats provided:
+
+##### combined
+
+Standard Apache combined log output.
+
+```
+:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"
+# will output
+::1 - - [27/Nov/2024:06:21:42 +0000] "GET /combined HTTP/1.1" 200 2 "-" "curl/8.7.1"
+```
+
+##### common
+
+Standard Apache common log output.
+
+```
+:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length]
+# will output
+::1 - - [27/Nov/2024:06:21:46 +0000] "GET /common HTTP/1.1" 200 2
+```
+
+##### dev
+
+Concise output colored by response status for development use. The `:status`
+token will be colored green for success codes, red for server error codes,
+yellow for client error codes, cyan for redirection codes, and uncolored
+for information codes.
+
+```
+:method :url :status :response-time ms - :res[content-length]
+# will output
+GET /dev 200 0.224 ms - 2
+```
+
+##### short
+
+Shorter than default, also including response time.
+
+```
+:remote-addr :remote-user :method :url HTTP/:http-version :status :res[content-length] - :response-time ms
+# will output
+::1 - GET /short HTTP/1.1 200 2 - 0.283 ms
+```
+
+##### tiny
+
+The minimal output.
+
+```
+:method :url :status :res[content-length] - :response-time ms
+# will output
+GET /tiny 200 2 - 0.188 ms
+```
+
+#### Tokens
+
+##### Creating new tokens
+
+To define a token, simply invoke `morgan.token()` with the name and a callback function.
+This callback function is expected to return a string value. The value returned is then
+available as ":type" in this case:
+
+
+
+```js
+morgan.token('type', function (req, res) {
+ return req.headers['content-type'];
+});
+```
+
+Calling `morgan.token()` using the same name as an existing token will overwrite that
+token definition.
+
+The token function is expected to be called with the arguments `req` and `res`, representing
+the HTTP request and HTTP response. Additionally, the token can accept further arguments of
+it's choosing to customize behavior.
+
+##### :date[format]
+
+The current date and time in UTC. The available formats are:
+
+- `clf` for the common log format (`"10/Oct/2000:13:55:36 +0000"`)
+- `iso` for the common ISO 8601 date time format (`2000-10-10T13:55:36.000Z`)
+- `web` for the common RFC 1123 date time format (`Tue, 10 Oct 2000 13:55:36 GMT`)
+
+If no format is given, then the default is `web`.
+
+##### :http-version
+
+The HTTP version of the request.
+
+##### :method
+
+The HTTP method of the request.
+
+##### :pid
+
+The process ID of the Node.js process handling the request.
+
+##### :referrer
+
+The Referrer header of the request. This will use the standard mis-spelled Referer header if exists, otherwise Referrer.
+
+##### :remote-addr
+
+The remote address of the request. This will use `req.ip`, otherwise the standard `req.connection.remoteAddress` value (socket address).
+
+##### :remote-user
+
+The user authenticated as part of Basic auth for the request.
+
+##### :req[header]
+
+The given `header` of the request. If the header is not present, the
+value will be displayed as `"-"` in the log.
+
+##### :res[header]
+
+The given `header` of the response. If the header is not present, the
+value will be displayed as `"-"` in the log.
+
+##### :response-time[digits]
+
+The time between the request coming into `morgan` and when the response
+headers are written, in milliseconds.
+
+The `digits` argument is a number that specifies the number of digits to
+include on the number, defaulting to `3`, which provides microsecond precision.
+
+##### :status
+
+The status code of the response.
+
+If the request/response cycle completes before a response was sent to the
+client (for example, the TCP socket closed prematurely by a client aborting
+the request), then the status will be empty (displayed as `"-"` in the log).
+
+##### :total-time[digits]
+
+The time between the request coming into `morgan` and when the response
+has finished being written out to the connection, in milliseconds.
+
+The `digits` argument is a number that specifies the number of digits to
+include on the number, defaulting to `3`, which provides microsecond precision.
+
+##### :url
+
+The URL of the request. This will use `req.originalUrl` if exists, otherwise `req.url`.
+
+##### :user-agent
+
+The contents of the User-Agent header of the request.
+
+### morgan.compile(format)
+
+Compile a format string into a `format` function for use by `morgan`. A format string
+is a string that represents a single log line and can utilize token syntax.
+Tokens are references by `:token-name`. If tokens accept arguments, they can
+be passed using `[]`, for example: `:token-name[pretty]` would pass the string
+`'pretty'` as an argument to the token `token-name`.
+
+The function returned from `morgan.compile` takes three arguments `tokens`, `req`, and
+`res`, where `tokens` is object with all defined tokens, `req` is the HTTP request and
+`res` is the HTTP response. The function will return a string that will be the log line,
+or `undefined` / `null` to skip logging.
+
+Normally formats are defined using `morgan.format(name, format)`, but for certain
+advanced uses, this compile function is directly available.
+
+## Examples
+
+### express/connect
+
+Sample app that will log all request in the Apache combined format to STDOUT
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+
+var app = express();
+
+app.use(morgan('combined'));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### vanilla http server
+
+Sample app that will log all request in the Apache combined format to STDOUT
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var morgan = require('morgan');
+
+// create "middleware"
+var logger = morgan('combined');
+
+http.createServer(function (req, res) {
+ var done = finalhandler(req, res);
+ logger(req, res, function (err) {
+ if (err) return done(err);
+
+ // respond to request
+ res.setHeader('content-type', 'text/plain');
+ res.end('hello, world!');
+ });
+});
+```
+
+### write logs to a file
+
+#### single file
+
+Sample app that will log all requests in the Apache combined format to the file
+`access.log`.
+
+```js
+var express = require('express');
+var fs = require('fs');
+var morgan = require('morgan');
+var path = require('path');
+
+var app = express();
+
+// create a write stream (in append mode)
+var accessLogStream = fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' });
+
+// setup the logger
+app.use(morgan('combined', { stream: accessLogStream }));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+#### log file rotation
+
+Sample app that will log all requests in the Apache combined format to one log
+file per day in the `log/` directory using the
+[rotating-file-stream module](https://www.npmjs.com/package/rotating-file-stream).
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+var path = require('path');
+var rfs = require('rotating-file-stream'); // version 2.x
+
+var app = express();
+
+// create a rotating write stream
+var accessLogStream = rfs.createStream('access.log', {
+ interval: '1d', // rotate daily
+ path: path.join(__dirname, 'log'),
+});
+
+// setup the logger
+app.use(morgan('combined', { stream: accessLogStream }));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### split / dual logging
+
+The `morgan` middleware can be used as many times as needed, enabling
+combinations like:
+
+- Log entry on request and one on response
+- Log all requests to file, but errors to console
+- ... and more!
+
+Sample app that will log all requests to a file using Apache format, but
+error responses are logged to the console:
+
+```js
+var express = require('express');
+var fs = require('fs');
+var morgan = require('morgan');
+var path = require('path');
+
+var app = express();
+
+// log only 4xx and 5xx responses to console
+app.use(
+ morgan('dev', {
+ skip: function (req, res) {
+ return res.statusCode < 400;
+ },
+ })
+);
+
+// log all requests to access.log
+app.use(
+ morgan('common', {
+ stream: fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' }),
+ })
+);
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+```
+
+### use custom token formats
+
+Sample app that will use custom token formats. This adds an ID to all requests and displays it using the `:id` token.
+
+```js
+var express = require('express');
+var morgan = require('morgan');
+var uuid = require('node-uuid');
+
+morgan.token('id', function getId(req) {
+ return req.id;
+});
+
+var app = express();
+
+app.use(assignId);
+app.use(morgan(':id :method :url :response-time'));
+
+app.get('/', function (req, res) {
+ res.send('hello, world!');
+});
+
+function assignId(req, res, next) {
+ req.id = uuid.v4();
+ next();
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://badgen.net/github/checks/expressjs/morgan/master?label=ci
+[ci-url]: https://github.com/expressjs/morgan/actions/workflows/ci.yml
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/morgan/master
+[coveralls-url]: https://coveralls.io/r/expressjs/morgan?branch=master
+[npm-downloads-image]: https://badgen.net/npm/dm/morgan
+[npm-url]: https://npmjs.org/package/morgan
+[npm-version-image]: https://badgen.net/npm/v/morgan
diff --git a/astro/src/content/resources/zh-tw/middleware/multer.md b/astro/src/content/resources/zh-tw/middleware/multer.md
new file mode 100644
index 0000000000..326786ab3d
--- /dev/null
+++ b/astro/src/content/resources/zh-tw/middleware/multer.md
@@ -0,0 +1,352 @@
+---
+title: Express multer middleware
+module: multer
+---
+
+# Multer [![NPM Version][npm-version-image]][npm-url] [![NPM Downloads][npm-downloads-image]][npm-url] [![Build Status][ci-image]][ci-url] [![Test Coverage][test-image]][test-url] [![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+
+Multer is a node.js middleware for handling `multipart/form-data`, which is primarily used for uploading files. It is written
+on top of [busboy](https://github.com/mscdex/busboy) for maximum efficiency.
+
+**NOTE**: Multer will not process any form which is not multipart (`multipart/form-data`).
+
+## Translations
+
+This README is also available in other languages:
+
+| | |
+| ------------------------------------------------------------------------------ | --------------- |
+| [العربية](https://github.com/expressjs/multer/blob/main/doc/README-ar.md) | Arabic |
+| [简体中文](https://github.com/expressjs/multer/blob/main/doc/README-zh-cn.md) | Chinese |
+| [Français](https://github.com/expressjs/multer/blob/main/doc/README-fr.md) | French |
+| [한국어](https://github.com/expressjs/multer/blob/main/doc/README-ko.md) | Korean |
+| [Português](https://github.com/expressjs/multer/blob/main/doc/README-pt-br.md) | Portuguese (BR) |
+| [Русский язык](https://github.com/expressjs/multer/blob/main/doc/README-ru.md) | Russian |
+| [Español](https://github.com/expressjs/multer/blob/main/doc/README-es.md) | Spanish |
+| [O'zbek tili](https://github.com/expressjs/multer/blob/main/doc/README-uz.md) | Uzbek |
+| [Việt Nam](https://github.com/expressjs/multer/blob/main/doc/README-vi.md) | Vietnamese |
+
+## Installation
+
+```sh
+$ npm install multer
+```
+
+## Usage
+
+Multer adds a `body` object and a `file` or `files` object to the `request` object. The `body` object contains the values of the text fields of the form, the `file` or `files` object contains the files uploaded via the form.
+
+Basic usage example:
+
+Don't forget the `enctype="multipart/form-data"` in your form.
+
+```html
+
+```
+
+```javascript
+const express = require('express');
+const multer = require('multer');
+const upload = multer({ dest: 'uploads/' });
+
+const app = express();
+
+app.post('/profile', upload.single('avatar'), function (req, res, next) {
+ // req.file is the `avatar` file
+ // req.body will hold the text fields, if there were any
+});
+
+app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
+ // req.files is array of `photos` files
+ // req.body will contain the text fields, if there were any
+});
+
+const uploadMiddleware = upload.fields([
+ { name: 'avatar', maxCount: 1 },
+ { name: 'gallery', maxCount: 8 },
+]);
+app.post('/cool-profile', uploadMiddleware, function (req, res, next) {
+ // req.files is an object (String -> Array) where fieldname is the key, and the value is array of files
+ //
+ // e.g.
+ // req.files['avatar'][0] -> File
+ // req.files['gallery'] -> Array
+ //
+ // req.body will contain the text fields, if there were any
+});
+```
+
+In case you need to handle a text-only multipart form, you should use the `.none()` method:
+
+```javascript
+const express = require('express');
+const app = express();
+const multer = require('multer');
+const upload = multer();
+
+app.post('/profile', upload.none(), function (req, res, next) {
+ // req.body contains the text fields
+});
+```
+
+Here's an example on how multer is used in a HTML form. Take special note of the `enctype="multipart/form-data"` and `name="uploaded_file"` fields:
+
+```html
+
+```
+
+Then in your javascript file you would add these lines to access both the file and the body. It is important that you use the `name` field value from the form in your upload function. This tells multer which field on the request it should look for the files in. If these fields aren't the same in the HTML form and on your server, your upload will fail:
+
+```javascript
+const multer = require('multer');
+const upload = multer({ dest: './public/data/uploads/' });
+app.post('/stats', upload.single('uploaded_file'), function (req, res) {
+ // req.file is the name of your file in the form above, here 'uploaded_file'
+ // req.body will hold the text fields, if there were any
+ console.log(req.file, req.body);
+});
+```
+
+## API
+
+### File information
+
+Each file contains the following information:
+
+| Key | Description | Note |
+| -------------- | --------------------------------------------- | --------------- |
+| `fieldname` | Field name specified in the form |
+| `originalname` | Name of the file on the user's computer |
+| `encoding` | Encoding type of the file |
+| `mimetype` | Mime type of the file |
+| `size` | Size of the file in bytes |
+| `destination` | The folder to which the file has been saved | `DiskStorage` |
+| `filename` | The name of the file within the `destination` | `DiskStorage` |
+| `path` | The full path to the uploaded file | `DiskStorage` |
+| `buffer` | A `Buffer` of the entire file | `MemoryStorage` |
+
+### `multer(opts)`
+
+Multer accepts an options object, the most basic of which is the `dest`
+property, which tells Multer where to upload the files. In case you omit the
+options object, the files will be kept in memory and never written to disk.
+
+By default, Multer will rename the files so as to avoid naming conflicts. The
+renaming function can be customized according to your needs.
+
+The following are the options that can be passed to Multer.
+
+| Key | Description |
+| ------------------- | --------------------------------------------------------- |
+| `dest` or `storage` | Where to store the files |
+| `fileFilter` | Function to control which files are accepted |
+| `limits` | Limits of the uploaded data |
+| `preservePath` | Keep the full path of files instead of just the base name |
+
+In an average web app, only `dest` might be required, and configured as shown in
+the following example.
+
+```javascript
+const upload = multer({ dest: 'uploads/' });
+```
+
+If you want more control over your uploads, you'll want to use the `storage`
+option instead of `dest`. Multer ships with storage engines `DiskStorage`
+and `MemoryStorage`; More engines are available from third parties.
+
+#### `.single(fieldname)`
+
+Accept a single file with the name `fieldname`. The single file will be stored
+in `req.file`.
+
+#### `.array(fieldname[, maxCount])`
+
+Accept an array of files, all with the name `fieldname`. Optionally error out if
+more than `maxCount` files are uploaded. The array of files will be stored in
+`req.files`.
+
+#### `.fields(fields)`
+
+Accept a mix of files, specified by `fields`. An object with arrays of files
+will be stored in `req.files`.
+
+`fields` should be an array of objects with `name` and optionally a `maxCount`.
+Example:
+
+```javascript
+[
+ { name: 'avatar', maxCount: 1 },
+ { name: 'gallery', maxCount: 8 },
+];
+```
+
+#### `.none()`
+
+Accept only text fields. If any file upload is made, error with code
+"LIMIT_UNEXPECTED_FILE" will be issued.
+
+#### `.any()`
+
+Accepts all files that comes over the wire. An array of files will be stored in
+`req.files`.
+
+**WARNING:** Make sure that you always handle the files that a user uploads.
+Never add multer as a global middleware since a malicious user could upload
+files to a route that you didn't anticipate. Only use this function on routes
+where you are handling the uploaded files.
+
+### `storage`
+
+#### `DiskStorage`
+
+The disk storage engine gives you full control on storing files to disk.
+
+```javascript
+const storage = multer.diskStorage({
+ destination: function (req, file, cb) {
+ cb(null, '/tmp/my-uploads');
+ },
+ filename: function (req, file, cb) {
+ const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
+ cb(null, file.fieldname + '-' + uniqueSuffix);
+ },
+});
+
+const upload = multer({ storage: storage });
+```
+
+There are two options available, `destination` and `filename`. They are both
+functions that determine where the file should be stored.
+
+`destination` is used to determine within which folder the uploaded files should
+be stored. This can also be given as a `string` (e.g. `'/tmp/uploads'`). If no
+`destination` is given, the operating system's default directory for temporary
+files is used.
+
+**Note:** You are responsible for creating the directory when providing
+`destination` as a function. When passing a string, multer will make sure that
+the directory is created for you.
+
+`filename` is used to determine what the file should be named inside the folder.
+If no `filename` is given, each file will be given a random name that doesn't
+include any file extension.
+
+**Note:** Multer will not append any file extension for you, your function
+should return a filename complete with a file extension.
+
+Each function gets passed both the request (`req`) and some information about
+the file (`file`) to aid with the decision.
+
+Note that `req.body` might not have been fully populated yet. It depends on the
+order that the client transmits fields and files to the server.
+
+For understanding the calling convention used in the callback (needing to pass
+null as the first param), refer to
+[Node.js error handling](https://web.archive.org/web/20220417042018/https://www.joyent.com/node-js/production/design/errors)
+
+#### `MemoryStorage`
+
+The memory storage engine stores the files in memory as `Buffer` objects. It
+doesn't have any options.
+
+```javascript
+const storage = multer.memoryStorage();
+const upload = multer({ storage: storage });
+```
+
+When using memory storage, the file info will contain a field called
+`buffer` that contains the entire file.
+
+**WARNING**: Uploading very large files, or relatively small files in large
+numbers very quickly, can cause your application to run out of memory when
+memory storage is used.
+
+### `limits`
+
+An object specifying the size limits of the following optional properties. Multer passes this object into busboy directly, and the details of the properties can be found on [busboy's page](https://github.com/mscdex/busboy#busboy-methods).
+
+The following integer values are available:
+
+| Key | Description | Default |
+| --------------- | ----------------------------------------------------------------------- | --------- |
+| `fieldNameSize` | Max field name size | 100 bytes |
+| `fieldSize` | Max field value size (in bytes) | 1MB |
+| `fields` | Max number of non-file fields | Infinity |
+| `fileSize` | For multipart forms, the max file size (in bytes) | Infinity |
+| `files` | For multipart forms, the max number of file fields | Infinity |
+| `parts` | For multipart forms, the max number of parts (fields + files) | Infinity |
+| `headerPairs` | For multipart forms, the max number of header key=>value pairs to parse | 2000 |
+
+Specifying the limits can help protect your site against denial of service (DoS) attacks.
+
+### `fileFilter`
+
+Set this to a function to control which files should be uploaded and which
+should be skipped. The function should look like this:
+
+```javascript
+function fileFilter(req, file, cb) {
+ // The function should call `cb` with a boolean
+ // to indicate if the file should be accepted
+
+ // To reject this file pass `false`, like so:
+ cb(null, false);
+
+ // To accept the file pass `true`, like so:
+ cb(null, true);
+
+ // You can always pass an error if something goes wrong:
+ cb(new Error("I don't have a clue!"));
+}
+```
+
+## Error handling
+
+When encountering an error, Multer will delegate the error to Express. You can
+display a nice error page using [the standard express way](http://expressjs.com/guide/error-handling.html).
+
+If you want to catch errors specifically from Multer, you can call the
+middleware function by yourself. Also, if you want to catch only [the Multer errors](https://github.com/expressjs/multer/blob/main/lib/multer-error.js), you can use the `MulterError` class that is attached to the `multer` object itself (e.g. `err instanceof multer.MulterError`).
+
+```javascript
+const multer = require('multer');
+const upload = multer().single('avatar');
+
+app.post('/profile', function (req, res) {
+ upload(req, res, function (err) {
+ if (err instanceof multer.MulterError) {
+ // A Multer error occurred when uploading.
+ } else if (err) {
+ // An unknown error occurred when uploading.
+ }
+
+ // Everything went fine.
+ });
+});
+```
+
+## Custom storage engine
+
+For information on how to build your own storage engine, see [Multer Storage Engine](https://github.com/expressjs/multer/blob/main/StorageEngine.md).
+
+## License
+
+[MIT](LICENSE)
+
+[ci-image]: https://github.com/expressjs/multer/actions/workflows/ci.yml/badge.svg
+[ci-url]: https://github.com/expressjs/multer/actions/workflows/ci.yml
+[test-url]: https://coveralls.io/r/expressjs/multer?branch=main
+[test-image]: https://badgen.net/coveralls/c/github/expressjs/multer/main
+[npm-downloads-image]: https://badgen.net/npm/dm/multer
+[npm-url]: https://npmjs.org/package/multer
+[npm-version-image]: https://badgen.net/npm/v/multer
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/multer/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer
diff --git a/astro/src/content/resources/zh-tw/middleware/overview.md b/astro/src/content/resources/zh-tw/middleware/overview.md
new file mode 100755
index 0000000000..46217759e7
--- /dev/null
+++ b/astro/src/content/resources/zh-tw/middleware/overview.md
@@ -0,0 +1,40 @@
+---
+title: Express middleware
+description: Explore a list of Express.js middleware modules maintained by the Express team and the community, including built-in middleware and popular third-party modules.
+module: mw-home
+---
+
+## Express middleware
+
+The Express middleware modules listed here are maintained by the
+[Expressjs team](https://github.com/orgs/expressjs/people).
+
+| Middleware module | Description |
+| ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
+| [body-parser](/en/resources/middleware/body-parser) | Parse HTTP request body. |
+| [compression](/en/resources/middleware/compression) | Compress HTTP responses. |
+| [cookie-parser](/en/resources/middleware/cookie-parser) | Parse cookie header and populate `req.cookies`. See also [cookies](https://github.com/jed/cookies). |
+| [cookie-session](/en/resources/middleware/cookie-session) | Establish cookie-based sessions. |
+| [cors](/en/resources/middleware/cors) | Enable cross-origin resource sharing (CORS) with various options. |
+| [errorhandler](/en/resources/middleware/errorhandler) | Development error-handling/debugging. |
+| [method-override](/en/resources/middleware/method-override) | Override HTTP methods using header. |
+| [morgan](/en/resources/middleware/morgan) | HTTP request logger. |
+| [multer](/en/resources/middleware/multer) | Handle multi-part form data. |
+| [response-time](/en/resources/middleware/response-time) | Record HTTP response time. |
+| [serve-favicon](/en/resources/middleware/serve-favicon) | Serve a favicon. |
+| [serve-index](/en/resources/middleware/serve-index) | Serve directory listing for a given path. |
+| [serve-static](/en/resources/middleware/serve-static) | Serve static files. |
+| [session](/en/resources/middleware/session) | Establish server-based sessions (development only). |
+| [timeout](/en/resources/middleware/timeout) | Set a timeout perioHTTP request processing. |
+| [vhost](/en/resources/middleware/vhost) | Create virtual domains. |
+
+## Additional middleware modules
+
+These are some additional popular middleware modules.
+
+{% include community-caveat.html %}
+
+| Middleware module | Description |
+| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
+| [helmet](https://github.com/helmetjs/helmet) | Helps secure your apps by setting various HTTP headers. |
+| [passport](https://github.com/jaredhanson/passport) | Authentication using "strategies" such as OAuth, OpenID and many others. See [passportjs.org](https://passportjs.org/) for more information. |
diff --git a/astro/src/content/resources/zh-tw/middleware/response-time.md b/astro/src/content/resources/zh-tw/middleware/response-time.md
new file mode 100644
index 0000000000..f911f480f5
--- /dev/null
+++ b/astro/src/content/resources/zh-tw/middleware/response-time.md
@@ -0,0 +1,314 @@
+---
+title: Express response-time middleware
+module: response-time
+---
+
+# compression
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
+[![Funding][funding-image]][funding-url]
+
+Node.js compression middleware.
+
+The following compression codings are supported:
+
+- deflate
+- gzip
+- br (brotli)
+
+**Note** Brotli is supported only since Node.js versions v11.7.0 and v10.16.0.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```bash
+$ npm install compression
+```
+
+## API
+
+```js
+var compression = require('compression');
+```
+
+### compression([options])
+
+Returns the compression middleware using the given `options`. The middleware
+will attempt to compress response bodies for all requests that traverse through
+the middleware, based on the given `options`.
+
+This middleware will never compress responses that include a `Cache-Control`
+header with the [`no-transform` directive](https://tools.ietf.org/html/rfc7234#section-5.2.2.4),
+as compressing will transform the body.
+
+#### Options
+
+`compression()` accepts these properties in the options object. In addition to
+those listed below, [zlib](https://nodejs.org/api/zlib.html) options may be
+passed in to the options object or
+[brotli](https://nodejs.org/api/zlib.html#zlib_class_brotlioptions) options.
+
+##### chunkSize
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_CHUNK`, or `16384`.
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### filter
+
+Type: `Function`
+
+A function to decide if the response should be considered for compression.
+This function is called as `filter(req, res)` and is expected to return
+`true` to consider the response for compression, or `false` to not compress
+the response.
+
+The default filter function uses the [compressible](https://www.npmjs.com/package/compressible)
+module to determine if `res.getHeader('Content-Type')` is compressible.
+
+##### level
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_COMPRESSION`, or `-1`
+
+The level of zlib compression to apply to responses. A higher level will result
+in better compression, but will take longer to complete. A lower level will
+result in less compression, but will be much faster.
+
+This is an integer in the range of `0` (no compression) to `9` (maximum
+compression). The special value `-1` can be used to mean the "default
+compression level", which is a default compromise between speed and
+compression (currently equivalent to level 6).
+
+- `-1` Default compression level (also `zlib.constants.Z_DEFAULT_COMPRESSION`).
+- `0` No compression (also `zlib.constants.Z_NO_COMPRESSION`).
+- `1` Fastest compression (also `zlib.constants.Z_BEST_SPEED`).
+- `2`
+- `3`
+- `4`
+- `5`
+- `6` (currently what `zlib.constants.Z_DEFAULT_COMPRESSION` points to).
+- `7`
+- `8`
+- `9` Best compression (also `zlib.constants.Z_BEST_COMPRESSION`).
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### memLevel
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_MEMLEVEL`, or `8`
+
+This specifies how much memory should be allocated for the internal compression
+state and is an integer in the range of `1` (minimum level) and `9` (maximum
+level).
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### brotli
+
+Type: `Object`
+
+This specifies the options for configuring Brotli. See [Node.js documentation](https://nodejs.org/api/zlib.html#class-brotlioptions) for a complete list of available options.
+
+##### strategy
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_STRATEGY`
+
+This is used to tune the compression algorithm. This value only affects the
+compression ratio, not the correctness of the compressed output, even if it
+is not set appropriately.
+
+- `zlib.constants.Z_DEFAULT_STRATEGY` Use for normal data.
+- `zlib.constants.Z_FILTERED` Use for data produced by a filter (or predictor).
+ Filtered data consists mostly of small values with a somewhat random
+ distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect is to force more Huffman coding and less
+ string matching; it is somewhat intermediate between `zlib.constants.Z_DEFAULT_STRATEGY`
+ and `zlib.constants.Z_HUFFMAN_ONLY`.
+- `zlib.constants.Z_FIXED` Use to prevent the use of dynamic Huffman codes, allowing
+ for a simpler decoder for special applications.
+- `zlib.constants.Z_HUFFMAN_ONLY` Use to force Huffman encoding only (no string match).
+- `zlib.constants.Z_RLE` Use to limit match distances to one (run-length encoding).
+ This is designed to be almost as fast as `zlib.constants.Z_HUFFMAN_ONLY`, but give
+ better compression for PNG image data.
+
+**Note** in the list above, `zlib` is from `zlib = require('zlib')`.
+
+##### threshold
+
+Type: `Number` or `String`
+Default: `1kb`
+
+The byte threshold for the response body size before compression is considered
+for the response. This is a number of bytes or any string
+accepted by the [bytes](https://www.npmjs.com/package/bytes) module.
+
+**Note** this is only an advisory setting; if the response size cannot be determined
+at the time the response headers are written, then it is assumed the response is
+_over_ the threshold. To guarantee the response size can be determined, be sure
+set a `Content-Length` response header.
+
+##### windowBits
+
+Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_WINDOWBITS`, or `15`
+
+See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning)
+regarding the usage.
+
+##### enforceEncoding
+
+Type: `String`
+Default: `identity`
+
+This is the default encoding to use when the client does not specify an encoding in the request's [Accept-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) header.
+
+#### .filter
+
+The default `filter` function. This is used to construct a custom filter
+function that is an extension of the default function.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+app.use(compression({ filter: shouldCompress }));
+
+function shouldCompress(req, res) {
+ if (req.headers['x-no-compression']) {
+ // don't compress responses with this request header
+ return false;
+ }
+
+ // fallback to standard filter function
+ return compression.filter(req, res);
+}
+```
+
+### res.flush
+
+This module adds a `res.flush()` method to force the partially-compressed
+response to be flushed to the client.
+
+## Examples
+
+### express
+
+When using this module with express, simply `app.use` the module as
+high as you like. Requests that pass through the middleware will be compressed.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress all responses
+app.use(compression());
+
+// add all routes
+```
+
+### Node.js HTTP server
+
+```js
+var compression = require('compression')({ threshold: 0 });
+var http = require('http');
+
+function createServer(fn) {
+ return http.createServer(function (req, res) {
+ compression(req, res, function (err) {
+ if (err) {
+ res.statusCode = err.status || 500;
+ res.end(err.message);
+ return;
+ }
+
+ fn(req, res);
+ });
+ });
+}
+
+var server = createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello world!');
+});
+
+server.listen(3000, () => {
+ console.log('> Listening at http://localhost:3000');
+});
+```
+
+### Server-Sent Events
+
+Because of the nature of compression this module does not work out of the box
+with server-sent events. To compress content, a window of the output needs to
+be buffered up in order to get good compression. Typically when using server-sent
+events, there are certain block of data that need to reach the client.
+
+You can achieve this by calling `res.flush()` when you need the data written to
+actually make it to the client.
+
+```js
+var compression = require('compression');
+var express = require('express');
+
+var app = express();
+
+// compress responses
+app.use(compression());
+
+// server-sent event stream
+app.get('/events', function (req, res) {
+ res.setHeader('Content-Type', 'text/event-stream');
+ res.setHeader('Cache-Control', 'no-cache');
+
+ // send a ping approx every 2 seconds
+ var timer = setInterval(function () {
+ res.write('data: ping\n\n');
+
+ // !!! this is the important part
+ res.flush();
+ }, 2000);
+
+ res.on('close', function () {
+ clearInterval(timer);
+ });
+});
+```
+
+## Contributing
+
+The Express.js project welcomes all constructive contributions. Contributions take many forms,
+from code for bug fixes and enhancements, to additions and fixes to documentation, additional
+tests, triaging incoming pull requests and issues, and more!
+
+See the [Contributing Guide](https://github.com/expressjs/express/blob/master/Contributing.md) for more technical details on contributing.
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://badgen.net/npm/v/compression
+[npm-url]: https://npmjs.org/package/compression
+[downloads-image]: https://badgen.net/npm/dm/compression
+[downloads-url]: https://npmcharts.com/compare/compression?minimal=true
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/compression/master?label=CI
+[github-actions-ci-url]: https://github.com/expressjs/compression/actions?query=workflow%3Aci
+[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/compression/badge
+[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/compression
+[funding-url]: https://opencollective.com/express
+[funding-image]: https://badgen.net/badge/icon/sponsor/pink?icon=github&label=Open%20Collective
diff --git a/astro/src/content/resources/zh-tw/middleware/serve-favicon.md b/astro/src/content/resources/zh-tw/middleware/serve-favicon.md
new file mode 100644
index 0000000000..7a77865c6b
--- /dev/null
+++ b/astro/src/content/resources/zh-tw/middleware/serve-favicon.md
@@ -0,0 +1,156 @@
+---
+title: Express serve-favicon middleware
+module: serve-favicon
+---
+
+# serve-index
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Linux Build Status][ci-image]][ci-url]
+[![Windows Build][appveyor-image]][appveyor-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+Serves pages that contain directory listings for a given path.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-index
+```
+
+## API
+
+```js
+var serveIndex = require('serve-index');
+```
+
+### serveIndex(path, options)
+
+Returns middlware that serves an index of the directory in the given `path`.
+
+The `path` is based off the `req.url` value, so a `req.url` of `'/some/dir`
+with a `path` of `'public'` will look at `'public/some/dir'`. If you are using
+something like `express`, you can change the URL "base" with `app.use` (see
+the express example).
+
+#### Options
+
+Serve index accepts these properties in the options object.
+
+##### filter
+
+Apply this filter function to files. Defaults to `false`. The `filter` function
+is called for each file, with the signature `filter(filename, index, files, dir)`
+where `filename` is the name of the file, `index` is the array index, `files` is
+the array of files and `dir` is the absolute path the file is located (and thus,
+the directory the listing is for).
+
+##### hidden
+
+Display hidden (dot) files. Defaults to `false`.
+
+##### icons
+
+Display icons. Defaults to `false`.
+
+##### stylesheet
+
+Optional path to a CSS stylesheet. Defaults to a built-in stylesheet.
+
+##### template
+
+Optional path to an HTML template or a function that will render a HTML
+string. Defaults to a built-in template.
+
+When given a string, the string is used as a file path to load and then the
+following tokens are replaced in templates:
+
+- `{directory}` with the name of the directory.
+- `{files}` with the HTML of an unordered list of file links.
+- `{linked-path}` with the HTML of a link to the directory.
+- `{style}` with the specified stylesheet and embedded images.
+
+When given as a function, the function is called as `template(locals, callback)`
+and it needs to invoke `callback(error, htmlString)`. The following are the
+provided locals:
+
+- `directory` is the directory being displayed (where `/` is the root).
+- `displayIcons` is a Boolean for if icons should be rendered or not.
+- `fileList` is a sorted array of files in the directory. The array contains
+ objects with the following properties:
+ - `name` is the relative name for the file.
+ - `stat` is a `fs.Stats` object for the file.
+- `path` is the full filesystem path to `directory`.
+- `style` is the default stylesheet or the contents of the `stylesheet` option.
+- `viewName` is the view name provided by the `view` option.
+
+##### view
+
+Display mode. `tiles` and `details` are available. Defaults to `tiles`.
+
+## Examples
+
+### Serve directory indexes with vanilla node.js http server
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var serveIndex = require('serve-index');
+var serveStatic = require('serve-static');
+
+// Serve directory indexes for public/ftp folder (with icons)
+var index = serveIndex('public/ftp', { icons: true });
+
+// Serve up public/ftp folder files
+var serve = serveStatic('public/ftp');
+
+// Create server
+var server = http.createServer(function onRequest(req, res) {
+ var done = finalhandler(req, res);
+ serve(req, res, function onNext(err) {
+ if (err) return done(err);
+ index(req, res, done);
+ });
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve directory indexes with express
+
+```js
+var express = require('express');
+var serveIndex = require('serve-index');
+
+var app = express();
+
+// Serve URLs like /ftp/thing as public/ftp/thing
+// The express.static serves the file contents
+// The serveIndex is this module serving the directory
+app.use('/ftp', express.static('public/ftp'), serveIndex('public/ftp', { icons: true }));
+
+// Listen
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE). The [Silk](http://www.famfamfam.com/lab/icons/silk/) icons
+are created by/copyright of [FAMFAMFAM](http://www.famfamfam.com/).
+
+[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/serve-index/master.svg?label=windows
+[appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index
+[ci-image]: https://badgen.net/github/checks/expressjs/serve-index/master?label=ci
+[ci-url]: https://github.com/expressjs/serve-index/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/serve-index/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-index?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/serve-index.svg
+[downloads-url]: https://npmjs.org/package/serve-index
+[npm-image]: https://img.shields.io/npm/v/serve-index.svg
+[npm-url]: https://npmjs.org/package/serve-index
diff --git a/astro/src/content/resources/zh-tw/middleware/serve-index.md b/astro/src/content/resources/zh-tw/middleware/serve-index.md
new file mode 100644
index 0000000000..da03cf94b2
--- /dev/null
+++ b/astro/src/content/resources/zh-tw/middleware/serve-index.md
@@ -0,0 +1,156 @@
+---
+title: Express serve-index middleware
+module: serve-index
+---
+
+# serve-index
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Linux Build Status][ci-image]][ci-url]
+[![Windows Build][appveyor-image]][appveyor-url]
+[![Coverage Status][coveralls-image]][coveralls-url]
+
+Serves pages that contain directory listings for a given path.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-index
+```
+
+## API
+
+```js
+var serveIndex = require('serve-index');
+```
+
+### serveIndex(path, options)
+
+Returns middlware that serves an index of the directory in the given `path`.
+
+The `path` is based off the `req.url` value, so a `req.url` of `'/some/dir`
+with a `path` of `'public'` will look at `'public/some/dir'`. If you are using
+something like `express`, you can change the URL "base" with `app.use` (see
+the express example).
+
+#### Options
+
+Serve index accepts these properties in the options object.
+
+##### filter
+
+Apply this filter function to files. Defaults to `false`. The `filter` function
+is called for each file, with the signature `filter(filename, index, files, dir)`
+where `filename` is the name of the file, `index` is the array index, `files` is
+the array of files and `dir` is the absolute path the file is located (and thus,
+the directory the listing is for).
+
+##### hidden
+
+Display hidden (dot) files. Defaults to `false`.
+
+##### icons
+
+Display icons. Defaults to `false`.
+
+##### stylesheet
+
+Optional path to a CSS stylesheet. Defaults to a built-in stylesheet.
+
+##### template
+
+Optional path to an HTML template or a function that will render a HTML
+string. Defaults to a built-in template.
+
+When given a string, the string is used as a file path to load and then the
+following tokens are replaced in templates:
+
+- `{directory}` with the name of the directory.
+- `{files}` with the HTML of an unordered list of file links.
+- `{linked-path}` with the HTML of a link to the directory.
+- `{style}` with the specified stylesheet and embedded images.
+
+When given as a function, the function is called as `template(locals, callback)`
+and it needs to invoke `callback(error, htmlString)`. The following are the
+provided locals:
+
+- `directory` is the directory being displayed (where `/` is the root).
+- `displayIcons` is a Boolean for if icons should be rendered or not.
+- `fileList` is a sorted array of files in the directory. The array contains
+ objects with the following properties:
+ - `name` is the relative name for the file.
+ - `stat` is a `fs.Stats` object for the file.
+- `path` is the full filesystem path to `directory`.
+- `style` is the default stylesheet or the contents of the `stylesheet` option.
+- `viewName` is the view name provided by the `view` option.
+
+##### view
+
+Display mode. `tiles` and `details` are available. Defaults to `tiles`.
+
+## Examples
+
+### Serve directory indexes with vanilla node.js http server
+
+```js
+var finalhandler = require('finalhandler');
+var http = require('http');
+var serveIndex = require('serve-index');
+var serveStatic = require('serve-static');
+
+// Serve directory indexes for public/ftp folder (with icons)
+var index = serveIndex('public/ftp', { icons: true });
+
+// Serve up public/ftp folder files
+var serve = serveStatic('public/ftp');
+
+// Create server
+var server = http.createServer(function onRequest(req, res) {
+ var done = finalhandler(req, res);
+ serve(req, res, function onNext(err) {
+ if (err) return done(err);
+ index(req, res, done);
+ });
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve directory indexes with express
+
+```js
+var express = require('express');
+var serveIndex = require('serve-index');
+
+var app = express();
+
+// Serve URLs like /ftp/thing as public/ftp/thing
+// The express.static serves the file contents
+// The serveIndex is this module serving the directory
+app.use('/ftp', express.static('public/ftp'), serveIndex('public/ftp', { icons: true }));
+
+// Listen
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE). The [Silk](http://www.famfamfam.com/lab/icons/silk/) icons
+are created by/copyright of [FAMFAMFAM](http://www.famfamfam.com/).
+
+[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/serve-index/master.svg?label=windows
+[appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index
+[ci-image]: https://badgen.net/github/checks/expressjs/serve-index/master?label=ci
+[ci-url]: https://github.com/expressjs/serve-index/actions/workflows/ci.yml
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/serve-index/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-index?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/serve-index.svg
+[downloads-url]: https://npmjs.org/package/serve-index
+[npm-image]: https://img.shields.io/npm/v/serve-index.svg
+[npm-url]: https://npmjs.org/package/serve-index
diff --git a/astro/src/content/resources/zh-tw/middleware/serve-static.md b/astro/src/content/resources/zh-tw/middleware/serve-static.md
new file mode 100644
index 0000000000..b048165d7b
--- /dev/null
+++ b/astro/src/content/resources/zh-tw/middleware/serve-static.md
@@ -0,0 +1,260 @@
+---
+title: Express serve-static middleware
+module: serve-static
+---
+
+# serve-static
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![CI][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install serve-static
+```
+
+## API
+
+```js
+const serveStatic = require('serve-static');
+```
+
+### serveStatic(root, options)
+
+Create a new middleware function to serve files from within a given root
+directory. The file to serve will be determined by combining `req.url`
+with the provided root directory. When a file is not found, instead of
+sending a 404 response, this module will instead call `next()` to move on
+to the next middleware, allowing for stacking and fall-backs.
+
+#### Options
+
+##### acceptRanges
+
+Enable or disable accepting ranged requests, defaults to true.
+Disabling this will not send `Accept-Ranges` and ignore the contents
+of the `Range` request header.
+
+##### cacheControl
+
+Enable or disable setting `Cache-Control` response header, defaults to
+true. Disabling this will ignore the `immutable` and `maxAge` options.
+
+##### dotfiles
+
+Set how "dotfiles" are treated when encountered. A dotfile is a file
+or directory that begins with a dot ("."). Note this check is done on
+the path itself without checking if the path actually exists on the
+disk. If `root` is specified, only the dotfiles above the root are
+checked (i.e. the root itself can be within a dotfile when set
+to "deny").
+
+- `'allow'` No special treatment for dotfiles.
+- `'deny'` Deny a request for a dotfile and 403/`next()`.
+- `'ignore'` Pretend like the dotfile does not exist and 404/`next()`.
+
+The default value is `'ignore'`.
+
+##### etag
+
+Enable or disable etag generation, defaults to true.
+
+##### extensions
+
+Set file extension fallbacks. When set, if a file is not found, the given
+extensions will be added to the file name and search for. The first that
+exists will be served. Example: `['html', 'htm']`.
+
+The default value is `false`.
+
+##### fallthrough
+
+Set the middleware to have client errors fall-through as just unhandled
+requests, otherwise forward a client error. The difference is that client
+errors like a bad request or a request to a non-existent file will cause
+this middleware to simply `next()` to your next middleware when this value
+is `true`. When this value is `false`, these errors (even 404s), will invoke
+`next(err)`.
+
+Typically `true` is desired such that multiple physical directories can be
+mapped to the same web address or for routes to fill in non-existent files.
+
+The value `false` can be used if this middleware is mounted at a path that
+is designed to be strictly a single file system directory, which allows for
+short-circuiting 404s for less overhead. This middleware will also reply to
+all methods.
+
+The default value is `true`.
+
+##### immutable
+
+Enable or disable the `immutable` directive in the `Cache-Control` response
+header, defaults to `false`. If set to `true`, the `maxAge` option should
+also be specified to enable caching. The `immutable` directive will prevent
+supported clients from making conditional requests during the life of the
+`maxAge` option to check if the file has changed.
+
+##### index
+
+By default this module will send "index.html" files in response to a request
+on a directory. To disable this set `false` or to supply a new index pass a
+string or an array in preferred order.
+
+##### lastModified
+
+Enable or disable `Last-Modified` header, defaults to true. Uses the file
+system's last modified value.
+
+##### maxAge
+
+Provide a max-age in milliseconds for http caching, defaults to 0. This
+can also be a string accepted by the [ms](https://www.npmjs.org/package/ms#readme)
+module.
+
+##### redirect
+
+Redirect to trailing "/" when the pathname is a dir. Defaults to `true`.
+
+##### setHeaders
+
+Function to set custom headers on response. Alterations to the headers need to
+occur synchronously. The function is called as `fn(res, path, stat)`, where
+the arguments are:
+
+- `res` the response object
+- `path` the file path that is being sent
+- `stat` the stat object of the file that is being sent
+
+## Examples
+
+### Serve files with vanilla node.js http server
+
+```js
+const finalhandler = require('finalhandler');
+const http = require('http');
+const serveStatic = require('serve-static');
+
+// Serve up public/ftp folder
+const serve = serveStatic('public/ftp', { index: ['index.html', 'index.htm'] });
+
+// Create server
+const server = http.createServer((req, res) => {
+ serve(req, res, finalhandler(req, res));
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serve all files as downloads
+
+```js
+const contentDisposition = require('content-disposition');
+const finalhandler = require('finalhandler');
+const http = require('http');
+const serveStatic = require('serve-static');
+
+// Serve up public/ftp folder
+const serve = serveStatic('public/ftp', {
+ index: false,
+ setHeaders: setHeaders,
+});
+
+// Set header to force download
+function setHeaders(res, path) {
+ res.setHeader('Content-Disposition', contentDisposition(path));
+}
+
+// Create server
+const server = http.createServer((req, res) => {
+ serve(req, res, finalhandler(req, res));
+});
+
+// Listen
+server.listen(3000);
+```
+
+### Serving using express
+
+#### Simple
+
+This is a simple example of using Express.
+
+```js
+const express = require('express');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(serveStatic('public/ftp', { index: ['default.html', 'default.htm'] }));
+app.listen(3000);
+```
+
+#### Multiple roots
+
+This example shows a simple way to search through multiple directories.
+Files are searched for in `public-optimized/` first, then `public/` second
+as a fallback.
+
+```js
+const express = require('express');
+const path = require('path');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(serveStatic(path.join(__dirname, 'public-optimized')));
+app.use(serveStatic(path.join(__dirname, 'public')));
+app.listen(3000);
+```
+
+#### Different settings for paths
+
+This example shows how to set a different max age depending on the served
+file. In this example, HTML files are not cached, while everything else
+is for 1 day.
+
+```js
+const express = require('express');
+const path = require('path');
+const serveStatic = require('serve-static');
+
+const app = express();
+
+app.use(
+ serveStatic(path.join(__dirname, 'public'), {
+ maxAge: '1d',
+ setHeaders: setCustomCacheControl,
+ })
+);
+
+app.listen(3000);
+
+function setCustomCacheControl(res, file) {
+ if (path.extname(file) === '.html') {
+ // Custom Cache-Control for HTML files
+ res.setHeader('Cache-Control', 'public, max-age=0');
+ }
+}
+```
+
+## License
+
+[MIT](LICENSE)
+
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/serve-static/master
+[coveralls-url]: https://coveralls.io/r/expressjs/serve-static?branch=master
+[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/serve-static/master?label=linux
+[github-actions-ci-url]: https://github.com/expressjs/serve-static/actions/workflows/ci.yml
+[node-image]: https://badgen.net/npm/node/serve-static
+[node-url]: https://nodejs.org/en/download/
+[npm-downloads-image]: https://badgen.net/npm/dm/serve-static
+[npm-url]: https://npmjs.org/package/serve-static
+[npm-version-image]: https://badgen.net/npm/v/serve-static
diff --git a/astro/src/content/resources/zh-tw/middleware/session.md b/astro/src/content/resources/zh-tw/middleware/session.md
new file mode 100644
index 0000000000..90f3837a42
--- /dev/null
+++ b/astro/src/content/resources/zh-tw/middleware/session.md
@@ -0,0 +1,1046 @@
+---
+title: Express session middleware
+module: session
+---
+
+# express-session
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][node-url]
+[![Build Status][ci-image]][ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install express-session
+```
+
+## API
+
+```js
+var session = require('express-session');
+```
+
+### session(options)
+
+Create a session middleware with the given `options`.
+
+**Note** Session data is _not_ saved in the cookie itself, just the session ID.
+Session data is stored server-side.
+
+**Note** Since version 1.5.0, the [`cookie-parser` middleware](https://www.npmjs.com/package/cookie-parser)
+no longer needs to be used for this module to work. This module now directly reads
+and writes cookies on `req`/`res`. Using `cookie-parser` may result in issues
+if the `secret` is not the same between this module and `cookie-parser`.
+
+**Warning** The default server-side session storage, `MemoryStore`, is _purposely_
+not designed for a production environment. It will leak memory under most
+conditions, does not scale past a single process, and is meant for debugging and
+developing.
+
+For a list of stores, see [compatible session stores](#compatible-session-stores).
+
+#### Options
+
+`express-session` accepts these properties in the options object.
+
+##### cookie
+
+Settings object for the session ID cookie. The default value is
+`{ path: '/', httpOnly: true, secure: false, maxAge: null }`.
+
+The following are options that can be set in this object.
+
+##### cookie.domain
+
+Specifies the value for the `Domain` `Set-Cookie` attribute. By default, no domain
+is set, and most clients will consider the cookie to apply to only the current
+domain.
+
+##### cookie.expires
+
+Specifies the `Date` object to be the value for the `Expires` `Set-Cookie` attribute.
+By default, no expiration is set, and most clients will consider this a
+"non-persistent cookie" and will delete it on a condition like exiting a web browser
+application.
+
+**Note** If both `expires` and `maxAge` are set in the options, then the last one
+defined in the object is what is used.
+
+**Note** The `expires` option should not be set directly; instead only use the `maxAge`
+option.
+
+##### cookie.httpOnly
+
+Specifies the `boolean` value for the `HttpOnly` `Set-Cookie` attribute. When truthy,
+the `HttpOnly` attribute is set, otherwise it is not. By default, the `HttpOnly`
+attribute is set.
+
+**Note** be careful when setting this to `true`, as compliant clients will not allow
+client-side JavaScript to see the cookie in `document.cookie`.
+
+##### cookie.maxAge
+
+Specifies the `number` (in milliseconds) to use when calculating the `Expires`
+`Set-Cookie` attribute. This is done by taking the current server time and adding
+`maxAge` milliseconds to the value to calculate an `Expires` datetime. By default,
+no maximum age is set.
+
+**Note** If both `expires` and `maxAge` are set in the options, then the last one
+defined in the object is what is used.
+
+##### cookie.partitioned
+
+Specifies the `boolean` value for the [`Partitioned` `Set-Cookie`](rfc-cutler-httpbis-partitioned-cookies)
+attribute. When truthy, the `Partitioned` attribute is set, otherwise it is not.
+By default, the `Partitioned` attribute is not set.
+
+**Note** This is an attribute that has not yet been fully standardized, and may
+change in the future. This also means many clients may ignore this attribute until
+they understand it.
+
+More information about can be found in [the proposal](https://github.com/privacycg/CHIPS).
+
+##### cookie.path
+
+Specifies the value for the `Path` `Set-Cookie`. By default, this is set to `'/'`, which
+is the root path of the domain.
+
+##### cookie.priority
+
+Specifies the `string` to be the value for the [`Priority` `Set-Cookie` attribute][rfc-west-cookie-priority-00-4.1].
+
+- `'low'` will set the `Priority` attribute to `Low`.
+- `'medium'` will set the `Priority` attribute to `Medium`, the default priority when not set.
+- `'high'` will set the `Priority` attribute to `High`.
+
+More information about the different priority levels can be found in
+[the specification][rfc-west-cookie-priority-00-4.1].
+
+**Note** This is an attribute that has not yet been fully standardized, and may change in the future.
+This also means many clients may ignore this attribute until they understand it.
+
+##### cookie.sameSite
+
+Specifies the `boolean` or `string` to be the value for the `SameSite` `Set-Cookie` attribute.
+By default, this is `false`.
+
+- `true` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
+- `false` will not set the `SameSite` attribute.
+- `'lax'` will set the `SameSite` attribute to `Lax` for lax same site enforcement.
+- `'none'` will set the `SameSite` attribute to `None` for an explicit cross-site cookie.
+- `'strict'` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
+
+More information about the different enforcement levels can be found in
+[the specification][rfc-6265bis-03-4.1.2.7].
+
+**Note** This is an attribute that has not yet been fully standardized, and may change in
+the future. This also means many clients may ignore this attribute until they understand it.
+
+**Note** There is a [draft spec](https://tools.ietf.org/html/draft-west-cookie-incrementalism-01)
+that requires that the `Secure` attribute be set to `true` when the `SameSite` attribute has been
+set to `'none'`. Some web browsers or other clients may be adopting this specification.
+
+##### cookie.secure
+
+Specifies the `boolean` value for the `Secure` `Set-Cookie` attribute. When truthy,
+the `Secure` attribute is set, otherwise it is not. By default, the `Secure`
+attribute is not set.
+
+**Note** be careful when setting this to `true`, as compliant clients will not send
+the cookie back to the server in the future if the browser does not have an HTTPS
+connection.
+
+Please note that `secure: true` is a **recommended** option. However, it requires
+an https-enabled website, i.e., HTTPS is necessary for secure cookies. If `secure`
+is set, and you access your site over HTTP, the cookie will not be set. If you
+have your node.js behind a proxy and are using `secure: true`, you need to set
+"trust proxy" in express:
+
+```js
+var app = express();
+app.set('trust proxy', 1); // trust first proxy
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ cookie: { secure: true },
+ })
+);
+```
+
+For using secure cookies in production, but allowing for testing in development,
+the following is an example of enabling this setup based on `NODE_ENV` in express:
+
+```js
+var app = express();
+var sess = {
+ secret: 'keyboard cat',
+ cookie: {},
+};
+
+if (app.get('env') === 'production') {
+ app.set('trust proxy', 1); // trust first proxy
+ sess.cookie.secure = true; // serve secure cookies
+}
+
+app.use(session(sess));
+```
+
+The `cookie.secure` option can also be set to the special value `'auto'` to have
+this setting automatically match the determined security of the connection. Be
+careful when using this setting if the site is available both as HTTP and HTTPS,
+as once the cookie is set on HTTPS, it will no longer be visible over HTTP. This
+is useful when the Express `"trust proxy"` setting is properly setup to simplify
+development vs production configuration.
+
+##### genid
+
+Function to call to generate a new session ID. Provide a function that returns
+a string that will be used as a session ID. The function is given `req` as the
+first argument if you want to use some value attached to `req` when generating
+the ID.
+
+The default value is a function which uses the `uid-safe` library to generate IDs.
+
+**NOTE** be careful to generate unique IDs so your sessions do not conflict.
+
+```js
+app.use(
+ session({
+ genid: function (req) {
+ return genuuid(); // use UUIDs for session IDs
+ },
+ secret: 'keyboard cat',
+ })
+);
+```
+
+##### name
+
+The name of the session ID cookie to set in the response (and read from in the
+request).
+
+The default value is `'connect.sid'`.
+
+**Note** if you have multiple apps running on the same hostname (this is just
+the name, i.e. `localhost` or `127.0.0.1`; different schemes and ports do not
+name a different hostname), then you need to separate the session cookies from
+each other. The simplest method is to simply set different `name`s per app.
+
+##### proxy
+
+Trust the reverse proxy when setting secure cookies (via the "X-Forwarded-Proto"
+header).
+
+The default value is `undefined`.
+
+- `true` The "X-Forwarded-Proto" header will be used.
+- `false` All headers are ignored and the connection is considered secure only
+ if there is a direct TLS/SSL connection.
+- `undefined` Uses the "trust proxy" setting from express
+
+##### resave
+
+Forces the session to be saved back to the session store, even if the session
+was never modified during the request. Depending on your store this may be
+necessary, but it can also create race conditions where a client makes two
+parallel requests to your server and changes made to the session in one
+request may get overwritten when the other request ends, even if it made no
+changes (this behavior also depends on what store you're using).
+
+The default value is `true`, but using the default has been deprecated,
+as the default will change in the future. Please research into this setting
+and choose what is appropriate to your use-case. Typically, you'll want
+`false`.
+
+How do I know if this is necessary for my store? The best way to know is to
+check with your store if it implements the `touch` method. If it does, then
+you can safely set `resave: false`. If it does not implement the `touch`
+method and your store sets an expiration date on stored sessions, then you
+likely need `resave: true`.
+
+##### rolling
+
+Force the session identifier cookie to be set on every response. The expiration
+is reset to the original [`maxAge`](#cookiemaxage), resetting the expiration
+countdown.
+
+The default value is `false`.
+
+With this enabled, the session identifier cookie will expire in
+[`maxAge`](#cookiemaxage) since the last response was sent instead of in
+[`maxAge`](#cookiemaxage) since the session was last modified by the server.
+
+This is typically used in conjunction with short, non-session-length
+[`maxAge`](#cookiemaxage) values to provide a quick timeout of the session data
+with reduced potential of it occurring during on going server interactions.
+
+**Note** When this option is set to `true` but the `saveUninitialized` option is
+set to `false`, the cookie will not be set on a response with an uninitialized
+session. This option only modifies the behavior when an existing session was
+loaded for the request.
+
+##### saveUninitialized
+
+Forces a session that is "uninitialized" to be saved to the store. A session is
+uninitialized when it is new but not modified. Choosing `false` is useful for
+implementing login sessions, reducing server storage usage, or complying with
+laws that require permission before setting a cookie. Choosing `false` will also
+help with race conditions where a client makes multiple parallel requests
+without a session.
+
+The default value is `true`, but using the default has been deprecated, as the
+default will change in the future. Please research into this setting and
+choose what is appropriate to your use-case.
+
+**Note** if you are using Session in conjunction with PassportJS, Passport
+will add an empty Passport object to the session for use after a user is
+authenticated, which will be treated as a modification to the session, causing
+it to be saved. _This has been fixed in PassportJS 0.3.0_
+
+##### secret
+
+**Required option**
+
+This is the secret used to sign the session ID cookie. The secret can be any type
+of value that is supported by Node.js `crypto.createHmac` (like a string or a
+`Buffer`). This can be either a single secret, or an array of multiple secrets. If
+an array of secrets is provided, only the first element will be used to sign the
+session ID cookie, while all the elements will be considered when verifying the
+signature in requests. The secret itself should be not easily parsed by a human and
+would best be a random set of characters. A best practice may include:
+
+- The use of environment variables to store the secret, ensuring the secret itself
+ does not exist in your repository.
+- Periodic updates of the secret, while ensuring the previous secret is in the
+ array.
+
+Using a secret that cannot be guessed will reduce the ability to hijack a session to
+only guessing the session ID (as determined by the `genid` option).
+
+Changing the secret value will invalidate all existing sessions. In order to rotate
+the secret without invalidating sessions, provide an array of secrets, with the new
+secret as first element of the array, and including previous secrets as the later
+elements.
+
+**Note** HMAC-256 is used to sign the session ID. For this reason, the secret should
+contain at least 32 bytes of entropy.
+
+##### store
+
+The session store instance, defaults to a new `MemoryStore` instance.
+
+##### unset
+
+Control the result of unsetting `req.session` (through `delete`, setting to `null`,
+etc.).
+
+The default value is `'keep'`.
+
+- `'destroy'` The session will be destroyed (deleted) when the response ends.
+- `'keep'` The session in the store will be kept, but modifications made during
+ the request are ignored and not saved.
+
+### req.session
+
+To store or access session data, simply use the request property `req.session`,
+which is (generally) serialized as JSON by the store, so nested objects
+are typically fine. For example below is a user-specific view counter:
+
+```js
+// Use the session middleware
+app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 } }));
+
+// Access the session as req.session
+app.get('/', function (req, res, next) {
+ if (req.session.views) {
+ req.session.views++;
+ res.setHeader('Content-Type', 'text/html');
+ res.write('views: ' + req.session.views + '
');
+ res.write('expires in: ' + req.session.cookie.maxAge / 1000 + 's
');
+ res.end();
+ } else {
+ req.session.views = 1;
+ res.end('welcome to the session demo. refresh!');
+ }
+});
+```
+
+#### Session.regenerate(callback)
+
+To regenerate the session simply invoke the method. Once complete,
+a new SID and `Session` instance will be initialized at `req.session`
+and the `callback` will be invoked.
+
+```js
+req.session.regenerate(function (err) {
+ // will have a new session here
+});
+```
+
+#### Session.destroy(callback)
+
+Destroys the session and will unset the `req.session` property.
+Once complete, the `callback` will be invoked.
+
+```js
+req.session.destroy(function (err) {
+ // cannot access session here
+});
+```
+
+#### Session.reload(callback)
+
+Reloads the session data from the store and re-populates the
+`req.session` object. Once complete, the `callback` will be invoked.
+
+```js
+req.session.reload(function (err) {
+ // session updated
+});
+```
+
+#### Session.save(callback)
+
+Save the session back to the store, replacing the contents on the store with the
+contents in memory (though a store may do something else--consult the store's
+documentation for exact behavior).
+
+This method is automatically called at the end of the HTTP response if the
+session data has been altered (though this behavior can be altered with various
+options in the middleware constructor). Because of this, typically this method
+does not need to be called.
+
+There are some cases where it is useful to call this method, for example,
+redirects, long-lived requests or in WebSockets.
+
+```js
+req.session.save(function (err) {
+ // session saved
+});
+```
+
+#### Session.touch()
+
+Updates the `.maxAge` property. Typically this is
+not necessary to call, as the session middleware does this for you.
+
+### req.session.id
+
+Each session has a unique ID associated with it. This property is an
+alias of [`req.sessionID`](#reqsessionid-1) and cannot be modified.
+It has been added to make the session ID accessible from the `session`
+object.
+
+### req.session.cookie
+
+Each session has a unique cookie object accompany it. This allows
+you to alter the session cookie per visitor. For example we can
+set `req.session.cookie.expires` to `false` to enable the cookie
+to remain for only the duration of the user-agent.
+
+#### Cookie.maxAge
+
+Alternatively `req.session.cookie.maxAge` will return the time
+remaining in milliseconds, which we may also re-assign a new value
+to adjust the `.expires` property appropriately. The following
+are essentially equivalent
+
+```js
+var hour = 3600000;
+req.session.cookie.expires = new Date(Date.now() + hour);
+req.session.cookie.maxAge = hour;
+```
+
+For example when `maxAge` is set to `60000` (one minute), and 30 seconds
+has elapsed it will return `30000` until the current request has completed,
+at which time `req.session.touch()` is called to reset
+`req.session.cookie.maxAge` to its original value.
+
+```js
+req.session.cookie.maxAge; // => 30000
+```
+
+#### Cookie.originalMaxAge
+
+The `req.session.cookie.originalMaxAge` property returns the original
+`maxAge` (time-to-live), in milliseconds, of the session cookie.
+
+### req.sessionID
+
+To get the ID of the loaded session, access the request property
+`req.sessionID`. This is simply a read-only value set when a session
+is loaded/created.
+
+## Session Store Implementation
+
+Every session store _must_ be an `EventEmitter` and implement specific
+methods. The following methods are the list of **required**, **recommended**,
+and **optional**.
+
+- Required methods are ones that this module will always call on the store.
+- Recommended methods are ones that this module will call on the store if
+ available.
+- Optional methods are ones this module does not call at all, but helps
+ present uniform stores to users.
+
+For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo.
+
+### store.all(callback)
+
+**Optional**
+
+This optional method is used to get all sessions in the store as an array. The
+`callback` should be called as `callback(error, sessions)`.
+
+### store.destroy(sid, callback)
+
+**Required**
+
+This required method is used to destroy/delete a session from the store given
+a session ID (`sid`). The `callback` should be called as `callback(error)` once
+the session is destroyed.
+
+### store.clear(callback)
+
+**Optional**
+
+This optional method is used to delete all sessions from the store. The
+`callback` should be called as `callback(error)` once the store is cleared.
+
+### store.length(callback)
+
+**Optional**
+
+This optional method is used to get the count of all sessions in the store.
+The `callback` should be called as `callback(error, len)`.
+
+### store.get(sid, callback)
+
+**Required**
+
+This required method is used to get a session from the store given a session
+ID (`sid`). The `callback` should be called as `callback(error, session)`.
+
+The `session` argument should be a session if found, otherwise `null` or
+`undefined` if the session was not found (and there was no error). A special
+case is made when `error.code === 'ENOENT'` to act like `callback(null, null)`.
+
+### store.set(sid, session, callback)
+
+**Required**
+
+This required method is used to upsert a session into the store given a
+session ID (`sid`) and session (`session`) object. The callback should be
+called as `callback(error)` once the session has been set in the store.
+
+### store.touch(sid, session, callback)
+
+**Recommended**
+
+This recommended method is used to "touch" a given session given a
+session ID (`sid`) and session (`session`) object. The `callback` should be
+called as `callback(error)` once the session has been touched.
+
+This is primarily used when the store will automatically delete idle sessions
+and this method is used to signal to the store the given session is active,
+potentially resetting the idle timer.
+
+## Compatible Session Stores
+
+The following modules implement a session store that is compatible with this
+module. Please make a PR to add additional modules :)
+
+[![★][aerospike-session-store-image] aerospike-session-store][aerospike-session-store-url] A session store using [Aerospike](http://www.aerospike.com/).
+
+[aerospike-session-store-url]: https://www.npmjs.com/package/aerospike-session-store
+[aerospike-session-store-image]: https://badgen.net/github/stars/aerospike/aerospike-session-store-expressjs?label=%E2%98%85
+
+[![★][better-sqlite3-session-store-image] better-sqlite3-session-store][better-sqlite3-session-store-url] A session store based on [better-sqlite3](https://github.com/JoshuaWise/better-sqlite3).
+
+[better-sqlite3-session-store-url]: https://www.npmjs.com/package/better-sqlite3-session-store
+[better-sqlite3-session-store-image]: https://badgen.net/github/stars/timdaub/better-sqlite3-session-store?label=%E2%98%85
+
+[![★][cassandra-store-image] cassandra-store][cassandra-store-url] An Apache Cassandra-based session store.
+
+[cassandra-store-url]: https://www.npmjs.com/package/cassandra-store
+[cassandra-store-image]: https://badgen.net/github/stars/webcc/cassandra-store?label=%E2%98%85
+
+[![★][cluster-store-image] cluster-store][cluster-store-url] A wrapper for using in-process / embedded
+stores - such as SQLite (via knex), leveldb, files, or memory - with node cluster (desirable for Raspberry Pi 2
+and other multi-core embedded devices).
+
+[cluster-store-url]: https://www.npmjs.com/package/cluster-store
+[cluster-store-image]: https://badgen.net/github/stars/coolaj86/cluster-store?label=%E2%98%85
+
+[![★][connect-arango-image] connect-arango][connect-arango-url] An ArangoDB-based session store.
+
+[connect-arango-url]: https://www.npmjs.com/package/connect-arango
+[connect-arango-image]: https://badgen.net/github/stars/AlexanderArvidsson/connect-arango?label=%E2%98%85
+
+[![★][connect-azuretables-image] connect-azuretables][connect-azuretables-url] An [Azure Table Storage](https://azure.microsoft.com/en-gb/services/storage/tables/)-based session store.
+
+[connect-azuretables-url]: https://www.npmjs.com/package/connect-azuretables
+[connect-azuretables-image]: https://badgen.net/github/stars/mike-goodwin/connect-azuretables?label=%E2%98%85
+
+[![★][connect-cloudant-store-image] connect-cloudant-store][connect-cloudant-store-url] An [IBM Cloudant](https://cloudant.com/)-based session store.
+
+[connect-cloudant-store-url]: https://www.npmjs.com/package/connect-cloudant-store
+[connect-cloudant-store-image]: https://badgen.net/github/stars/adriantanasa/connect-cloudant-store?label=%E2%98%85
+
+[![★][connect-cosmosdb-image] connect-cosmosdb][connect-cosmosdb-url] An Azure [Cosmos DB](https://azure.microsoft.com/en-us/products/cosmos-db/)-based session store.
+
+[connect-cosmosdb-url]: https://www.npmjs.com/package/connect-cosmosdb
+[connect-cosmosdb-image]: https://badgen.net/github/stars/thekillingspree/connect-cosmosdb?label=%E2%98%85
+
+[![★][connect-couchbase-image] connect-couchbase][connect-couchbase-url] A [couchbase](http://www.couchbase.com/)-based session store.
+
+[connect-couchbase-url]: https://www.npmjs.com/package/connect-couchbase
+[connect-couchbase-image]: https://badgen.net/github/stars/christophermina/connect-couchbase?label=%E2%98%85
+
+[![★][connect-datacache-image] connect-datacache][connect-datacache-url] An [IBM Bluemix Data Cache](http://www.ibm.com/cloud-computing/bluemix/)-based session store.
+
+[connect-datacache-url]: https://www.npmjs.com/package/connect-datacache
+[connect-datacache-image]: https://badgen.net/github/stars/adriantanasa/connect-datacache?label=%E2%98%85
+
+[![★][@google-cloud/connect-datastore-image] @google-cloud/connect-datastore][@google-cloud/connect-datastore-url] A [Google Cloud Datastore](https://cloud.google.com/datastore/docs/concepts/overview)-based session store.
+
+[@google-cloud/connect-datastore-url]: https://www.npmjs.com/package/@google-cloud/connect-datastore
+[@google-cloud/connect-datastore-image]: https://badgen.net/github/stars/GoogleCloudPlatform/cloud-datastore-session-node?label=%E2%98%85
+
+[![★][connect-db2-image] connect-db2][connect-db2-url] An IBM DB2-based session store built using [ibm_db](https://www.npmjs.com/package/ibm_db) module.
+
+[connect-db2-url]: https://www.npmjs.com/package/connect-db2
+[connect-db2-image]: https://badgen.net/github/stars/wallali/connect-db2?label=%E2%98%85
+
+[![★][connect-dynamodb-image] connect-dynamodb][connect-dynamodb-url] A DynamoDB-based session store.
+
+[connect-dynamodb-url]: https://www.npmjs.com/package/connect-dynamodb
+[connect-dynamodb-image]: https://badgen.net/github/stars/ca98am79/connect-dynamodb?label=%E2%98%85
+
+[![★][@google-cloud/connect-firestore-image] @google-cloud/connect-firestore][@google-cloud/connect-firestore-url] A [Google Cloud Firestore](https://cloud.google.com/firestore/docs/overview)-based session store.
+
+[@google-cloud/connect-firestore-url]: https://www.npmjs.com/package/@google-cloud/connect-firestore
+[@google-cloud/connect-firestore-image]: https://badgen.net/github/stars/googleapis/nodejs-firestore-session?label=%E2%98%85
+
+[![★][connect-hazelcast-image] connect-hazelcast][connect-hazelcast-url] Hazelcast session store for Connect and Express.
+
+[connect-hazelcast-url]: https://www.npmjs.com/package/connect-hazelcast
+[connect-hazelcast-image]: https://badgen.net/github/stars/huseyinbabal/connect-hazelcast?label=%E2%98%85
+
+[![★][connect-loki-image] connect-loki][connect-loki-url] A Loki.js-based session store.
+
+[connect-loki-url]: https://www.npmjs.com/package/connect-loki
+[connect-loki-image]: https://badgen.net/github/stars/Requarks/connect-loki?label=%E2%98%85
+
+[![★][connect-lowdb-image] connect-lowdb][connect-lowdb-url] A lowdb-based session store.
+
+[connect-lowdb-url]: https://www.npmjs.com/package/connect-lowdb
+[connect-lowdb-image]: https://badgen.net/github/stars/travishorn/connect-lowdb?label=%E2%98%85
+
+[![★][connect-memcached-image] connect-memcached][connect-memcached-url] A memcached-based session store.
+
+[connect-memcached-url]: https://www.npmjs.com/package/connect-memcached
+[connect-memcached-image]: https://badgen.net/github/stars/balor/connect-memcached?label=%E2%98%85
+
+[![★][connect-memjs-image] connect-memjs][connect-memjs-url] A memcached-based session store using
+[memjs](https://www.npmjs.com/package/memjs) as the memcached client.
+
+[connect-memjs-url]: https://www.npmjs.com/package/connect-memjs
+[connect-memjs-image]: https://badgen.net/github/stars/liamdon/connect-memjs?label=%E2%98%85
+
+[![★][connect-ml-image] connect-ml][connect-ml-url] A MarkLogic Server-based session store.
+
+[connect-ml-url]: https://www.npmjs.com/package/connect-ml
+[connect-ml-image]: https://badgen.net/github/stars/bluetorch/connect-ml?label=%E2%98%85
+
+[![★][connect-monetdb-image] connect-monetdb][connect-monetdb-url] A MonetDB-based session store.
+
+[connect-monetdb-url]: https://www.npmjs.com/package/connect-monetdb
+[connect-monetdb-image]: https://badgen.net/github/stars/MonetDB/npm-connect-monetdb?label=%E2%98%85
+
+[![★][connect-mongo-image] connect-mongo][connect-mongo-url] A MongoDB-based session store.
+
+[connect-mongo-url]: https://www.npmjs.com/package/connect-mongo
+[connect-mongo-image]: https://badgen.net/github/stars/kcbanner/connect-mongo?label=%E2%98%85
+
+[![★][connect-mongodb-session-image] connect-mongodb-session][connect-mongodb-session-url] Lightweight MongoDB-based session store built and maintained by MongoDB.
+
+[connect-mongodb-session-url]: https://www.npmjs.com/package/connect-mongodb-session
+[connect-mongodb-session-image]: https://badgen.net/github/stars/mongodb-js/connect-mongodb-session?label=%E2%98%85
+
+[![★][connect-mssql-v2-image] connect-mssql-v2][connect-mssql-v2-url] A Microsoft SQL Server-based session store based on [connect-mssql](https://www.npmjs.com/package/connect-mssql).
+
+[connect-mssql-v2-url]: https://www.npmjs.com/package/connect-mssql-v2
+[connect-mssql-v2-image]: https://badgen.net/github/stars/jluboff/connect-mssql-v2?label=%E2%98%85
+
+[![★][connect-neo4j-image] connect-neo4j][connect-neo4j-url] A [Neo4j](https://neo4j.com)-based session store.
+
+[connect-neo4j-url]: https://www.npmjs.com/package/connect-neo4j
+[connect-neo4j-image]: https://badgen.net/github/stars/MaxAndersson/connect-neo4j?label=%E2%98%85
+
+[![★][connect-ottoman-image] connect-ottoman][connect-ottoman-url] A [couchbase ottoman](http://www.couchbase.com/)-based session store.
+
+[connect-ottoman-url]: https://www.npmjs.com/package/connect-ottoman
+[connect-ottoman-image]: https://badgen.net/github/stars/noiissyboy/connect-ottoman?label=%E2%98%85
+
+[![★][connect-pg-simple-image] connect-pg-simple][connect-pg-simple-url] A PostgreSQL-based session store.
+
+[connect-pg-simple-url]: https://www.npmjs.com/package/connect-pg-simple
+[connect-pg-simple-image]: https://badgen.net/github/stars/voxpelli/node-connect-pg-simple?label=%E2%98%85
+
+[![★][connect-redis-image] connect-redis][connect-redis-url] A Redis-based session store.
+
+[connect-redis-url]: https://www.npmjs.com/package/connect-redis
+[connect-redis-image]: https://badgen.net/github/stars/tj/connect-redis?label=%E2%98%85
+
+[![★][connect-session-firebase-image] connect-session-firebase][connect-session-firebase-url] A session store based on the [Firebase Realtime Database](https://firebase.google.com/docs/database/)
+
+[connect-session-firebase-url]: https://www.npmjs.com/package/connect-session-firebase
+[connect-session-firebase-image]: https://badgen.net/github/stars/benweier/connect-session-firebase?label=%E2%98%85
+
+[![★][connect-session-knex-image] connect-session-knex][connect-session-knex-url] A session store using
+[Knex.js](http://knexjs.org/), which is a SQL query builder for PostgreSQL, MySQL, MariaDB, SQLite3, and Oracle.
+
+[connect-session-knex-url]: https://www.npmjs.com/package/connect-session-knex
+[connect-session-knex-image]: https://badgen.net/github/stars/llambda/connect-session-knex?label=%E2%98%85
+
+[![★][connect-session-sequelize-image] connect-session-sequelize][connect-session-sequelize-url] A session store using
+[Sequelize.js](http://sequelizejs.com/), which is a Node.js / io.js ORM for PostgreSQL, MySQL, SQLite and MSSQL.
+
+[connect-session-sequelize-url]: https://www.npmjs.com/package/connect-session-sequelize
+[connect-session-sequelize-image]: https://badgen.net/github/stars/mweibel/connect-session-sequelize?label=%E2%98%85
+
+[![★][connect-sqlite3-image] connect-sqlite3][connect-sqlite3-url] A [SQLite3](https://github.com/mapbox/node-sqlite3) session store modeled after the TJ's `connect-redis` store.
+
+[connect-sqlite3-url]: https://www.npmjs.com/package/connect-sqlite3
+[connect-sqlite3-image]: https://badgen.net/github/stars/rawberg/connect-sqlite3?label=%E2%98%85
+
+[![★][connect-typeorm-image] connect-typeorm][connect-typeorm-url] A [TypeORM](https://github.com/typeorm/typeorm)-based session store.
+
+[connect-typeorm-url]: https://www.npmjs.com/package/connect-typeorm
+[connect-typeorm-image]: https://badgen.net/github/stars/makepost/connect-typeorm?label=%E2%98%85
+
+[![★][couchdb-expression-image] couchdb-expression][couchdb-expression-url] A [CouchDB](https://couchdb.apache.org/)-based session store.
+
+[couchdb-expression-url]: https://www.npmjs.com/package/couchdb-expression
+[couchdb-expression-image]: https://badgen.net/github/stars/tkshnwesper/couchdb-expression?label=%E2%98%85
+
+[![★][dynamodb-store-image] dynamodb-store][dynamodb-store-url] A DynamoDB-based session store.
+
+[dynamodb-store-url]: https://www.npmjs.com/package/dynamodb-store
+[dynamodb-store-image]: https://badgen.net/github/stars/rafaelrpinto/dynamodb-store?label=%E2%98%85
+
+[![★][dynamodb-store-v3-image] dynamodb-store-v3][dynamodb-store-v3-url] Implementation of a session store using DynamoDB backed by the [AWS SDK for JavaScript v3](https://github.com/aws/aws-sdk-js-v3).
+
+[dynamodb-store-v3-url]: https://www.npmjs.com/package/dynamodb-store-v3
+[dynamodb-store-v3-image]: https://badgen.net/github/stars/FryDay/dynamodb-store-v3?label=%E2%98%85
+
+[![★][express-etcd-image] express-etcd][express-etcd-url] An [etcd](https://github.com/stianeikeland/node-etcd) based session store.
+
+[express-etcd-url]: https://www.npmjs.com/package/express-etcd
+[express-etcd-image]: https://badgen.net/github/stars/gildean/express-etcd?label=%E2%98%85
+
+[![★][express-mysql-session-image] express-mysql-session][express-mysql-session-url] A session store using native
+[MySQL](https://www.mysql.com/) via the [node-mysql](https://github.com/felixge/node-mysql) module.
+
+[express-mysql-session-url]: https://www.npmjs.com/package/express-mysql-session
+[express-mysql-session-image]: https://badgen.net/github/stars/chill117/express-mysql-session?label=%E2%98%85
+
+[![★][express-nedb-session-image] express-nedb-session][express-nedb-session-url] A NeDB-based session store.
+
+[express-nedb-session-url]: https://www.npmjs.com/package/express-nedb-session
+[express-nedb-session-image]: https://badgen.net/github/stars/louischatriot/express-nedb-session?label=%E2%98%85
+
+[![★][express-oracle-session-image] express-oracle-session][express-oracle-session-url] A session store using native
+[oracle](https://www.oracle.com/) via the [node-oracledb](https://www.npmjs.com/package/oracledb) module.
+
+[express-oracle-session-url]: https://www.npmjs.com/package/express-oracle-session
+[express-oracle-session-image]: https://badgen.net/github/stars/slumber86/express-oracle-session?label=%E2%98%85
+
+[![★][express-session-cache-manager-image] express-session-cache-manager][express-session-cache-manager-url]
+A store that implements [cache-manager](https://www.npmjs.com/package/cache-manager), which supports
+a [variety of storage types](https://www.npmjs.com/package/cache-manager#store-engines).
+
+[express-session-cache-manager-url]: https://www.npmjs.com/package/express-session-cache-manager
+[express-session-cache-manager-image]: https://badgen.net/github/stars/theogravity/express-session-cache-manager?label=%E2%98%85
+
+[![★][express-session-etcd3-image] express-session-etcd3][express-session-etcd3-url] An [etcd3](https://github.com/mixer/etcd3) based session store.
+
+[express-session-etcd3-url]: https://www.npmjs.com/package/express-session-etcd3
+[express-session-etcd3-image]: https://badgen.net/github/stars/willgm/express-session-etcd3?label=%E2%98%85
+
+[![★][express-session-level-image] express-session-level][express-session-level-url] A [LevelDB](https://github.com/Level/levelup) based session store.
+
+[express-session-level-url]: https://www.npmjs.com/package/express-session-level
+[express-session-level-image]: https://badgen.net/github/stars/tgohn/express-session-level?label=%E2%98%85
+
+[![★][express-session-rsdb-image] express-session-rsdb][express-session-rsdb-url] Session store based on Rocket-Store: A very simple, super fast and yet powerful, flat file database.
+
+[express-session-rsdb-url]: https://www.npmjs.com/package/express-session-rsdb
+[express-session-rsdb-image]: https://badgen.net/github/stars/paragi/express-session-rsdb?label=%E2%98%85
+
+[![★][express-sessions-image] express-sessions][express-sessions-url] A session store supporting both MongoDB and Redis.
+
+[express-sessions-url]: https://www.npmjs.com/package/express-sessions
+[express-sessions-image]: https://badgen.net/github/stars/konteck/express-sessions?label=%E2%98%85
+
+[![★][firestore-store-image] firestore-store][firestore-store-url] A [Firestore](https://github.com/hendrysadrak/firestore-store)-based session store.
+
+[firestore-store-url]: https://www.npmjs.com/package/firestore-store
+[firestore-store-image]: https://badgen.net/github/stars/hendrysadrak/firestore-store?label=%E2%98%85
+
+[![★][fortune-session-image] fortune-session][fortune-session-url] A [Fortune.js](https://github.com/fortunejs/fortune)
+based session store. Supports all backends supported by Fortune (MongoDB, Redis, Postgres, NeDB).
+
+[fortune-session-url]: https://www.npmjs.com/package/fortune-session
+[fortune-session-image]: https://badgen.net/github/stars/aliceklipper/fortune-session?label=%E2%98%85
+
+[![★][hazelcast-store-image] hazelcast-store][hazelcast-store-url] A Hazelcast-based session store built on the [Hazelcast Node Client](https://www.npmjs.com/package/hazelcast-client).
+
+[hazelcast-store-url]: https://www.npmjs.com/package/hazelcast-store
+[hazelcast-store-image]: https://badgen.net/github/stars/jackspaniel/hazelcast-store?label=%E2%98%85
+
+[![★][level-session-store-image] level-session-store][level-session-store-url] A LevelDB-based session store.
+
+[level-session-store-url]: https://www.npmjs.com/package/level-session-store
+[level-session-store-image]: https://badgen.net/github/stars/toddself/level-session-store?label=%E2%98%85
+
+[![★][lowdb-session-store-image] lowdb-session-store][lowdb-session-store-url] A [lowdb](https://www.npmjs.com/package/lowdb)-based session store.
+
+[lowdb-session-store-url]: https://www.npmjs.com/package/lowdb-session-store
+[lowdb-session-store-image]: https://badgen.net/github/stars/fhellwig/lowdb-session-store?label=%E2%98%85
+
+[![★][medea-session-store-image] medea-session-store][medea-session-store-url] A Medea-based session store.
+
+[medea-session-store-url]: https://www.npmjs.com/package/medea-session-store
+[medea-session-store-image]: https://badgen.net/github/stars/BenjaminVadant/medea-session-store?label=%E2%98%85
+
+[![★][memorystore-image] memorystore][memorystore-url] A memory session store made for production.
+
+[memorystore-url]: https://www.npmjs.com/package/memorystore
+[memorystore-image]: https://badgen.net/github/stars/roccomuso/memorystore?label=%E2%98%85
+
+[![★][mssql-session-store-image] mssql-session-store][mssql-session-store-url] A SQL Server-based session store.
+
+[mssql-session-store-url]: https://www.npmjs.com/package/mssql-session-store
+[mssql-session-store-image]: https://badgen.net/github/stars/jwathen/mssql-session-store?label=%E2%98%85
+
+[![★][nedb-session-store-image] nedb-session-store][nedb-session-store-url] An alternate NeDB-based (either in-memory or file-persisted) session store.
+
+[nedb-session-store-url]: https://www.npmjs.com/package/nedb-session-store
+[nedb-session-store-image]: https://badgen.net/github/stars/JamesMGreene/nedb-session-store?label=%E2%98%85
+
+[![★][@quixo3/prisma-session-store-image] @quixo3/prisma-session-store][@quixo3/prisma-session-store-url] A session store for the [Prisma Framework](https://www.prisma.io).
+
+[@quixo3/prisma-session-store-url]: https://www.npmjs.com/package/@quixo3/prisma-session-store
+[@quixo3/prisma-session-store-image]: https://badgen.net/github/stars/kleydon/prisma-session-store?label=%E2%98%85
+
+[![★][restsession-image] restsession][restsession-url] Store sessions utilizing a RESTful API
+
+[restsession-url]: https://www.npmjs.com/package/restsession
+[restsession-image]: https://badgen.net/github/stars/jankal/restsession?label=%E2%98%85
+
+[![★][sequelstore-connect-image] sequelstore-connect][sequelstore-connect-url] A session store using [Sequelize.js](http://sequelizejs.com/).
+
+[sequelstore-connect-url]: https://www.npmjs.com/package/sequelstore-connect
+[sequelstore-connect-image]: https://badgen.net/github/stars/MattMcFarland/sequelstore-connect?label=%E2%98%85
+
+[![★][session-file-store-image] session-file-store][session-file-store-url] A file system-based session store.
+
+[session-file-store-url]: https://www.npmjs.com/package/session-file-store
+[session-file-store-image]: https://badgen.net/github/stars/valery-barysok/session-file-store?label=%E2%98%85
+
+[![★][session-pouchdb-store-image] session-pouchdb-store][session-pouchdb-store-url] Session store for PouchDB / CouchDB. Accepts embedded, custom, or remote PouchDB instance and realtime synchronization.
+
+[session-pouchdb-store-url]: https://www.npmjs.com/package/session-pouchdb-store
+[session-pouchdb-store-image]: https://badgen.net/github/stars/solzimer/session-pouchdb-store?label=%E2%98%85
+
+[![★][@cyclic.sh/session-store-image] @cyclic.sh/session-store][@cyclic.sh/session-store-url] A DynamoDB-based session store for [Cyclic.sh](https://www.cyclic.sh/) apps.
+
+[@cyclic.sh/session-store-url]: https://www.npmjs.com/package/@cyclic.sh/session-store
+[@cyclic.sh/session-store-image]: https://badgen.net/github/stars/cyclic-software/session-store?label=%E2%98%85
+
+[![★][@databunker/session-store-image] @databunker/session-store][@databunker/session-store-url] A [Databunker](https://databunker.org/)-based encrypted session store.
+
+[@databunker/session-store-url]: https://www.npmjs.com/package/@databunker/session-store
+[@databunker/session-store-image]: https://badgen.net/github/stars/securitybunker/databunker-session-store?label=%E2%98%85
+
+[![★][sessionstore-image] sessionstore][sessionstore-url] A session store that works with various databases.
+
+[sessionstore-url]: https://www.npmjs.com/package/sessionstore
+[sessionstore-image]: https://badgen.net/github/stars/adrai/sessionstore?label=%E2%98%85
+
+[![★][tch-nedb-session-image] tch-nedb-session][tch-nedb-session-url] A file system session store based on NeDB.
+
+[tch-nedb-session-url]: https://www.npmjs.com/package/tch-nedb-session
+[tch-nedb-session-image]: https://badgen.net/github/stars/tomaschyly/NeDBSession?label=%E2%98%85
+
+## Examples
+
+### View counter
+
+A simple example using `express-session` to store page views for a user.
+
+```js
+var express = require('express');
+var parseurl = require('parseurl');
+var session = require('express-session');
+
+var app = express();
+
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ })
+);
+
+app.use(function (req, res, next) {
+ if (!req.session.views) {
+ req.session.views = {};
+ }
+
+ // get the url pathname
+ var pathname = parseurl(req).pathname;
+
+ // count the views
+ req.session.views[pathname] = (req.session.views[pathname] || 0) + 1;
+
+ next();
+});
+
+app.get('/foo', function (req, res, next) {
+ res.send('you viewed this page ' + req.session.views['/foo'] + ' times');
+});
+
+app.get('/bar', function (req, res, next) {
+ res.send('you viewed this page ' + req.session.views['/bar'] + ' times');
+});
+
+app.listen(3000);
+```
+
+### User login
+
+A simple example using `express-session` to keep a user log in session.
+
+```js
+var escapeHtml = require('escape-html');
+var express = require('express');
+var session = require('express-session');
+
+var app = express();
+
+app.use(
+ session({
+ secret: 'keyboard cat',
+ resave: false,
+ saveUninitialized: true,
+ })
+);
+
+// middleware to test if authenticated
+function isAuthenticated(req, res, next) {
+ if (req.session.user) next();
+ else next('route');
+}
+
+app.get('/', isAuthenticated, function (req, res) {
+ // this is only called when there is an authentication user due to isAuthenticated
+ res.send('hello, ' + escapeHtml(req.session.user) + '!' + ' Logout ');
+});
+
+app.get('/', function (req, res) {
+ res.send(
+ ''
+ );
+});
+
+app.post('/login', express.urlencoded({ extended: false }), function (req, res) {
+ // login logic to validate req.body.user and req.body.pass
+ // would be implemented here. for this example any combo works
+
+ // regenerate the session, which is good practice to help
+ // guard against forms of session fixation
+ req.session.regenerate(function (err) {
+ if (err) next(err);
+
+ // store user information in session, typically a user id
+ req.session.user = req.body.user;
+
+ // save the session before redirection to ensure page
+ // load does not happen before session is saved
+ req.session.save(function (err) {
+ if (err) return next(err);
+ res.redirect('/');
+ });
+ });
+});
+
+app.get('/logout', function (req, res, next) {
+ // logout logic
+
+ // clear the user from the session object and save.
+ // this will ensure that re-using the old session id
+ // does not have a logged in user
+ req.session.user = null;
+ req.session.save(function (err) {
+ if (err) next(err);
+
+ // regenerate the session, which is good practice to help
+ // guard against forms of session fixation
+ req.session.regenerate(function (err) {
+ if (err) next(err);
+ res.redirect('/');
+ });
+ });
+});
+
+app.listen(3000);
+```
+
+## Debugging
+
+This module uses the [debug](https://www.npmjs.com/package/debug) module
+internally to log information about session operations.
+
+To see all the internal logs, set the `DEBUG` environment variable to
+`express-session` when launching your app (`npm start`, in this example):
+
+```sh
+$ DEBUG=express-session npm start
+```
+
+On Windows, use the corresponding command;
+
+```sh
+> set DEBUG=express-session & npm start
+```
+
+## License
+
+[MIT](LICENSE)
+
+[rfc-6265bis-03-4.1.2.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7
+[rfc-cutler-httpbis-partitioned-cookies]: https://tools.ietf.org/html/draft-cutler-httpbis-partitioned-cookies/
+[rfc-west-cookie-priority-00-4.1]: https://tools.ietf.org/html/draft-west-cookie-priority-00#section-4.1
+[ci-image]: https://badgen.net/github/checks/expressjs/session/master?label=ci
+[ci-url]: https://github.com/expressjs/session/actions?query=workflow%3Aci
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/session/master
+[coveralls-url]: https://coveralls.io/r/expressjs/session?branch=master
+[node-url]: https://nodejs.org/en/download
+[npm-downloads-image]: https://badgen.net/npm/dm/express-session
+[npm-url]: https://npmjs.org/package/express-session
+[npm-version-image]: https://badgen.net/npm/v/express-session
diff --git a/astro/src/content/resources/zh-tw/middleware/timeout.md b/astro/src/content/resources/zh-tw/middleware/timeout.md
new file mode 100644
index 0000000000..f6057aedfd
--- /dev/null
+++ b/astro/src/content/resources/zh-tw/middleware/timeout.md
@@ -0,0 +1,176 @@
+---
+title: Express timeout middleware
+module: timeout
+---
+
+# connect-timeout
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][travis-image]][travis-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Times out a request in the Connect/Express application framework.
+
+## Install
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install connect-timeout
+```
+
+## API
+
+**NOTE** This module is not recommend as a "top-level" middleware (i.e.
+`app.use(timeout('5s'))`) unless you take precautions to halt your own
+middleware processing. See [as top-level middleware](#as-top-level-middleware)
+for how to use as a top-level middleware.
+
+While the library will emit a 'timeout' event when requests exceed the given
+timeout, node will continue processing the slow request until it terminates.
+Slow requests will continue to use CPU and memory, even if you are returning
+a HTTP response in the timeout callback. For better control over CPU/memory,
+you may need to find the events that are taking a long time (3rd party HTTP
+requests, disk I/O, database calls) and find a way to cancel them, and/or
+close the attached sockets.
+
+### timeout(time, [options])
+
+Returns middleware that times out in `time` milliseconds. `time` can also
+be a string accepted by the [ms](https://www.npmjs.org/package/ms#readme)
+module. On timeout, `req` will emit `"timeout"`.
+
+#### Options
+
+The `timeout` function takes an optional `options` object that may contain
+any of the following keys:
+
+##### respond
+
+Controls if this module will "respond" in the form of forwarding an error.
+If `true`, the timeout error is passed to `next()` so that you may customize
+the response behavior. This error has a `.timeout` property as well as
+`.status == 503`. This defaults to `true`.
+
+### req.clearTimeout()
+
+Clears the timeout on the request. The timeout is completely removed and
+will not fire for this request in the future.
+
+### req.timedout
+
+`true` if timeout fired; `false` otherwise.
+
+## Examples
+
+### as top-level middleware
+
+Because of the way middleware processing works, once this module
+passes the request to the next middleware (which it has to do in order
+for you to do work), it can no longer stop the flow, so you must take
+care to check if the request has timedout before you continue to act
+on the request.
+
+```javascript
+var bodyParser = require('body-parser');
+var cookieParser = require('cookie-parser');
+var express = require('express');
+var timeout = require('connect-timeout');
+
+// example of using this top-level; note the use of haltOnTimedout
+// after every middleware; it will stop the request flow on a timeout
+var app = express();
+app.use(timeout('5s'));
+app.use(bodyParser());
+app.use(haltOnTimedout);
+app.use(cookieParser());
+app.use(haltOnTimedout);
+
+// Add your routes here, etc.
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+app.listen(3000);
+```
+
+### express 3.x
+
+```javascript
+var express = require('express');
+var bodyParser = require('body-parser');
+var timeout = require('connect-timeout');
+
+var app = express();
+app.post('/save', timeout('5s'), bodyParser.json(), haltOnTimedout, function (req, res, next) {
+ savePost(req.body, function (err, id) {
+ if (err) return next(err);
+ if (req.timedout) return;
+ res.send('saved as id ' + id);
+ });
+});
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+function savePost(post, cb) {
+ setTimeout(
+ function () {
+ cb(null, (Math.random() * 40000) >>> 0);
+ },
+ (Math.random() * 7000) >>> 0
+ );
+}
+
+app.listen(3000);
+```
+
+### connect
+
+```javascript
+var bodyParser = require('body-parser');
+var connect = require('connect');
+var timeout = require('connect-timeout');
+
+var app = connect();
+app.use('/save', timeout('5s'), bodyParser.json(), haltOnTimedout, function (req, res, next) {
+ savePost(req.body, function (err, id) {
+ if (err) return next(err);
+ if (req.timedout) return;
+ res.send('saved as id ' + id);
+ });
+});
+
+function haltOnTimedout(req, res, next) {
+ if (!req.timedout) next();
+}
+
+function savePost(post, cb) {
+ setTimeout(
+ function () {
+ cb(null, (Math.random() * 40000) >>> 0);
+ },
+ (Math.random() * 7000) >>> 0
+ );
+}
+
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/connect-timeout.svg
+[npm-url]: https://npmjs.org/package/connect-timeout
+[travis-image]: https://img.shields.io/travis/expressjs/timeout/master.svg
+[travis-url]: https://travis-ci.org/expressjs/timeout
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/timeout/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/timeout?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/connect-timeout.svg
+[downloads-url]: https://npmjs.org/package/connect-timeout
diff --git a/astro/src/content/resources/zh-tw/middleware/vhost.md b/astro/src/content/resources/zh-tw/middleware/vhost.md
new file mode 100644
index 0000000000..72f49d7f93
--- /dev/null
+++ b/astro/src/content/resources/zh-tw/middleware/vhost.md
@@ -0,0 +1,174 @@
+---
+title: Express vhost middleware
+module: vhost
+---
+
+# vhost
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Install
+
+```sh
+$ npm install vhost
+```
+
+## API
+
+```js
+var vhost = require('vhost');
+```
+
+### vhost(hostname, handle)
+
+Create a new middleware function to hand off request to `handle` when the incoming
+host for the request matches `hostname`. The function is called as
+`handle(req, res, next)`, like a standard middleware.
+
+`hostname` can be a string or a RegExp object. When `hostname` is a string it can
+contain `*` to match 1 or more characters in that section of the hostname. When
+`hostname` is a RegExp, it will be forced to case-insensitive (since hostnames are)
+and will be forced to match based on the start and end of the hostname.
+
+When host is matched and the request is sent down to a vhost handler, the `req.vhost`
+property will be populated with an object. This object will have numeric properties
+corresponding to each wildcard (or capture group if RegExp object provided) and the
+`hostname` that was matched.
+
+```js
+var connect = require('connect');
+var vhost = require('vhost');
+var app = connect();
+
+app.use(
+ vhost('*.*.example.com', function handle(req, res, next) {
+ // for match of "foo.bar.example.com:8080" against "*.*.example.com":
+ console.dir(req.vhost.host); // => 'foo.bar.example.com:8080'
+ console.dir(req.vhost.hostname); // => 'foo.bar.example.com'
+ console.dir(req.vhost.length); // => 2
+ console.dir(req.vhost[0]); // => 'foo'
+ console.dir(req.vhost[1]); // => 'bar'
+ })
+);
+```
+
+## Examples
+
+### using with connect for static serving
+
+```js
+var connect = require('connect');
+var serveStatic = require('serve-static');
+var vhost = require('vhost');
+
+var mailapp = connect();
+
+// add middlewares to mailapp for mail.example.com
+
+// create app to serve static files on subdomain
+var staticapp = connect();
+staticapp.use(serveStatic('public'));
+
+// create main app
+var app = connect();
+
+// add vhost routing to main app for mail
+app.use(vhost('mail.example.com', mailapp));
+
+// route static assets for "assets-*" subdomain to get
+// around max host connections limit on browsers
+app.use(vhost('assets-*.example.com', staticapp));
+
+// add middlewares and main usage to app
+
+app.listen(3000);
+```
+
+### using with connect for user subdomains
+
+```js
+var connect = require('connect');
+var serveStatic = require('serve-static');
+var vhost = require('vhost');
+
+var mainapp = connect();
+
+// add middlewares to mainapp for the main web site
+
+// create app that will server user content from public/{username}/
+var userapp = connect();
+
+userapp.use(function (req, res, next) {
+ var username = req.vhost[0]; // username is the "*"
+
+ // pretend request was for /{username}/* for file serving
+ req.originalUrl = req.url;
+ req.url = '/' + username + req.url;
+
+ next();
+});
+userapp.use(serveStatic('public'));
+
+// create main app
+var app = connect();
+
+// add vhost routing for main app
+app.use(vhost('userpages.local', mainapp));
+app.use(vhost('www.userpages.local', mainapp));
+
+// listen on all subdomains for user pages
+app.use(vhost('*.userpages.local', userapp));
+
+app.listen(3000);
+```
+
+### using with any generic request handler
+
+```js
+var connect = require('connect');
+var http = require('http');
+var vhost = require('vhost');
+
+// create main app
+var app = connect();
+
+app.use(
+ vhost('mail.example.com', function (req, res) {
+ // handle req + res belonging to mail.example.com
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello from mail!');
+ })
+);
+
+// an external api server in any framework
+var httpServer = http.createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/plain');
+ res.end('hello from the api!');
+});
+
+app.use(
+ vhost('api.example.com', function (req, res) {
+ // handle req + res belonging to api.example.com
+ // pass the request to a standard Node.js HTTP server
+ httpServer.emit('request', req, res);
+ })
+);
+
+app.listen(3000);
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/vhost.svg
+[npm-url]: https://npmjs.org/package/vhost
+[coveralls-image]: https://img.shields.io/coveralls/expressjs/vhost/master.svg
+[coveralls-url]: https://coveralls.io/r/expressjs/vhost
+[downloads-image]: https://img.shields.io/npm/dm/vhost.svg
+[downloads-url]: https://npmjs.org/package/vhost
+[github-actions-ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/vhost/ci.yml?branch=master&label=ci
+[github-actions-ci-url]: https://github.com/expressjs/vhost/actions/workflows/ci.yml
diff --git a/astro/src/content/resources/zh-tw/utils.md b/astro/src/content/resources/zh-tw/utils.md
new file mode 100644
index 0000000000..546b2f09b4
--- /dev/null
+++ b/astro/src/content/resources/zh-tw/utils.md
@@ -0,0 +1,22 @@
+---
+title: Express utilities
+description: Discover utility modules related to Express.js and Node.js, including tools for cookies, CSRF protection, URL parsing, routing, and more to enhance your applications.
+---
+
+## Express utility functions
+
+The [pillarjs](https://github.com/pillarjs) GitHub organization contains a number of modules
+for utility functions that may be generally useful.
+
+| Utility modules | Description |
+| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| [cookies](https://www.npmjs.com/package/cookies) | Get and set HTTP(S) cookies that can be signed to prevent tampering, using Keygrip. Can be used with the Node.js HTTP library or as Express middleware. |
+| [csrf](https://www.npmjs.com/package/csrf) | Contains the logic behind CSRF token creation and verification. Use this module to create custom CSRF middleware. |
+| [finalhandler](https://www.npmjs.com/package/finalhandler) | Function to invoke as the final step to respond to HTTP request. |
+| [parseurl](https://www.npmjs.com/package/parseurl) | Parse a URL with caching. |
+| [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) | Turn an Express-style path string such as ``/user/:name` into a regular expression. |
+| [resolve-path](https://www.npmjs.com/package/resolve-path) | Resolves a relative path against a root path with validation. |
+| [router](https://www.npmjs.com/package/router) | Simple middleware-style router. |
+| [send](https://www.npmjs.com/package/send) | Library for streaming files as a HTTP response, with support for partial responses (ranges), conditional-GET negotiation, and granular events. |
+
+For additional low-level HTTP-related modules, see [jshttp](https://github.com/jshttp).
diff --git a/astro/src/i18n/locales.ts b/astro/src/i18n/locales.ts
new file mode 100644
index 0000000000..79ed73d631
--- /dev/null
+++ b/astro/src/i18n/locales.ts
@@ -0,0 +1,45 @@
+import en from './ui/en.json';
+import fr from './ui/fr.json';
+import de from './ui/de.json';
+import es from './ui/es.json';
+import it from './ui/it.json';
+import ja from './ui/ja.json';
+import ko from './ui/ko.json';
+import ptBr from './ui/pt-br.json';
+import zhCn from './ui/zh-cn.json';
+import zhTw from './ui/zh-tw.json';
+
+export const languages = {
+ en: { label: 'English', direction: 'ltr' },
+ de: { label: 'Deutsch', direction: 'ltr' },
+ es: { label: 'Español', direction: 'ltr' },
+ fr: { label: 'Français', direction: 'ltr' },
+ it: { label: 'Italiano', direction: 'ltr' },
+ ja: { label: '日本語', direction: 'ltr' },
+ ko: { label: '한국어', direction: 'ltr' },
+ 'pt-br': { label: 'Português', direction: 'ltr' },
+ 'zh-cn': { label: '简体中文', direction: 'ltr' },
+ 'zh-tw': { label: '繁體中文', direction: 'ltr' },
+} as const;
+
+export type LanguageCode = keyof typeof languages;
+
+export const languagesArray = Object.entries(languages).map(([code, obj]) => ({
+ code,
+ label: obj.label,
+}));
+
+export const defaultLang = 'en';
+
+export const ui = {
+ en,
+ fr,
+ de,
+ es,
+ it,
+ ja,
+ ko,
+ 'pt-br': ptBr,
+ 'zh-cn': zhCn,
+ 'zh-tw': zhTw,
+} as const;
diff --git a/astro/src/i18n/ui/de.json b/astro/src/i18n/ui/de.json
new file mode 100644
index 0000000000..a2ad0b9cdc
--- /dev/null
+++ b/astro/src/i18n/ui/de.json
@@ -0,0 +1,79 @@
+{
+ "home.welcome": "Willkommen",
+ "home.workInProgress": "Dies ist eine Work-in-Progress-Homepage.",
+ "home.reviewDesignSystemPrefix": "Sehen Sie sich die",
+ "home.reviewDesignSystemLink": "Designsystem-Grundlagen",
+ "home.reviewDesignSystemSuffix": "Demoseite an, um alle Tokens, Primitiven und Muster zu erkunden.",
+ "search.placeholder": "Tippen Sie, um zu suchen...",
+ "search.ariaLabel": "Suchen oder eine Frage stellen",
+ "theme.toggle": "Theme umschalten",
+ "theme.switchToLight": "Zum hellen Modus wechseln",
+ "theme.switchToDark": "Zum dunklen Modus wechseln",
+ "version.selectLabel": "API-Version auswählen",
+ "nav.mainMenu": "Hauptmenü",
+ "nav.toggleMenu": "Menü umschalten",
+ "nav.home": "Express-Startseite",
+ "nav.breadcrumb": "Breadcrumb",
+ "nav.mainNavigation": "Hauptnavigation",
+ "nav.selectVersion": "Dokumentationsversion auswählen",
+ "menu.docs": "Docs",
+ "menu.docsAria": "Dokumentation",
+ "menu.api": "API",
+ "menu.apiAria": "API-Referenz",
+ "menu.resources": "Ressourcen",
+ "menu.resourcesAria": "Ressourcen",
+ "menu.blog": "Blog",
+ "menu.blogAria": "Blog",
+ "menu.support": "Support",
+ "menu.supportAria": "Support",
+ "menu.gettingStarted": "Erste Schritte",
+ "menu.installing": "Installation",
+ "menu.installingAria": "Express installieren",
+ "menu.helloWorld": "Hello World",
+ "menu.helloWorldAria": "Hello-World-Beispiel",
+ "menu.expressGenerator": "Express-Generator",
+ "menu.expressGeneratorAria": "Express-Generator",
+ "menu.guide": "Leitfaden",
+ "menu.routing": "Routing",
+ "menu.routingAria": "Routing-Leitfaden",
+ "menu.writingMiddleware": "Middleware schreiben",
+ "menu.writingMiddlewareAria": "Middleware-Schreiben-Leitfaden",
+ "menu.usingMiddleware": "Middleware verwenden",
+ "menu.usingMiddlewareAria": "Middleware-Verwendungs-Leitfaden",
+ "menu.advancedTopics": "Fortgeschrittene Themen",
+ "menu.buildingTemplateEngines": "Template-Engines erstellen",
+ "menu.buildingTemplateEnginesAria": "Template-Engines-Erstellen-Leitfaden",
+ "menu.overview": "Übersicht",
+ "menu.overviewAria": "Übersicht",
+ "menu.application": "Anwendung",
+ "menu.applicationOverviewAria": "Anwendungsübersicht",
+ "menu.properties": "Eigenschaften",
+ "menu.applicationPropertiesAria": "Anwendungseigenschaften",
+ "menu.methods": "Methoden",
+ "menu.applicationMethodsAria": "Anwendungsmethoden",
+ "menu.request": "Request",
+ "menu.requestOverviewAria": "Request-Übersicht",
+ "menu.requestPropertiesAria": "Request-Eigenschaften",
+ "menu.response": "Response",
+ "menu.responseOverviewAria": "Response-Übersicht",
+ "menu.responsePropertiesAria": "Response-Eigenschaften",
+ "menu.router": "Router",
+ "menu.routerOverviewAria": "Router-Übersicht",
+ "menu.routerMethodsAria": "Router-Methoden",
+ "menu.community": "Community",
+ "menu.communityAria": "Community-Ressourcen",
+ "menu.glossary": "Glossar",
+ "menu.glossaryAria": "Glossar der Begriffe",
+ "menu.middleware": "Middleware",
+ "menu.middlewareAria": "Middleware-Ressourcen",
+ "menu.middlewareOverviewAria": "Middleware-Übersicht",
+ "404.title": "404 - Seite nicht gefunden",
+ "404.description": "Die gesuchte Seite konnte nicht gefunden werden.",
+ "404.heading": "Seite nicht gefunden",
+ "404.message": "Die gesuchte Seite existiert nicht oder wurde verschoben.",
+ "404.goHome": "Zur Startseite",
+ "hero.tagline": "Schnelles, unvoreingenommenes, minimalistisches Web-Framework für Node.js",
+ "hero.getStarted": "Erste Schritte",
+ "hero.videoPause": "Hintergrundvideo anhalten",
+ "hero.videoPlay": "Hintergrundvideo abspielen"
+}
diff --git a/astro/src/i18n/ui/en.json b/astro/src/i18n/ui/en.json
new file mode 100644
index 0000000000..635c3f1d3d
--- /dev/null
+++ b/astro/src/i18n/ui/en.json
@@ -0,0 +1,92 @@
+{
+ "home.welcome": "Welcome",
+ "home.workInProgress": "This is a work-in-progress homepage.",
+ "home.reviewDesignSystemPrefix": "Review the",
+ "home.reviewDesignSystemLink": "Design System Foundations",
+ "home.reviewDesignSystemSuffix": "demo page to explore all tokens, primitives, and patterns.",
+ "search.placeholder": "Start typing...",
+ "search.ariaLabel": "Start typing to search",
+ "theme.toggle": "Toggle theme",
+ "theme.switchToLight": "Switch to light mode",
+ "theme.switchToDark": "Switch to dark mode",
+ "version.selectLabel": "Select API version",
+ "nav.mainMenu": "Main menu",
+ "nav.toggleMenu": "Toggle menu",
+ "nav.home": "Express home",
+ "nav.breadcrumb": "Breadcrumb",
+ "nav.mainNavigation": "Main navigation",
+ "nav.selectVersion": "Select documentation version",
+ "menu.docs": "Docs",
+ "menu.docsAria": "Documentation",
+ "menu.api": "API",
+ "menu.apiAria": "API Reference",
+ "menu.resources": "Resources",
+ "menu.resourcesAria": "Resources",
+ "menu.blog": "Blog",
+ "menu.blogAria": "Blog",
+ "menu.support": "Support",
+ "menu.supportAria": "Support",
+ "menu.gettingStarted": "Getting started",
+ "menu.installing": "Installing",
+ "menu.installingAria": "Installing Express",
+ "menu.helloWorld": "Hello world",
+ "menu.helloWorldAria": "Hello world example",
+ "menu.expressGenerator": "Express generator",
+ "menu.expressGeneratorAria": "Express generator",
+ "menu.guide": "Guide",
+ "menu.routing": "Routing",
+ "menu.routingAria": "Routing guide",
+ "menu.writingMiddleware": "Writing middleware",
+ "menu.writingMiddlewareAria": "Writing middleware guide",
+ "menu.usingMiddleware": "Using middleware",
+ "menu.usingMiddlewareAria": "Using middleware guide",
+ "menu.advancedTopics": "Advanced topics",
+ "menu.buildingTemplateEngines": "Building template engines",
+ "menu.buildingTemplateEnginesAria": "Building template engines guide",
+ "menu.overview": "Overview",
+ "menu.events": "Events",
+ "menu.overviewAria": "Overview",
+ "menu.expressOverviewAria": "Express overview",
+ "menu.expressMethodsAria": "Express methods",
+ "menu.application": "Application",
+ "menu.applicationOverviewAria": "Application overview",
+ "menu.properties": "Properties",
+ "menu.applicationPropertiesAria": "Application properties",
+ "menu.applicationEventAria": "Application events",
+ "menu.methods": "Methods",
+ "menu.applicationMethodsAria": "Application methods",
+ "menu.request": "Request",
+ "menu.requestOverviewAria": "Request overview",
+ "menu.requestPropertiesAria": "Request properties",
+ "menu.response": "Response",
+ "menu.responseOverviewAria": "Response overview",
+ "menu.responsePropertiesAria": "Response properties",
+ "menu.router": "Router",
+ "menu.routerOverviewAria": "Router overview",
+ "menu.routerMethodsAria": "Router methods",
+ "menu.community": "Community",
+ "menu.communityAria": "Community resources",
+ "menu.glossary": "Glossary",
+ "menu.glossaryAria": "Glossary of terms",
+ "menu.middleware": "Middleware",
+ "menu.middlewareAria": "Middleware resources",
+ "menu.middlewareOverviewAria": "Middleware overview",
+ "404.title": "404 - Page Not Found",
+ "404.description": "The page you are looking for could not be found.",
+ "404.heading": "Page Not Found",
+ "404.message": "The page you are looking for does not exist or has been moved.",
+ "404.goHome": "Go to Home",
+ "hero.tagline": "Fast, unopinionated, minimalist web framework for Node.js",
+ "hero.getStarted": "Get Started",
+ "hero.videoPause": "Pause background video",
+ "hero.videoPlay": "Play background video",
+ "features.title": "Clarity over complexity. For every developer.",
+ "features.performance.title": "Performance",
+ "features.performance.body": "Express provides a thin layer of fundamental web application features, without obscuring Node.js features that you know and love.",
+ "features.api.title": "APIs",
+ "features.api.body": "With a myriad of HTTP utility methods and middleware at your disposal, creating a robust API is quick and easy.",
+ "features.middleware.title": "Middleware",
+ "features.middleware.body": "Express is a lightweight and flexible routing framework with minimal core features meant to be augmented through the use of Express middleware modules.",
+ "features.webapplication.title": "Web Applications",
+ "features.webapplication.body": "Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications."
+}
diff --git a/astro/src/i18n/ui/es.json b/astro/src/i18n/ui/es.json
new file mode 100644
index 0000000000..d4923ad3dd
--- /dev/null
+++ b/astro/src/i18n/ui/es.json
@@ -0,0 +1,79 @@
+{
+ "home.welcome": "Bienvenido",
+ "home.workInProgress": "Esta es una página de inicio en desarrollo.",
+ "home.reviewDesignSystemPrefix": "Revisa la página de demostración de",
+ "home.reviewDesignSystemLink": "Fundamentos del Sistema de Diseño",
+ "home.reviewDesignSystemSuffix": "para explorar todos los tokens, primitivas y patrones.",
+ "search.placeholder": "Empieza a escribir...",
+ "search.ariaLabel": "Buscar o hacer una pregunta",
+ "theme.toggle": "Cambiar tema",
+ "theme.switchToLight": "Cambiar a modo claro",
+ "theme.switchToDark": "Cambiar a modo oscuro",
+ "version.selectLabel": "Seleccionar versión de API",
+ "nav.mainMenu": "Menú principal",
+ "nav.toggleMenu": "Alternar menú",
+ "nav.home": "Inicio de Express",
+ "nav.breadcrumb": "Breadcrumb",
+ "nav.mainNavigation": "Navegación principal",
+ "nav.selectVersion": "Seleccionar versión de documentación",
+ "menu.docs": "Docs",
+ "menu.docsAria": "Documentación",
+ "menu.api": "API",
+ "menu.apiAria": "Referencia API",
+ "menu.resources": "Recursos",
+ "menu.resourcesAria": "Recursos",
+ "menu.blog": "Blog",
+ "menu.blogAria": "Blog",
+ "menu.support": "Soporte",
+ "menu.supportAria": "Soporte",
+ "menu.gettingStarted": "Primeros pasos",
+ "menu.installing": "Instalación",
+ "menu.installingAria": "Instalar Express",
+ "menu.helloWorld": "Hello World",
+ "menu.helloWorldAria": "Ejemplo Hello World",
+ "menu.expressGenerator": "Generador Express",
+ "menu.expressGeneratorAria": "Generador Express",
+ "menu.guide": "Guía",
+ "menu.routing": "Enrutamiento",
+ "menu.routingAria": "Guía de enrutamiento",
+ "menu.writingMiddleware": "Escribir middleware",
+ "menu.writingMiddlewareAria": "Guía para escribir middleware",
+ "menu.usingMiddleware": "Usar middleware",
+ "menu.usingMiddlewareAria": "Guía de uso de middleware",
+ "menu.advancedTopics": "Temas avanzados",
+ "menu.buildingTemplateEngines": "Crear motores de plantillas",
+ "menu.buildingTemplateEnginesAria": "Guía para crear motores de plantillas",
+ "menu.overview": "Descripción general",
+ "menu.overviewAria": "Descripción general",
+ "menu.application": "Aplicación",
+ "menu.applicationOverviewAria": "Descripción general de la aplicación",
+ "menu.properties": "Propiedades",
+ "menu.applicationPropertiesAria": "Propiedades de la aplicación",
+ "menu.methods": "Métodos",
+ "menu.applicationMethodsAria": "Métodos de la aplicación",
+ "menu.request": "Request",
+ "menu.requestOverviewAria": "Descripción general de Request",
+ "menu.requestPropertiesAria": "Propiedades de Request",
+ "menu.response": "Response",
+ "menu.responseOverviewAria": "Descripción general de Response",
+ "menu.responsePropertiesAria": "Propiedades de Response",
+ "menu.router": "Router",
+ "menu.routerOverviewAria": "Descripción general del Router",
+ "menu.routerMethodsAria": "Métodos del Router",
+ "menu.community": "Comunidad",
+ "menu.communityAria": "Recursos de la comunidad",
+ "menu.glossary": "Glosario",
+ "menu.glossaryAria": "Glosario de términos",
+ "menu.middleware": "Middleware",
+ "menu.middlewareAria": "Recursos de middleware",
+ "menu.middlewareOverviewAria": "Descripción general de middleware",
+ "404.title": "404 - Página no encontrada",
+ "404.description": "La página que buscas no se pudo encontrar.",
+ "404.heading": "Página no encontrada",
+ "404.message": "La página que buscas no existe o ha sido movida.",
+ "404.goHome": "Ir a inicio",
+ "hero.tagline": "Framework web rápido, sin opiniones y minimalista para Node.js",
+ "hero.getStarted": "Comenzar",
+ "hero.videoPause": "Pausar video de fondo",
+ "hero.videoPlay": "Reproducir video de fondo"
+}
diff --git a/astro/src/i18n/ui/fr.json b/astro/src/i18n/ui/fr.json
new file mode 100644
index 0000000000..428e87af0e
--- /dev/null
+++ b/astro/src/i18n/ui/fr.json
@@ -0,0 +1,79 @@
+{
+ "home.welcome": "Bienvenue",
+ "home.workInProgress": "Ceci est une page d'accueil en cours de développement.",
+ "home.reviewDesignSystemPrefix": "Consultez la page de démonstration des",
+ "home.reviewDesignSystemLink": "fondamentaux du système de design",
+ "home.reviewDesignSystemSuffix": "pour explorer tous les tokens, primitives et motifs.",
+ "search.placeholder": "Commencez à taper...",
+ "search.ariaLabel": "Rechercher ou poser une question",
+ "theme.toggle": "Changer de thème",
+ "theme.switchToLight": "Passer en mode clair",
+ "theme.switchToDark": "Passer en mode sombre",
+ "version.selectLabel": "Sélectionner la version de l'API",
+ "nav.mainMenu": "Menu principal",
+ "nav.toggleMenu": "Basculer le menu",
+ "nav.home": "Accueil Express",
+ "nav.breadcrumb": "Fil d'Ariane",
+ "nav.mainNavigation": "Navigation principale",
+ "nav.selectVersion": "Sélectionner la version de la documentation",
+ "menu.docs": "Docs",
+ "menu.docsAria": "Documentation",
+ "menu.api": "API",
+ "menu.apiAria": "Référence API",
+ "menu.resources": "Ressources",
+ "menu.resourcesAria": "Ressources",
+ "menu.blog": "Blog",
+ "menu.blogAria": "Blog",
+ "menu.support": "Support",
+ "menu.supportAria": "Support",
+ "menu.gettingStarted": "Démarrage",
+ "menu.installing": "Installation",
+ "menu.installingAria": "Installer Express",
+ "menu.helloWorld": "Hello World",
+ "menu.helloWorldAria": "Exemple Hello World",
+ "menu.expressGenerator": "Générateur Express",
+ "menu.expressGeneratorAria": "Générateur Express",
+ "menu.guide": "Guide",
+ "menu.routing": "Routage",
+ "menu.routingAria": "Guide de routage",
+ "menu.writingMiddleware": "Écrire un middleware",
+ "menu.writingMiddlewareAria": "Guide d'écriture de middleware",
+ "menu.usingMiddleware": "Utiliser un middleware",
+ "menu.usingMiddlewareAria": "Guide d'utilisation de middleware",
+ "menu.advancedTopics": "Sujets avancés",
+ "menu.buildingTemplateEngines": "Créer des moteurs de templates",
+ "menu.buildingTemplateEnginesAria": "Guide de création de moteurs de templates",
+ "menu.overview": "Aperçu",
+ "menu.overviewAria": "Aperçu",
+ "menu.application": "Application",
+ "menu.applicationOverviewAria": "Aperçu de l'application",
+ "menu.properties": "Propriétés",
+ "menu.applicationPropertiesAria": "Propriétés de l'application",
+ "menu.methods": "Méthodes",
+ "menu.applicationMethodsAria": "Méthodes de l'application",
+ "menu.request": "Request",
+ "menu.requestOverviewAria": "Aperçu de Request",
+ "menu.requestPropertiesAria": "Propriétés de Request",
+ "menu.response": "Response",
+ "menu.responseOverviewAria": "Aperçu de Response",
+ "menu.responsePropertiesAria": "Propriétés de Response",
+ "menu.router": "Router",
+ "menu.routerOverviewAria": "Aperçu du Router",
+ "menu.routerMethodsAria": "Méthodes du Router",
+ "menu.community": "Communauté",
+ "menu.communityAria": "Ressources de la communauté",
+ "menu.glossary": "Glossaire",
+ "menu.glossaryAria": "Glossaire des termes",
+ "menu.middleware": "Middleware",
+ "menu.middlewareAria": "Ressources middleware",
+ "menu.middlewareOverviewAria": "Aperçu du middleware",
+ "404.title": "404 - Page non trouvée",
+ "404.description": "La page que vous recherchez est introuvable.",
+ "404.heading": "Page non trouvée",
+ "404.message": "La page que vous recherchez n'existe pas ou a été déplacée.",
+ "404.goHome": "Aller à l'accueil",
+ "hero.tagline": "Framework web rapide, sans opinion et minimaliste pour Node.js",
+ "hero.getStarted": "Commencer",
+ "hero.videoPause": "Mettre en pause la vidéo de fond",
+ "hero.videoPlay": "Lire la vidéo de fond"
+}
diff --git a/astro/src/i18n/ui/it.json b/astro/src/i18n/ui/it.json
new file mode 100644
index 0000000000..9a85677fe6
--- /dev/null
+++ b/astro/src/i18n/ui/it.json
@@ -0,0 +1,79 @@
+{
+ "home.welcome": "Benvenuto",
+ "home.workInProgress": "Questa è una homepage in fase di sviluppo.",
+ "home.reviewDesignSystemPrefix": "Rivedi la pagina di dimostrazione dei",
+ "home.reviewDesignSystemLink": "fondamenti del sistema di design",
+ "home.reviewDesignSystemSuffix": "per esplorare tutti i token, le primitive e i pattern.",
+ "search.placeholder": "Inizia a digitare...",
+ "search.ariaLabel": "Cerca o fai una domanda",
+ "theme.toggle": "Cambia tema",
+ "theme.switchToLight": "Passa alla modalità chiara",
+ "theme.switchToDark": "Passa alla modalità scura",
+ "version.selectLabel": "Seleziona versione API",
+ "nav.mainMenu": "Menu principale",
+ "nav.toggleMenu": "Attiva/disattiva menu",
+ "nav.home": "Home di Express",
+ "nav.breadcrumb": "Breadcrumb",
+ "nav.mainNavigation": "Navigazione principale",
+ "nav.selectVersion": "Seleziona versione documentazione",
+ "menu.docs": "Docs",
+ "menu.docsAria": "Documentazione",
+ "menu.api": "API",
+ "menu.apiAria": "Riferimento API",
+ "menu.resources": "Risorse",
+ "menu.resourcesAria": "Risorse",
+ "menu.blog": "Blog",
+ "menu.blogAria": "Blog",
+ "menu.support": "Supporto",
+ "menu.supportAria": "Supporto",
+ "menu.gettingStarted": "Per iniziare",
+ "menu.installing": "Installazione",
+ "menu.installingAria": "Installare Express",
+ "menu.helloWorld": "Hello World",
+ "menu.helloWorldAria": "Esempio Hello World",
+ "menu.expressGenerator": "Generatore Express",
+ "menu.expressGeneratorAria": "Generatore Express",
+ "menu.guide": "Guida",
+ "menu.routing": "Routing",
+ "menu.routingAria": "Guida al routing",
+ "menu.writingMiddleware": "Scrivere middleware",
+ "menu.writingMiddlewareAria": "Guida alla scrittura middleware",
+ "menu.usingMiddleware": "Usare middleware",
+ "menu.usingMiddlewareAria": "Guida all'uso middleware",
+ "menu.advancedTopics": "Argomenti avanzati",
+ "menu.buildingTemplateEngines": "Creare motori di template",
+ "menu.buildingTemplateEnginesAria": "Guida alla creazione di motori di template",
+ "menu.overview": "Panoramica",
+ "menu.overviewAria": "Panoramica",
+ "menu.application": "Applicazione",
+ "menu.applicationOverviewAria": "Panoramica dell'applicazione",
+ "menu.properties": "Proprietà",
+ "menu.applicationPropertiesAria": "Proprietà dell'applicazione",
+ "menu.methods": "Metodi",
+ "menu.applicationMethodsAria": "Metodi dell'applicazione",
+ "menu.request": "Request",
+ "menu.requestOverviewAria": "Panoramica Request",
+ "menu.requestPropertiesAria": "Proprietà Request",
+ "menu.response": "Response",
+ "menu.responseOverviewAria": "Panoramica Response",
+ "menu.responsePropertiesAria": "Proprietà Response",
+ "menu.router": "Router",
+ "menu.routerOverviewAria": "Panoramica Router",
+ "menu.routerMethodsAria": "Metodi Router",
+ "menu.community": "Comunità",
+ "menu.communityAria": "Risorse della comunità",
+ "menu.glossary": "Glossario",
+ "menu.glossaryAria": "Glossario dei termini",
+ "menu.middleware": "Middleware",
+ "menu.middlewareAria": "Risorse middleware",
+ "menu.middlewareOverviewAria": "Panoramica middleware",
+ "404.title": "404 - Pagina non trovata",
+ "404.description": "La pagina che stai cercando non è stata trovata.",
+ "404.heading": "Pagina non trovata",
+ "404.message": "La pagina che stai cercando non esiste o è stata spostata.",
+ "404.goHome": "Vai alla home",
+ "hero.tagline": "Framework web veloce, non prescrittivo e minimalista per Node.js",
+ "hero.getStarted": "Inizia",
+ "hero.videoPause": "Metti in pausa il video in background",
+ "hero.videoPlay": "Riproduci il video in background"
+}
diff --git a/astro/src/i18n/ui/ja.json b/astro/src/i18n/ui/ja.json
new file mode 100644
index 0000000000..ba78dcff99
--- /dev/null
+++ b/astro/src/i18n/ui/ja.json
@@ -0,0 +1,79 @@
+{
+ "home.welcome": "ようこそ",
+ "home.workInProgress": "これは開発中のホームページです。",
+ "home.reviewDesignSystemPrefix": "",
+ "home.reviewDesignSystemLink": "デザインシステム基礎",
+ "home.reviewDesignSystemSuffix": "のデモページを確認して、すべてのトークン、プリミティブ、パターンを探索してください。",
+ "search.placeholder": "入力を開始...",
+ "search.ariaLabel": "検索または質問する",
+ "theme.toggle": "テーマを切り替え",
+ "theme.switchToLight": "ライトモードに切り替え",
+ "theme.switchToDark": "ダークモードに切り替え",
+ "version.selectLabel": "APIバージョンを選択",
+ "nav.mainMenu": "メインメニュー",
+ "nav.toggleMenu": "メニューを切り替え",
+ "nav.home": "Expressホーム",
+ "nav.breadcrumb": "パンくずリスト",
+ "nav.mainNavigation": "メインナビゲーション",
+ "nav.selectVersion": "ドキュメントバージョンを選択",
+ "menu.docs": "ドキュメント",
+ "menu.docsAria": "ドキュメント",
+ "menu.api": "API",
+ "menu.apiAria": "APIリファレンス",
+ "menu.resources": "リソース",
+ "menu.resourcesAria": "リソース",
+ "menu.blog": "ブログ",
+ "menu.blogAria": "ブログ",
+ "menu.support": "サポート",
+ "menu.supportAria": "サポート",
+ "menu.gettingStarted": "はじめに",
+ "menu.installing": "インストール",
+ "menu.installingAria": "Expressをインストール",
+ "menu.helloWorld": "Hello World",
+ "menu.helloWorldAria": "Hello Worldの例",
+ "menu.expressGenerator": "Expressジェネレーター",
+ "menu.expressGeneratorAria": "Expressジェネレーター",
+ "menu.guide": "ガイド",
+ "menu.routing": "ルーティング",
+ "menu.routingAria": "ルーティングガイド",
+ "menu.writingMiddleware": "ミドルウェアの作成",
+ "menu.writingMiddlewareAria": "ミドルウェア作成ガイド",
+ "menu.usingMiddleware": "ミドルウェアの使用",
+ "menu.usingMiddlewareAria": "ミドルウェア使用ガイド",
+ "menu.advancedTopics": "高度なトピック",
+ "menu.buildingTemplateEngines": "テンプレートエンジンの構築",
+ "menu.buildingTemplateEnginesAria": "テンプレートエンジン構築ガイド",
+ "menu.overview": "概要",
+ "menu.overviewAria": "概要",
+ "menu.application": "アプリケーション",
+ "menu.applicationOverviewAria": "アプリケーション概要",
+ "menu.properties": "プロパティ",
+ "menu.applicationPropertiesAria": "アプリケーションプロパティ",
+ "menu.methods": "メソッド",
+ "menu.applicationMethodsAria": "アプリケーションメソッド",
+ "menu.request": "Request",
+ "menu.requestOverviewAria": "Request概要",
+ "menu.requestPropertiesAria": "Requestプロパティ",
+ "menu.response": "Response",
+ "menu.responseOverviewAria": "Response概要",
+ "menu.responsePropertiesAria": "Responseプロパティ",
+ "menu.router": "Router",
+ "menu.routerOverviewAria": "Router概要",
+ "menu.routerMethodsAria": "Routerメソッド",
+ "menu.community": "コミュニティ",
+ "menu.communityAria": "コミュニティリソース",
+ "menu.glossary": "用語集",
+ "menu.glossaryAria": "用語集",
+ "menu.middleware": "ミドルウェア",
+ "menu.middlewareAria": "ミドルウェアリソース",
+ "menu.middlewareOverviewAria": "ミドルウェア概要",
+ "404.title": "404 - ページが見つかりません",
+ "404.description": "お探しのページが見つかりませんでした。",
+ "404.heading": "ページが見つかりません",
+ "404.message": "お探しのページは存在しないか、移動されました。",
+ "404.goHome": "ホームに戻る",
+ "hero.tagline": "Node.js向けの高速で中立的なミニマリストWebフレームワーク",
+ "hero.getStarted": "始める",
+ "hero.videoPause": "背景動画を一時停止",
+ "hero.videoPlay": "背景動画を再生"
+}
diff --git a/astro/src/i18n/ui/ko.json b/astro/src/i18n/ui/ko.json
new file mode 100644
index 0000000000..23561f5f63
--- /dev/null
+++ b/astro/src/i18n/ui/ko.json
@@ -0,0 +1,79 @@
+{
+ "home.welcome": "환영합니다",
+ "home.workInProgress": "이것은 작업 중인 홈페이지입니다.",
+ "home.reviewDesignSystemPrefix": "",
+ "home.reviewDesignSystemLink": "디자인 시스템 기초",
+ "home.reviewDesignSystemSuffix": "데모 페이지를 검토하여 모든 토큰, 프리미티브 및 패턴을 탐색하세요.",
+ "search.placeholder": "입력을 시작하세요...",
+ "search.ariaLabel": "검색 또는 질문하기",
+ "theme.toggle": "테마 전환",
+ "theme.switchToLight": "라이트 모드로 전환",
+ "theme.switchToDark": "다크 모드로 전환",
+ "version.selectLabel": "API 버전 선택",
+ "nav.mainMenu": "메인 메뉴",
+ "nav.toggleMenu": "메뉴 전환",
+ "nav.home": "Express 홈",
+ "nav.breadcrumb": "탐색 경로",
+ "nav.mainNavigation": "메인 내비게이션",
+ "nav.selectVersion": "문서 버전 선택",
+ "menu.docs": "문서",
+ "menu.docsAria": "문서",
+ "menu.api": "API",
+ "menu.apiAria": "API 참조",
+ "menu.resources": "리소스",
+ "menu.resourcesAria": "리소스",
+ "menu.blog": "블로그",
+ "menu.blogAria": "블로그",
+ "menu.support": "지원",
+ "menu.supportAria": "지원",
+ "menu.gettingStarted": "시작하기",
+ "menu.installing": "설치",
+ "menu.installingAria": "Express 설치",
+ "menu.helloWorld": "Hello World",
+ "menu.helloWorldAria": "Hello World 예제",
+ "menu.expressGenerator": "Express 생성기",
+ "menu.expressGeneratorAria": "Express 생성기",
+ "menu.guide": "가이드",
+ "menu.routing": "라우팅",
+ "menu.routingAria": "라우팅 가이드",
+ "menu.writingMiddleware": "미들웨어 작성",
+ "menu.writingMiddlewareAria": "미들웨어 작성 가이드",
+ "menu.usingMiddleware": "미들웨어 사용",
+ "menu.usingMiddlewareAria": "미들웨어 사용 가이드",
+ "menu.advancedTopics": "고급 주제",
+ "menu.buildingTemplateEngines": "템플릿 엔진 구축",
+ "menu.buildingTemplateEnginesAria": "템플릿 엔진 구축 가이드",
+ "menu.overview": "개요",
+ "menu.overviewAria": "개요",
+ "menu.application": "애플리케이션",
+ "menu.applicationOverviewAria": "애플리케이션 개요",
+ "menu.properties": "속성",
+ "menu.applicationPropertiesAria": "애플리케이션 속성",
+ "menu.methods": "메서드",
+ "menu.applicationMethodsAria": "애플리케이션 메서드",
+ "menu.request": "Request",
+ "menu.requestOverviewAria": "Request 개요",
+ "menu.requestPropertiesAria": "Request 속성",
+ "menu.response": "Response",
+ "menu.responseOverviewAria": "Response 개요",
+ "menu.responsePropertiesAria": "Response 속성",
+ "menu.router": "Router",
+ "menu.routerOverviewAria": "Router 개요",
+ "menu.routerMethodsAria": "Router 메서드",
+ "menu.community": "커뮤니티",
+ "menu.communityAria": "커뮤니티 리소스",
+ "menu.glossary": "용어집",
+ "menu.glossaryAria": "용어집",
+ "menu.middleware": "미들웨어",
+ "menu.middlewareAria": "미들웨어 리소스",
+ "menu.middlewareOverviewAria": "미들웨어 개요",
+ "404.title": "404 - 페이지를 찾을 수 없습니다",
+ "404.description": "찾으시는 페이지를 찾을 수 없습니다.",
+ "404.heading": "페이지를 찾을 수 없습니다",
+ "404.message": "찾으시는 페이지가 존재하지 않거나 이동되었습니다.",
+ "404.goHome": "홈으로 이동",
+ "hero.tagline": "Node.js를 위한 빠르고 독단적이지 않은 미니멀리스트 웹 프레임워크",
+ "hero.getStarted": "시작하기",
+ "hero.videoPause": "배경 비디오 일시정지",
+ "hero.videoPlay": "배경 비디오 재생"
+}
diff --git a/astro/src/i18n/ui/pt-br.json b/astro/src/i18n/ui/pt-br.json
new file mode 100644
index 0000000000..17cc03007b
--- /dev/null
+++ b/astro/src/i18n/ui/pt-br.json
@@ -0,0 +1,79 @@
+{
+ "home.welcome": "Bem-vindo",
+ "home.workInProgress": "Esta é uma página inicial em desenvolvimento.",
+ "home.reviewDesignSystemPrefix": "Revise a página de demonstração dos",
+ "home.reviewDesignSystemLink": "Fundamentos do Sistema de Design",
+ "home.reviewDesignSystemSuffix": "para explorar todos os tokens, primitivas e padrões.",
+ "search.placeholder": "Comece a digitar...",
+ "search.ariaLabel": "Pesquisar ou fazer uma pergunta",
+ "theme.toggle": "Alternar tema",
+ "theme.switchToLight": "Mudar para modo claro",
+ "theme.switchToDark": "Mudar para modo escuro",
+ "version.selectLabel": "Selecionar versão da API",
+ "nav.mainMenu": "Menu principal",
+ "nav.toggleMenu": "Alternar menu",
+ "nav.home": "Início do Express",
+ "nav.breadcrumb": "Navegação estrutural",
+ "nav.mainNavigation": "Navegação principal",
+ "nav.selectVersion": "Selecionar versão da documentação",
+ "menu.docs": "Docs",
+ "menu.docsAria": "Documentação",
+ "menu.api": "API",
+ "menu.apiAria": "Referência da API",
+ "menu.resources": "Recursos",
+ "menu.resourcesAria": "Recursos",
+ "menu.blog": "Blog",
+ "menu.blogAria": "Blog",
+ "menu.support": "Suporte",
+ "menu.supportAria": "Suporte",
+ "menu.gettingStarted": "Primeiros passos",
+ "menu.installing": "Instalação",
+ "menu.installingAria": "Instalar Express",
+ "menu.helloWorld": "Hello World",
+ "menu.helloWorldAria": "Exemplo Hello World",
+ "menu.expressGenerator": "Gerador Express",
+ "menu.expressGeneratorAria": "Gerador Express",
+ "menu.guide": "Guia",
+ "menu.routing": "Roteamento",
+ "menu.routingAria": "Guia de roteamento",
+ "menu.writingMiddleware": "Escrever middleware",
+ "menu.writingMiddlewareAria": "Guia para escrever middleware",
+ "menu.usingMiddleware": "Usar middleware",
+ "menu.usingMiddlewareAria": "Guia de uso de middleware",
+ "menu.advancedTopics": "Tópicos avançados",
+ "menu.buildingTemplateEngines": "Construir motores de template",
+ "menu.buildingTemplateEnginesAria": "Guia para construir motores de template",
+ "menu.overview": "Visão geral",
+ "menu.overviewAria": "Visão geral",
+ "menu.application": "Aplicação",
+ "menu.applicationOverviewAria": "Visão geral da aplicação",
+ "menu.properties": "Propriedades",
+ "menu.applicationPropertiesAria": "Propriedades da aplicação",
+ "menu.methods": "Métodos",
+ "menu.applicationMethodsAria": "Métodos da aplicação",
+ "menu.request": "Request",
+ "menu.requestOverviewAria": "Visão geral do Request",
+ "menu.requestPropertiesAria": "Propriedades do Request",
+ "menu.response": "Response",
+ "menu.responseOverviewAria": "Visão geral do Response",
+ "menu.responsePropertiesAria": "Propriedades do Response",
+ "menu.router": "Router",
+ "menu.routerOverviewAria": "Visão geral do Router",
+ "menu.routerMethodsAria": "Métodos do Router",
+ "menu.community": "Comunidade",
+ "menu.communityAria": "Recursos da comunidade",
+ "menu.glossary": "Glossário",
+ "menu.glossaryAria": "Glossário de termos",
+ "menu.middleware": "Middleware",
+ "menu.middlewareAria": "Recursos de middleware",
+ "menu.middlewareOverviewAria": "Visão geral do middleware",
+ "404.title": "404 - Página não encontrada",
+ "404.description": "A página que você está procurando não foi encontrada.",
+ "404.heading": "Página não encontrada",
+ "404.message": "A página que você está procurando não existe ou foi movida.",
+ "404.goHome": "Ir para a página inicial",
+ "hero.tagline": "Framework web rápido, sem opinião e minimalista para Node.js",
+ "hero.getStarted": "Começar",
+ "hero.videoPause": "Pausar vídeo de fundo",
+ "hero.videoPlay": "Reproduzir vídeo de fundo"
+}
diff --git a/astro/src/i18n/ui/zh-cn.json b/astro/src/i18n/ui/zh-cn.json
new file mode 100644
index 0000000000..05a9699a36
--- /dev/null
+++ b/astro/src/i18n/ui/zh-cn.json
@@ -0,0 +1,79 @@
+{
+ "home.welcome": "欢迎",
+ "home.workInProgress": "这是一个正在开发中的主页。",
+ "home.reviewDesignSystemPrefix": "查看",
+ "home.reviewDesignSystemLink": "设计系统基础",
+ "home.reviewDesignSystemSuffix": "演示页面,探索所有令牌、原语和模式。",
+ "search.placeholder": "开始输入...",
+ "search.ariaLabel": "搜索或提问",
+ "theme.toggle": "切换主题",
+ "theme.switchToLight": "切换到浅色模式",
+ "theme.switchToDark": "切换到深色模式",
+ "version.selectLabel": "选择API版本",
+ "nav.mainMenu": "主菜单",
+ "nav.toggleMenu": "切换菜单",
+ "nav.home": "Express主页",
+ "nav.breadcrumb": "面包屑导航",
+ "nav.mainNavigation": "主导航",
+ "nav.selectVersion": "选择文档版本",
+ "menu.docs": "文档",
+ "menu.docsAria": "文档",
+ "menu.api": "API",
+ "menu.apiAria": "API参考",
+ "menu.resources": "资源",
+ "menu.resourcesAria": "资源",
+ "menu.blog": "博客",
+ "menu.blogAria": "博客",
+ "menu.support": "支持",
+ "menu.supportAria": "支持",
+ "menu.gettingStarted": "入门",
+ "menu.installing": "安装",
+ "menu.installingAria": "安装Express",
+ "menu.helloWorld": "Hello World",
+ "menu.helloWorldAria": "Hello World示例",
+ "menu.expressGenerator": "Express生成器",
+ "menu.expressGeneratorAria": "Express生成器",
+ "menu.guide": "指南",
+ "menu.routing": "路由",
+ "menu.routingAria": "路由指南",
+ "menu.writingMiddleware": "编写中间件",
+ "menu.writingMiddlewareAria": "编写中间件指南",
+ "menu.usingMiddleware": "使用中间件",
+ "menu.usingMiddlewareAria": "使用中间件指南",
+ "menu.advancedTopics": "高级主题",
+ "menu.buildingTemplateEngines": "构建模板引擎",
+ "menu.buildingTemplateEnginesAria": "构建模板引擎指南",
+ "menu.overview": "概述",
+ "menu.overviewAria": "概述",
+ "menu.application": "应用程序",
+ "menu.applicationOverviewAria": "应用程序概述",
+ "menu.properties": "属性",
+ "menu.applicationPropertiesAria": "应用程序属性",
+ "menu.methods": "方法",
+ "menu.applicationMethodsAria": "应用程序方法",
+ "menu.request": "Request",
+ "menu.requestOverviewAria": "Request概述",
+ "menu.requestPropertiesAria": "Request属性",
+ "menu.response": "Response",
+ "menu.responseOverviewAria": "Response概述",
+ "menu.responsePropertiesAria": "Response属性",
+ "menu.router": "Router",
+ "menu.routerOverviewAria": "Router概述",
+ "menu.routerMethodsAria": "Router方法",
+ "menu.community": "社区",
+ "menu.communityAria": "社区资源",
+ "menu.glossary": "术语表",
+ "menu.glossaryAria": "术语表",
+ "menu.middleware": "中间件",
+ "menu.middlewareAria": "中间件资源",
+ "menu.middlewareOverviewAria": "中间件概述",
+ "404.title": "404 - 页面未找到",
+ "404.description": "您正在查找的页面无法找到。",
+ "404.heading": "页面未找到",
+ "404.message": "您正在查找的页面不存在或已被移动。",
+ "404.goHome": "返回主页",
+ "hero.tagline": "快速、无偏见、极简主义的 Node.js Web 框架",
+ "hero.getStarted": "开始使用",
+ "hero.videoPause": "暂停背景视频",
+ "hero.videoPlay": "播放背景视频"
+}
diff --git a/astro/src/i18n/ui/zh-tw.json b/astro/src/i18n/ui/zh-tw.json
new file mode 100644
index 0000000000..10c42eaa88
--- /dev/null
+++ b/astro/src/i18n/ui/zh-tw.json
@@ -0,0 +1,79 @@
+{
+ "home.welcome": "歡迎",
+ "home.workInProgress": "這是一個正在開發中的首頁。",
+ "home.reviewDesignSystemPrefix": "查看",
+ "home.reviewDesignSystemLink": "設計系統基礎",
+ "home.reviewDesignSystemSuffix": "演示頁面,探索所有令牌、原語和模式。",
+ "search.placeholder": "開始輸入...",
+ "search.ariaLabel": "搜尋或提問",
+ "theme.toggle": "切換主題",
+ "theme.switchToLight": "切換到淺色模式",
+ "theme.switchToDark": "切換到深色模式",
+ "version.selectLabel": "選擇API版本",
+ "nav.mainMenu": "主選單",
+ "nav.toggleMenu": "切換選單",
+ "nav.home": "Express首頁",
+ "nav.breadcrumb": "麵包屑導航",
+ "nav.mainNavigation": "主導航",
+ "nav.selectVersion": "選擇文件版本",
+ "menu.docs": "文件",
+ "menu.docsAria": "文件",
+ "menu.api": "API",
+ "menu.apiAria": "API參考",
+ "menu.resources": "資源",
+ "menu.resourcesAria": "資源",
+ "menu.blog": "部落格",
+ "menu.blogAria": "部落格",
+ "menu.support": "支援",
+ "menu.supportAria": "支援",
+ "menu.gettingStarted": "入門",
+ "menu.installing": "安裝",
+ "menu.installingAria": "安裝Express",
+ "menu.helloWorld": "Hello World",
+ "menu.helloWorldAria": "Hello World範例",
+ "menu.expressGenerator": "Express產生器",
+ "menu.expressGeneratorAria": "Express產生器",
+ "menu.guide": "指南",
+ "menu.routing": "路由",
+ "menu.routingAria": "路由指南",
+ "menu.writingMiddleware": "編寫中介軟體",
+ "menu.writingMiddlewareAria": "編寫中介軟體指南",
+ "menu.usingMiddleware": "使用中介軟體",
+ "menu.usingMiddlewareAria": "使用中介軟體指南",
+ "menu.advancedTopics": "進階主題",
+ "menu.buildingTemplateEngines": "建立範本引擎",
+ "menu.buildingTemplateEnginesAria": "建立範本引擎指南",
+ "menu.overview": "概述",
+ "menu.overviewAria": "概述",
+ "menu.application": "應用程式",
+ "menu.applicationOverviewAria": "應用程式概述",
+ "menu.properties": "屬性",
+ "menu.applicationPropertiesAria": "應用程式屬性",
+ "menu.methods": "方法",
+ "menu.applicationMethodsAria": "應用程式方法",
+ "menu.request": "Request",
+ "menu.requestOverviewAria": "Request概述",
+ "menu.requestPropertiesAria": "Request屬性",
+ "menu.response": "Response",
+ "menu.responseOverviewAria": "Response概述",
+ "menu.responsePropertiesAria": "Response屬性",
+ "menu.router": "Router",
+ "menu.routerOverviewAria": "Router概述",
+ "menu.routerMethodsAria": "Router方法",
+ "menu.community": "社群",
+ "menu.communityAria": "社群資源",
+ "menu.glossary": "詞彙表",
+ "menu.glossaryAria": "詞彙表",
+ "menu.middleware": "中介軟體",
+ "menu.middlewareAria": "中介軟體資源",
+ "menu.middlewareOverviewAria": "中介軟體概述",
+ "404.title": "404 - 頁面未找到",
+ "404.description": "您正在尋找的頁面無法找到。",
+ "404.heading": "頁面未找到",
+ "404.message": "您正在尋找的頁面不存在或已被移動。",
+ "404.goHome": "返回首頁",
+ "hero.tagline": "快速、無偏見、極簡主義的 Node.js Web 框架",
+ "hero.getStarted": "開始使用",
+ "hero.videoPause": "暫停背景影片",
+ "hero.videoPlay": "播放背景影片"
+}
diff --git a/astro/src/i18n/utils.ts b/astro/src/i18n/utils.ts
new file mode 100644
index 0000000000..21d3b1b620
--- /dev/null
+++ b/astro/src/i18n/utils.ts
@@ -0,0 +1,45 @@
+import { ui, defaultLang, languages } from './locales';
+
+export function getLangFromUrl(url: URL) {
+ const [, lang] = url.pathname.split('/');
+ if (lang in ui) return lang as keyof typeof ui;
+ return defaultLang;
+}
+
+export function useTranslations(lang: keyof typeof ui) {
+ return function t(key: keyof (typeof ui)[typeof defaultLang] | string): string {
+ return (
+ ui[lang][key as keyof (typeof ui)[typeof defaultLang]] ||
+ ui[defaultLang][key as keyof (typeof ui)[typeof defaultLang]] ||
+ key
+ );
+ };
+}
+
+/**
+ * Get all supported language codes
+ */
+export function getLanguageCodes(): string[] {
+ return Object.keys(languages);
+}
+
+/**
+ * Create a regex pattern to match language prefixes in URLs
+ */
+export function createLanguagePathRegex(): RegExp {
+ const codes = getLanguageCodes().join('|');
+ return new RegExp(`^/(${codes})/`);
+}
+
+/**
+ * Replace the language code in a path with a new one
+ */
+export function replaceLanguageInPath(path: string, newLang: string): string {
+ const langRegex = createLanguagePathRegex();
+
+ if (langRegex.test(path)) {
+ return path.replace(langRegex, `/${newLang}/`);
+ } else {
+ return `/${newLang}${path}`;
+ }
+}
diff --git a/astro/src/icons/bsky.svg b/astro/src/icons/bsky.svg
new file mode 100644
index 0000000000..470288aa8c
--- /dev/null
+++ b/astro/src/icons/bsky.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/astro/src/icons/github.svg b/astro/src/icons/github.svg
new file mode 100644
index 0000000000..e5c5a6896e
--- /dev/null
+++ b/astro/src/icons/github.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/astro/src/icons/logo-dark.svg b/astro/src/icons/logo-dark.svg
new file mode 100644
index 0000000000..0dc200a93c
--- /dev/null
+++ b/astro/src/icons/logo-dark.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/astro/src/icons/logo-express-black.svg b/astro/src/icons/logo-express-black.svg
new file mode 100644
index 0000000000..d9dace678c
--- /dev/null
+++ b/astro/src/icons/logo-express-black.svg
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/astro/src/icons/logo-express-white.svg b/astro/src/icons/logo-express-white.svg
new file mode 100644
index 0000000000..6b14ccf672
--- /dev/null
+++ b/astro/src/icons/logo-express-white.svg
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/astro/src/icons/logo-light.svg b/astro/src/icons/logo-light.svg
new file mode 100644
index 0000000000..1ba7920fd9
--- /dev/null
+++ b/astro/src/icons/logo-light.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/astro/src/icons/open-collective.svg b/astro/src/icons/open-collective.svg
new file mode 100644
index 0000000000..250d734a1f
--- /dev/null
+++ b/astro/src/icons/open-collective.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/astro/src/icons/slack.svg b/astro/src/icons/slack.svg
new file mode 100644
index 0000000000..c0b1f1156a
--- /dev/null
+++ b/astro/src/icons/slack.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/astro/src/icons/x.svg b/astro/src/icons/x.svg
new file mode 100644
index 0000000000..780ab6a346
--- /dev/null
+++ b/astro/src/icons/x.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/astro/src/icons/youtube.svg b/astro/src/icons/youtube.svg
new file mode 100644
index 0000000000..e8db9ce050
--- /dev/null
+++ b/astro/src/icons/youtube.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/astro/src/layouts/DocLayout.astro b/astro/src/layouts/DocLayout.astro
new file mode 100644
index 0000000000..42d7260a04
--- /dev/null
+++ b/astro/src/layouts/DocLayout.astro
@@ -0,0 +1,24 @@
+---
+import Layout from './Layout.astro';
+import type { BreadcrumbItem } from '@utils/content';
+import { Breadcrumbs } from '@components/patterns';
+import { Container } from '@/components/primitives';
+
+interface Props {
+ title: string;
+ description?: string;
+ breadcrumbs: BreadcrumbItem[];
+}
+
+const { title, description, breadcrumbs } = Astro.props;
+---
+
+
+
+
+
+
+
+
+
+
diff --git a/astro/src/layouts/Layout.astro b/astro/src/layouts/Layout.astro
new file mode 100644
index 0000000000..5e075a3a2d
--- /dev/null
+++ b/astro/src/layouts/Layout.astro
@@ -0,0 +1,117 @@
+---
+import '@styles/main.css';
+import { Flex, FlexItem } from '@components/primitives';
+import { Footer, Sidebar } from '@/components/patterns';
+import { Header } from '@/components/patterns';
+import { getLangFromUrl, replaceLanguageInPath } from '@/i18n/utils';
+import { languages } from '@/i18n/locales';
+
+interface Props {
+ title?: string;
+ description?: string;
+}
+
+const {
+ title = 'Express - Node.js web application framework',
+ description = 'Fast, unopinionated, minimalist web framework for Node.js',
+} = Astro.props;
+
+const isNetlify = import.meta.env.DEPLOY_PRIME_URL;
+
+const lang = getLangFromUrl(Astro.url);
+---
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {
+ Object.keys(languages).map((altLang) => (
+
+ ))
+ }
+
+ {title}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/astro/src/pages/404.astro b/astro/src/pages/404.astro
new file mode 100644
index 0000000000..3a7e077c19
--- /dev/null
+++ b/astro/src/pages/404.astro
@@ -0,0 +1,27 @@
+---
+import Layout from '@/layouts/Layout.astro';
+import { Icon } from 'astro-icon/components';
+import { Container, H1, H2, Body, Button, Flex } from '@components/primitives';
+---
+
+
+
+
+
404
+ Page Not Found
+
+ The page you are looking for does not exist or has been moved.
+
+
+ Go to Home
+
+
+ Raise a issue
+
+
+
+
+
diff --git a/astro/src/pages/[lang]/[...slug].astro b/astro/src/pages/[lang]/[...slug].astro
new file mode 100644
index 0000000000..26f3597a46
--- /dev/null
+++ b/astro/src/pages/[lang]/[...slug].astro
@@ -0,0 +1,161 @@
+---
+import { getCollection } from 'astro:content';
+import DocLayout from '@layouts/DocLayout.astro';
+import { languages } from '@i18n/locales';
+import { render } from 'astro:content';
+import { buildBreadcrumbs } from '@utils/content';
+
+export async function getStaticPaths() {
+ const DEFAULT_VERSION = '5x';
+ const VERSION_PREFIXES = ['5x', '4x', '3x'];
+ const DEFAULT_LANG = 'en';
+
+ const pages = await getCollection('docs');
+ const api = await getCollection('api');
+
+ const paths: Array<{
+ params: { lang: string; slug: string };
+ props: { page: (typeof pages)[0]; version: string };
+ }> = [];
+
+ // Helper to create a map of existing content for fallback logic
+ const existingContent = new Map();
+ pages.forEach((page) => {
+ const [lang, ...slugParts] = page.id.split('/');
+ const fullSlug = slugParts.join('/');
+ existingContent.set(`${lang}/${fullSlug}`, page);
+ });
+
+ api.forEach((page) => {
+ existingContent.set(`en/${page.id}`, page);
+ });
+
+ pages.forEach((page) => {
+ const [lang, ...slugParts] = page.id.split('/');
+ const fullSlug = slugParts.join('/');
+
+ const isVersioned = VERSION_PREFIXES.some((v) => fullSlug.startsWith(`${v}/`));
+
+ paths.push({
+ params: { lang, slug: fullSlug },
+ props: { page, version: isVersioned ? slugParts[0] : DEFAULT_VERSION },
+ });
+ });
+
+ for (const lang of Object.keys(languages)) {
+ api.forEach((page) => {
+ const slugParts = page.id.split('/');
+ const version = slugParts[0];
+ const slug = page.id;
+
+ paths.push({
+ params: { lang, slug },
+ props: { page, version },
+ });
+ });
+ }
+
+ const defaultVersionApiPages = api.filter((page) => page.id.startsWith(`${DEFAULT_VERSION}/`));
+
+ for (const lang of Object.keys(languages)) {
+ defaultVersionApiPages.forEach((page) => {
+ const [, ...restSlugParts] = page.id.split('/');
+ const nonVersionedSlug = restSlugParts.join('/');
+
+ const exists = paths.some(
+ (p) => p.params.lang === lang && p.params.slug === nonVersionedSlug
+ );
+
+ if (!exists && nonVersionedSlug) {
+ paths.push({
+ params: { lang, slug: nonVersionedSlug },
+ props: { page, version: DEFAULT_VERSION },
+ });
+ }
+ });
+ }
+
+ const defaultVersionPages = pages.filter((page) => {
+ const [, ...slugParts] = page.id.split('/');
+ return slugParts[0] === DEFAULT_VERSION;
+ });
+
+ defaultVersionPages.forEach((page) => {
+ const [lang, , ...restSlugParts] = page.id.split('/');
+ const nonVersionedSlug = restSlugParts.join('/');
+
+ const exists = paths.some((p) => p.params.lang === lang && p.params.slug === nonVersionedSlug);
+
+ if (!exists && nonVersionedSlug) {
+ paths.push({
+ params: { lang, slug: nonVersionedSlug },
+ props: { page, version: DEFAULT_VERSION },
+ });
+ }
+ });
+
+ // Fallback for non-versioned default-version slugs: use English content for missing languages
+ const englishDefaultVersionPages = defaultVersionPages.filter((p) =>
+ p.id.startsWith(`${DEFAULT_LANG}/`)
+ );
+
+ for (const lang of Object.keys(languages)) {
+ if (lang === DEFAULT_LANG) continue;
+
+ englishDefaultVersionPages.forEach((page) => {
+ const [, , ...restSlugParts] = page.id.split('/');
+ const nonVersionedSlug = restSlugParts.join('/');
+
+ const exists = paths.some(
+ (p) => p.params.lang === lang && p.params.slug === nonVersionedSlug
+ );
+
+ if (!exists && nonVersionedSlug) {
+ paths.push({
+ params: { lang, slug: nonVersionedSlug },
+ props: { page, version: DEFAULT_VERSION },
+ });
+ }
+ });
+ }
+
+ // Fallback: Create paths for non-English languages using English content
+ for (const lang of Object.keys(languages)) {
+ if (lang === DEFAULT_LANG) continue; // Skip English, already added
+
+ const englishPages = pages.filter((p) => p.id.startsWith(`${DEFAULT_LANG}/`));
+
+ englishPages.forEach((page) => {
+ const [, ...slugParts] = page.id.split('/');
+ const fullSlug = slugParts.join('/');
+
+ const langSpecificExists = paths.some(
+ (p) => p.params.lang === lang && p.params.slug === fullSlug
+ );
+
+ // If no language-specific version exists, add fallback to English
+ if (!langSpecificExists) {
+ paths.push({
+ params: { lang, slug: fullSlug },
+ props: {
+ page,
+ version: slugParts[0] === DEFAULT_VERSION ? DEFAULT_VERSION : slugParts[0],
+ },
+ });
+ }
+ });
+ }
+
+ return paths;
+}
+
+const { page, version } = Astro.props;
+const { lang, slug } = Astro.params;
+const { Content } = await render(page);
+const breadcrumbs = await buildBreadcrumbs(lang, slug, 'docs', version);
+const { title, description } = page.data;
+---
+
+
+
+
diff --git a/astro/src/pages/[lang]/blog/[...page].astro b/astro/src/pages/[lang]/blog/[...page].astro
new file mode 100644
index 0000000000..68e4a42e1d
--- /dev/null
+++ b/astro/src/pages/[lang]/blog/[...page].astro
@@ -0,0 +1,198 @@
+---
+import Layout from '@layouts/Layout.astro';
+import { languages } from '@i18n/locales';
+import { Container, Grid, Col, Tabs } from '@components/primitives';
+import type { TabItem } from '@components/primitives';
+import { PostCard, PageHead, Pagination } from '@components/patterns';
+import { getCollection, type CollectionEntry } from 'astro:content';
+import type { PaginateFunction } from 'astro';
+
+export async function getStaticPaths({ paginate }: { paginate: PaginateFunction }) {
+ const PAGE_SIZE = 6;
+ const allPosts = await getCollection('blog');
+
+ return Object.keys(languages).flatMap((lang) => {
+ const langPosts = allPosts
+ .filter((post) => post.id.startsWith('en/'))
+ .sort((a, b) => {
+ const aFile = a.id.split('/').pop() ?? '';
+ const bFile = b.id.split('/').pop() ?? '';
+ return bFile.localeCompare(aFile);
+ });
+
+ const allTags = [...new Set(langPosts.flatMap((p) => p.data.tags ?? []))];
+
+ return paginate(langPosts, {
+ params: { lang },
+ pageSize: PAGE_SIZE,
+ props: { allTags, langPosts, pageSize: PAGE_SIZE },
+ });
+ });
+}
+
+const { page, allTags, langPosts, pageSize } = Astro.props;
+const { lang } = Astro.params;
+const pagePosts = page.data as CollectionEntry<'blog'>[];
+
+function getDate(id: string) {
+ const filename = id.split('/').pop() ?? id;
+ return new Date(filename.substring(0, 10)).toLocaleDateString('en-US', {
+ month: 'short',
+ day: 'numeric',
+ year: 'numeric',
+ });
+}
+
+function formatTagLabel(tag: string) {
+ const spaced = tag.replace(/-/g, ' ');
+ return spaced.charAt(0).toUpperCase() + spaced.slice(1);
+}
+
+function getLabels(tags?: string[]) {
+ return (tags ?? []).map(formatTagLabel);
+}
+
+function getPostProps(post: CollectionEntry<'blog'>) {
+ return {
+ href: `/${lang}/blog/${post.id.split('/').pop()}`,
+ labels: getLabels(post.data.tags),
+ title: post.data.title,
+ coverSrc: '/posts/sample-cover.png',
+ authors: (post.data.authors ?? []).map((a) => ({
+ src: a.github ? `https://github.com/${a.github}.png` : '',
+ name: a.name ?? '',
+ })),
+ avatarCaption: getDate(post.id),
+ };
+}
+
+const filterTabs: TabItem[] = [
+ { label: 'All', value: 'all' },
+ ...(allTags as string[]).map((tag) => ({
+ label: formatTagLabel(tag),
+ value: tag,
+ })),
+];
+---
+
+
+
+
+
+
+ {
+ pagePosts.map((post) => (
+
+
+
+ ))
+ }
+
+
+
+ {
+ langPosts.map((post) => (
+
+
+
+ ))
+ }
+
+
+
+
+
diff --git a/astro/src/pages/[lang]/blog/[slug].astro b/astro/src/pages/[lang]/blog/[slug].astro
new file mode 100644
index 0000000000..d77f61bbef
--- /dev/null
+++ b/astro/src/pages/[lang]/blog/[slug].astro
@@ -0,0 +1,55 @@
+---
+import { getCollection, render } from 'astro:content';
+import Layout from '@layouts/Layout.astro';
+import { Container, H1, BodySm, Avatar } from '@/components/primitives';
+import { languages } from '@i18n/locales';
+
+export async function getStaticPaths() {
+ const posts = await getCollection('blog');
+ const enPosts = posts.filter((post) => post.id.startsWith('en/'));
+
+ return Object.keys(languages).flatMap((lang) =>
+ enPosts.map((post) => {
+ const filename = post.id.split('/').pop()!;
+ return {
+ params: { lang, slug: filename },
+ props: { post },
+ };
+ })
+ );
+}
+
+const { post } = Astro.props;
+const { Content } = await render(post);
+
+const { title, description, tags, authors } = post.data;
+const authorsList = (authors ?? []).map((a) => ({
+ src: a.github ? `https://github.com/${a.github}.png` : '',
+ name: a.name ?? '',
+}));
+const filename = post.id.split('/').pop() ?? post.id;
+const dateStr = filename.substring(0, 10);
+const date = new Date(dateStr).toLocaleDateString('en-US', {
+ month: 'long',
+ day: 'numeric',
+ year: 'numeric',
+});
+const label = tags?.[0] ?? '';
+---
+
+
+
+
+ {
+ label && (
+
+ {label}
+
+ )
+ }
+ {title}
+ {authorsList.length > 0 && }
+
+
+
+
diff --git a/astro/src/pages/[lang]/ds-foundations.astro b/astro/src/pages/[lang]/ds-foundations.astro
new file mode 100644
index 0000000000..80acc93489
--- /dev/null
+++ b/astro/src/pages/[lang]/ds-foundations.astro
@@ -0,0 +1,1349 @@
+---
+/**
+ * Design System Foundations Demo
+ *
+ * A single-page demo of all primitive components and tokens.
+ * TODO: This is a temporary page built to provide a reference for the design system. Can be replaced with a more comprehensive documentation site in the future.
+ */
+import { Icon } from 'astro-icon/components';
+import Layout from '@layouts/Layout.astro';
+import {
+ Container,
+ Grid,
+ Col,
+ Flex,
+ FlexItem,
+ H1,
+ H2,
+ H3,
+ H4,
+ H5,
+ Body,
+ BodyMd,
+ BodySm,
+ BodyXs,
+ Button,
+ Code,
+ Select,
+} from '@components/primitives';
+import { Code as CodeBlock } from 'astro:components';
+import { getLangFromUrl } from '@i18n/utils';
+import { languages } from '@i18n/locales';
+
+export function getStaticPaths() {
+ return Object.keys(languages).map((lang) => ({
+ params: { lang },
+ }));
+}
+
+const lang = getLangFromUrl(Astro.url);
+---
+
+
+
+
+
+
+
+
+
+
+
+ Typography
+
+
+
Headings
+
+
Heading 1 — Page titles
+ Heading 2 — Section titles
+ Heading 3 — Subsections
+ Heading 4 — Minor headings
+ Heading 5 — Lead/intro paragraph text
+
+
+
+
+
Body Text
+
+
Body — Default paragraph text. This is the standard size for documentation content
+ and general reading.
+
Body Medium — Slightly smaller than default body. Good for sidebars and secondary
+ content.
+
+ Body Small — Secondary text, captions, and helper text. Used for metadata and less
+ prominent content.
+
+
Body Extra Small — Fine print, legal text, and timestamps.
+
+
+
+
+
Inline Code
+
+ const express = require('express');
+ Inline code: Use npm install express to install.
+
+
+
+
+
Weights
+
+ Light 300
+ Normal 400
+ Medium 500
+ Semibold 600
+ Bold 700
+
+
+
+
+
Polymorphic Rendering
+
+
H1 styled, rendered as h2
+ Body text rendered as span (inline)
+
+
+
+
+
Type Scale
+
+
+
+ Aa
+ 6xl (54px)
+
+
+ Aa
+ 5xl (45px)
+
+
+ Aa
+ 4xl (36px)
+
+
+ Aa
+ 3xl (30px)
+
+
+ Aa
+ 2xl (24px)
+
+
+ Aa
+ xl (20px)
+
+
+ Aa
+ lg (18px)
+
+
+ Aa
+ base (16px)
+
+
+ Aa
+ sm (14px)
+
+
+ Aa
+ xs (12px)
+
+
+
+ Usage
+
+ h2 styled as H1
+This is body text. It renders a paragraph by default.
+const express = require('express');
+ `}
+ />
+
+
+
+
+ Iconography
+
+ Icons are provided by astro-icon, a well-supported and officially
+ recommended package for Astro that gives access to 200,000+ icons from various icon sets. We
+ primarily use Fluent Icons (prefix fluent:).
+
+
+
+
Examples
+
+
+
+
+
+
+
+
+
+
+
Usage
+
+
+ `}
+ />
+
+ Browse available icons at Phosphor Icons or explore other icon sets at Iconify .
+
+
+
+
+
+
+ Color Tokens
+
+
+
Primitive tokens
+
+
white
+
+ gray-50
+
+
+ gray-100
+
+
+ gray-200
+
+
+ gray-300
+
+
+ gray-400
+
+
+ gray-500
+
+
+ gray-600
+
+
+ gray-700
+
+
+ gray-800
+
+
+ gray-900
+
+
+ gray-950
+
+
black
+
+
+
+
+ sky-50
+
+
+ sky-500
+
+
+ sky-700
+
+
+ sky-800
+
+
+
+
+
+ green-50
+
+
+ green-300
+
+
+ green-500
+
+
+ green-700
+
+
+ green-900
+
+
+
+
+
+ amber-50
+
+
+ amber-300
+
+
+ amber-500
+
+
+ amber-600
+
+
+ amber-700
+
+
+ amber-900
+
+
+
+
+
+ red-50
+
+
+ red-300
+
+
+ red-500
+
+
+ red-600
+
+
+ red-700
+
+
+ red-900
+
+
+
+
+
+
+
Semantic tokens
+
+
+ bg-primary
+
+
+ bg-secondary
+
+
+ bg-tertiary
+
+
+ bg-inverse
+
+
+ bg-mute
+
+
+ bg-success
+
+
+ bg-warning
+
+
+ bg-error
+
+
+
+
+ text-primary
+
+
+ text-secondary
+
+
+ text-tertiary
+
+
+ text-inverse
+
+
+ text-mute
+
+
+ text-success
+
+
+ text-warning
+
+
+ text-error
+
+
+
+
+
+ border-primary
+
+
+ border-secondary
+
+
+ border-tertiary
+
+
+ border-inverse
+
+
+ border-mute
+
+
+ border-success
+
+
+ border-warning
+
+
+ border-error
+
+
+
+
+
+ Usage
+
+
+
+
+
+ Spacing
+
+
+
+ Usage
+
+
+
+
+
+
+
+
+
+
+
+ Grid & Layout
+
+ 12-column responsive grid system with Grid, Col, and Flex components.
+
+
+
+
Grid Component
+
+ Responsive 12-column grid. Columns cascade from xs → md → lg.
+
+
+
+
+
+ xs=12, md=6, lg=4
+
+
+
+
+ xs=12, md=6, lg=4
+
+
+
+
+ xs=12, md=12, lg=4
+
+
+
+
+
Usage
+
+ Content
+ Content
+ Content
+
+ `}
+ />
+
+
+
+
Flex Component
+
Flexbox layouts for 1D directional content.
+
+
+
+ Item 1
+
+
+ Item 2
+
+
+ Item 3
+
+
+
+
Usage
+
+ Item 1
+ Item 2
+
+ `}
+ />
+
+
+
+
FlexItem Component
+
Control flex-grow, flex-shrink, and flex-basis for individual flex children.
+
+
Equal Columns
+
+
+
+ flex="1"
+
+
+ flex="1"
+
+
+ flex="1"
+
+
+
+
+
Different Basis & Grow
+
+
+
+
+ FlexItem basis="1/4"
+
+
+
+
+ FlexItem (grow="1")
+
+
+
+
+
+
Usage
+
+ Equal column
+ Sidebar
+ Flexible content
+
+ `}
+ />
+
+
+
+
Container
+
+ Centered, responsive content wrapper with max-width and padding.
+
+
+
+
+ Content centered with max-width: 1440px, width: 90-95%
+
+
+
+
+ Usage
+
+ Your content here
+
+ `}
+ />
+
+
+
+
+ Breakpoints
+
+
+
+ Current: Mobile (xs) < 768px
+ Current: Tablet (md) 768px – 1439px
+ Current: Desktop (lg) ≥ 1440px
+
+
+
+
+
Usage
+
+
+
+
+
+
+
+
diff --git a/astro/src/pages/[lang]/index.astro b/astro/src/pages/[lang]/index.astro
new file mode 100644
index 0000000000..5355d7048d
--- /dev/null
+++ b/astro/src/pages/[lang]/index.astro
@@ -0,0 +1,51 @@
+---
+import { Hero, Features, Banner } from '@components/patterns';
+import { BodyMd, Card, Col } from '@components/primitives';
+import Layout from '@layouts/Layout.astro';
+import { languages } from '@i18n/locales';
+import { getLangFromUrl, useTranslations } from '@i18n/utils';
+
+export function getStaticPaths() {
+ return Object.keys(languages).map((lang) => ({
+ params: { lang },
+ }));
+}
+
+const lang = getLangFromUrl(Astro.url);
+const t = useTranslations(lang);
+---
+
+
+
+
+ Express 5.1.0 is now the default on npm, and we're introducing an official LTS schedule for
+ the v4 and v5 release lines. Check out our latest blog for more information.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/astro/src/pages/[lang]/resources/[...slug].astro b/astro/src/pages/[lang]/resources/[...slug].astro
new file mode 100644
index 0000000000..2b92154f92
--- /dev/null
+++ b/astro/src/pages/[lang]/resources/[...slug].astro
@@ -0,0 +1,31 @@
+---
+import { getCollection } from 'astro:content';
+import DocLayout from '@layouts/DocLayout.astro';
+import { render } from 'astro:content';
+import { buildBreadcrumbs } from '@utils/content';
+
+export async function getStaticPaths() {
+ const pages = await getCollection('resources');
+ return pages.map((page) => {
+ const [lang, ...slugParts] = page.id.split('/');
+
+ return {
+ params: {
+ lang,
+ slug: slugParts.join('/'),
+ },
+ props: { page },
+ };
+ });
+}
+
+const { page } = Astro.props;
+const { lang, slug } = Astro.params;
+const { Content } = await render(page);
+const breadcrumbs = await buildBreadcrumbs(lang, slug, 'resources');
+const { title, description } = page.data;
+---
+
+
+
+
diff --git a/astro/src/pages/[lang]/support/index.astro b/astro/src/pages/[lang]/support/index.astro
new file mode 100644
index 0000000000..b9d7446b41
--- /dev/null
+++ b/astro/src/pages/[lang]/support/index.astro
@@ -0,0 +1,24 @@
+---
+/**
+ * Express Documentation Index Page
+ *
+ * TODO: This is a temporary index page for support page. This will be replaced with a proper support layout in the future.
+ */
+import Layout from '@layouts/Layout.astro';
+import { languages } from '@i18n/locales';
+import { Container } from '@/components/primitives';
+
+export function getStaticPaths() {
+ return Object.keys(languages).map((lang) => ({
+ params: { lang },
+ }));
+}
+---
+
+
+
+ Express Version Support
+ This is a temporary entry point page for the Express support.
+ This page will be replaced with a proper support layout soon.
+
+
diff --git a/astro/src/pages/feed.xml.ts b/astro/src/pages/feed.xml.ts
new file mode 100644
index 0000000000..0041a0e99a
--- /dev/null
+++ b/astro/src/pages/feed.xml.ts
@@ -0,0 +1,31 @@
+import rss from '@astrojs/rss';
+import { getCollection } from 'astro:content';
+import type { APIRoute } from 'astro';
+import {
+ getLinkedTitleContent,
+ getAuthorsCustomData,
+ getPubDateFromId,
+ shouldIncludeInFeed,
+ sortByIdDateDesc,
+} from '@/utils/rss';
+
+export const GET: APIRoute = async (context) => {
+ const site = context.site as URL;
+ const blog = await getCollection('blog');
+ const sortedBlog = sortByIdDateDesc(blog.filter((post) => shouldIncludeInFeed(post.id)));
+
+ return rss({
+ title: 'The Express.js Blog',
+ description: 'News and updates about express.js',
+ site: site.href,
+ items: sortedBlog.map((post) => ({
+ link: `/blog/${post.id}/`,
+ title: post.data.title,
+ pubDate: getPubDateFromId(post.id),
+ description: post.data.description,
+ content: getLinkedTitleContent(post.data.title, post.id, site),
+ categories: post.data.tags,
+ customData: getAuthorsCustomData(post.data.authors),
+ })),
+ });
+};
diff --git a/astro/src/pages/index.astro b/astro/src/pages/index.astro
new file mode 100644
index 0000000000..655eb6cb65
--- /dev/null
+++ b/astro/src/pages/index.astro
@@ -0,0 +1 @@
+
diff --git a/astro/src/pages/robots.txt.ts b/astro/src/pages/robots.txt.ts
new file mode 100644
index 0000000000..9c3032c062
--- /dev/null
+++ b/astro/src/pages/robots.txt.ts
@@ -0,0 +1,23 @@
+import type { APIRoute } from 'astro';
+
+const getRobotsTxt = (sitemapURL: URL) => `\
+User-agent: *
+Allow: /
+
+Sitemap: ${sitemapURL.href}
+`;
+
+const getBlockedRobotsTxt = () => `\
+User-agent: *
+Disallow: /
+`;
+
+export const GET: APIRoute = ({ site }) => {
+ // Netlify builds should not be indexed.
+ if (import.meta.env.DEPLOY_PRIME_URL) {
+ return new Response(getBlockedRobotsTxt());
+ }
+
+ const sitemapURL = new URL('sitemap-index.xml', site);
+ return new Response(getRobotsTxt(sitemapURL));
+};
diff --git a/astro/src/pages/vulnerabilities.xml.ts b/astro/src/pages/vulnerabilities.xml.ts
new file mode 100644
index 0000000000..4a568c9aa7
--- /dev/null
+++ b/astro/src/pages/vulnerabilities.xml.ts
@@ -0,0 +1,35 @@
+import rss from '@astrojs/rss';
+import { getCollection } from 'astro:content';
+import type { APIRoute } from 'astro';
+import {
+ getLinkedTitleContent,
+ getAuthorsCustomData,
+ getPubDateFromId,
+ shouldIncludeInFeed,
+ sortByIdDateDesc,
+} from '@/utils/rss';
+
+export const GET: APIRoute = async (context) => {
+ const site = context.site as URL;
+ const blog = await getCollection('blog');
+ const securityPosts = sortByIdDateDesc(
+ blog.filter(
+ (post) => shouldIncludeInFeed(post.id) && (post.data.tags ?? []).includes('security')
+ )
+ );
+
+ return rss({
+ title: 'Express.js Security Feed',
+ description: 'Posts tagged as security from the Express.js blog.',
+ site: site.href,
+ items: securityPosts.map((post) => ({
+ link: `/blog/${post.id}/`,
+ title: post.data.title,
+ pubDate: getPubDateFromId(post.id),
+ description: post.data.description,
+ content: getLinkedTitleContent(post.data.title, post.id, site),
+ categories: post.data.tags,
+ customData: getAuthorsCustomData(post.data.authors),
+ })),
+ });
+};
diff --git a/astro/src/styles/base/_expressive-code.css b/astro/src/styles/base/_expressive-code.css
new file mode 100644
index 0000000000..dbb335d318
--- /dev/null
+++ b/astro/src/styles/base/_expressive-code.css
@@ -0,0 +1,24 @@
+/**
+ * Expressive Code Global Styles
+ *
+ * Applied to all expressive-code blocks across the app
+ * Using higher specificity selectors to override expressive-code defaults
+ */
+
+/* Increase specificity by doubling the class selector */
+.expressive-code.expressive-code {
+ .copy {
+ top: var(--space-3);
+ right: var(--space-3);
+ height: var(--size-5);
+ }
+
+ figcaption:not(:empty) ~ .copy {
+ top: var(--space-10);
+ }
+}
+
+.expressive-code.expressive-code .feedback {
+ line-height: var(--line-height-snug);
+ font-family: var(--font-family-body);
+}
diff --git a/astro/src/styles/base/_fonts.css b/astro/src/styles/base/_fonts.css
new file mode 100644
index 0000000000..1101ee226c
--- /dev/null
+++ b/astro/src/styles/base/_fonts.css
@@ -0,0 +1,24 @@
+/**
+ * Font Face Declarations
+ *
+ * Self-hosted JetBrains Mono for code blocks.
+ * Currently only Light (300) weight is used across the site.
+ * Using font-display: swap for better performance.
+ */
+
+/* JetBrains Mono - Light */
+@font-face {
+ font-family: 'JetBrains Mono';
+ src: url('/fonts/JetBrainsMono-Light.woff2') format('woff2');
+ font-weight: 300;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'JetBrains Mono';
+ src: url('/fonts/JetBrainsMono-LightItalic.woff2') format('woff2');
+ font-weight: 300;
+ font-style: italic;
+ font-display: swap;
+}
diff --git a/astro/src/styles/base/_global.css b/astro/src/styles/base/_global.css
new file mode 100644
index 0000000000..538b722ff8
--- /dev/null
+++ b/astro/src/styles/base/_global.css
@@ -0,0 +1,254 @@
+/**
+ * Global Base Styles (layer: base)
+ *
+ * Applies design tokens to base HTML elements
+ */
+
+html {
+ font-family: var(--font-family-body);
+ font-size: 62.5%;
+ color: var(--color-text-primary);
+ background-color: var(--color-bg-primary);
+ scroll-behavior: smooth;
+ -moz-text-size-adjust: none;
+ -webkit-text-size-adjust: none;
+ text-size-adjust: none;
+ box-sizing: border-box;
+
+ *,
+ *:before,
+ *:after {
+ box-sizing: inherit;
+ }
+}
+
+body {
+ font-family: var(--font-family-body);
+ font-size: var(--font-size-body);
+ line-height: var(--line-height-body);
+ background-color: var(--color-bg-primary);
+ text-rendering: optimizeLegibility;
+}
+
+/* Headings */
+h1,
+.h1,
+h2,
+.h2,
+h3,
+.h3,
+h4,
+.h4,
+h5,
+.h5,
+h6,
+.h6 {
+ font-weight: var(--font-weight-medium);
+ line-height: var(--line-height-tight);
+ letter-spacing: var(--letter-spacing-tight);
+ margin: 0;
+}
+
+h1,
+.h1 {
+ font-size: var(--font-size-h1);
+ margin: var(--space-h1) 0;
+}
+
+h2,
+.h2 {
+ font-size: var(--font-size-h2);
+ margin: var(--space-h2) 0;
+}
+
+h3,
+.h3 {
+ font-size: var(--font-size-h3);
+ margin: var(--space-h3) 0;
+}
+
+h4,
+.h4 {
+ font-size: var(--font-size-h4);
+ margin: var(--space-h4) 0;
+}
+
+h5,
+.h5 {
+ font-size: var(--font-size-lg);
+ font-weight: var(--font-weight-normal);
+ line-height: var(--line-height-relaxed);
+ margin: var(--space-body) 0;
+}
+
+h6,
+.h6 {
+ font-size: var(--font-size-base);
+ margin: var(--space-body) 0;
+}
+
+p,
+.body {
+ font-family: var(--font-family-body);
+ font-size: var(--font-size-body);
+ font-weight: var(--font-weight-normal);
+ line-height: var(--line-height-body);
+ letter-spacing: var(--letter-spacing-body);
+ margin: var(--space-body) 0;
+}
+
+span,
+.body-md {
+ font-family: var(--font-family-body);
+ font-weight: var(--font-weight-normal);
+ line-height: var(--line-height-normal);
+}
+
+.body-md {
+ margin: var(--space-body) 0;
+ font-size: var(--font-size-sm);
+}
+
+small,
+.body-sm {
+ font-family: var(--font-family-body);
+ font-weight: var(--font-weight-normal);
+ line-height: var(--line-height-normal);
+ margin: var(--space-body) 0;
+}
+
+.body-sm {
+ font-size: var(--font-size-xs);
+}
+
+.body-xs {
+ font-family: var(--font-family-body);
+ font-size: var(--font-size-xxs);
+ font-weight: var(--font-weight-normal);
+ line-height: var(--line-height-normal);
+ margin: var(--space-body) 0;
+}
+
+/* Links */
+a {
+ color: var(--color-link);
+ text-decoration: underline;
+ text-underline-offset: 0.15em;
+ transition: var(--transition-colors);
+}
+
+a:hover {
+ color: var(--color-link-hover);
+}
+
+a:focus-visible,
+button:focus-visible,
+input:focus-visible,
+select:focus-visible,
+textarea:focus-visible,
+[tabindex]:focus-visible {
+ outline: 1px solid var(--color-focus-ring);
+ outline-offset: -2px;
+}
+
+/* Code */
+code,
+kbd,
+samp,
+pre {
+ font-family: var(--font-family-code);
+ font-size: var(--font-size-code);
+
+ *,
+ *:before,
+ *:after {
+ font-family: inherit;
+ }
+}
+
+code,
+.code {
+ font-family: var(--font-family-code);
+ font-size: var(--font-size-code);
+ font-weight: var(--font-weight-normal);
+ line-height: var(--line-height-snug);
+ background-color: var(--color-bg-tertiary);
+ padding: var(--space-0-5) var(--space-1);
+ border-radius: var(--radius-base);
+ letter-spacing: var(--letter-spacing-normal);
+}
+
+pre {
+ padding: var(--space-4);
+ background-color: var(--color-pre-bg);
+ color: var(--color-pre-fg);
+ border-radius: var(--radius-lg);
+ overflow-x: auto;
+}
+
+pre code {
+ padding: 0;
+ background: none;
+ border-radius: 0;
+}
+
+/* Blockquote */
+blockquote {
+ padding-left: var(--space-4);
+ border-left: var(--border-width-4) solid var(--color-border-primary);
+ font-style: italic;
+}
+
+/* Horizontal rule */
+hr {
+ border: none;
+ border-top: var(--border-width-1) solid var(--color-border-primary);
+ margin: var(--space-8) 0;
+}
+
+/* Tables */
+table {
+ width: 100%;
+ border-collapse: collapse;
+}
+
+th,
+td {
+ padding: var(--space-3) var(--space-4);
+ text-align: left;
+ border-bottom: var(--border-width-1) solid var(--color-border-primary);
+}
+
+th {
+ font-weight: var(--font-weight-semibold);
+}
+
+/* Lists */
+ul,
+ol {
+ margin: var(--space-body) 0;
+ padding-left: var(--space-6);
+}
+
+main {
+ flex-grow: 1;
+ padding-bottom: var(--space-16);
+
+ @media (--md-up) {
+ padding-top: var(--space-16);
+ padding-bottom: var(--space-32);
+ }
+}
+
+@media (--md-up) {
+ .layout-wrapper {
+ background-color: var(--color-bg-secondary);
+ }
+ .layout-content {
+ background-color: var(--color-bg-primary);
+ }
+}
+
+.layout-content {
+ min-width: 0;
+}
diff --git a/astro/src/styles/base/_reset.css b/astro/src/styles/base/_reset.css
new file mode 100644
index 0000000000..04353be936
--- /dev/null
+++ b/astro/src/styles/base/_reset.css
@@ -0,0 +1,82 @@
+/**
+ * CSS Reset (layer: reset)
+ *
+ * Modern CSS reset based on Josh Comeau's reset
+ * https://www.joshwcomeau.com/css/custom-css-reset/
+ */
+
+/* Box sizing rules */
+*,
+*::before,
+*::after {
+ box-sizing: border-box;
+}
+
+/* Remove default margin and padding */
+* {
+ margin: 0;
+ padding: 0;
+}
+
+/* Set core body defaults */
+body {
+ min-height: 100vh;
+ -webkit-font-smoothing: antialiased;
+}
+
+/* Remove list styles on ul, ol elements with a list role */
+ul[role='list'],
+ol[role='list'] {
+ list-style: none;
+}
+
+/* Set shorter line heights on interactive elements */
+button,
+input,
+label {
+ line-height: 1.1;
+}
+
+/* Balance text wrapping on headings */
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ text-wrap: balance;
+}
+
+/* Better text decoration rendering */
+a {
+ text-decoration-skip-ink: auto;
+}
+
+/* Make images easier to work with */
+img,
+picture,
+video,
+canvas,
+svg {
+ display: block;
+ max-width: 100%;
+}
+
+/* Inherit fonts for inputs and buttons */
+input,
+button,
+textarea,
+select {
+ font: inherit;
+ color: inherit;
+}
+
+/* Make sure textareas without a rows attribute are not tiny */
+textarea:not([rows]) {
+ min-height: 10em;
+}
+
+/* Anything that has been anchored to should have extra scroll margin */
+:target {
+ scroll-margin-block: 5ex;
+}
diff --git a/astro/src/styles/main.css b/astro/src/styles/main.css
new file mode 100644
index 0000000000..ad16559b4c
--- /dev/null
+++ b/astro/src/styles/main.css
@@ -0,0 +1,26 @@
+/**
+ * Main Stylesheet
+ *
+ * Entry point for all styles
+ * Import this file in your layout
+ *
+ * CSS Cascade Layers order (lowest to highest priority):
+ * 1. base - Global styles (reset, fonts, global, utilities)
+ * 2. primitives - Primitive component styles
+ * 3. patterns - Pattern component styles
+ *
+ * Layer order is defined in Layout.astro
+ * Layers ensure correct specificity order regardless of bundle order
+ */
+
+/* Design Tokens - CSS custom properties (OUTSIDE layers for global access) */
+@import './tokens/index.css';
+
+/* Import base styles into the base layer */
+@import './base/_reset.css' layer(base);
+@import './base/_fonts.css' layer(base);
+@import './base/_global.css' layer(base);
+@import './utilities/_utilities.css' layer(base);
+
+/* Import expressive-code customizations OUTSIDE layers for highest priority */
+@import './base/_expressive-code.css';
diff --git a/astro/src/styles/tokens/_borders.css b/astro/src/styles/tokens/_borders.css
new file mode 100644
index 0000000000..80ea81603e
--- /dev/null
+++ b/astro/src/styles/tokens/_borders.css
@@ -0,0 +1,31 @@
+/**
+ * Border Tokens
+ *
+ * Border widths and radius
+ */
+
+:root {
+ /* Border Widths */
+ --border-width-0: 0px;
+ --border-width-1: 1px;
+ --border-width-2: 2px;
+ --border-width-4: 4px;
+ --border-width-8: 8px;
+
+ /* Border Radius */
+ --radius-none: 0;
+ --radius-sm: 0.2rem; /* 2px */
+ --radius-base: 0.4rem; /* 4px */
+ --radius-md: 0.6rem; /* 6px */
+ --radius-lg: 0.8rem; /* 8px */
+ --radius-xl: 1.2rem; /* 12px */
+ --radius-2xl: 1.6rem; /* 16px */
+ --radius-3xl: 2.4rem; /* 24px */
+ --radius-full: 9999px;
+
+ /* Semantic */
+ --radius-button: var(--radius-md);
+ --radius-input: var(--radius-md);
+ --radius-card: var(--radius-lg);
+ --radius-badge: var(--radius-full);
+}
diff --git a/astro/src/styles/tokens/_breakpoints.css b/astro/src/styles/tokens/_breakpoints.css
new file mode 100644
index 0000000000..21bcc232a8
--- /dev/null
+++ b/astro/src/styles/tokens/_breakpoints.css
@@ -0,0 +1,46 @@
+/**
+ * Breakpoint Tokens
+ *
+ * Design breakpoints:
+ * - Mobile: < 768px
+ * - Tablet: 768px - 1439px
+ * - Desktop: >= 1440px
+ *
+ * Usage:
+ * @media (--xs-only) { ... } - Mobile only
+ * @media (--md-only) { ... } - Tablet only
+ * @media (--md-up) { ... } - Above Tablet
+ * @media (--lg-up) { ... } - Above Desktop
+ * @media (--lg-down) { ... } - Below Desktop
+ */
+
+/* ============================================
+ CUSTOM MEDIA QUERIES
+ ============================================ */
+
+/* Device-specific (exclusive) */
+@custom-media --xs-only (width < 768px);
+@custom-media --md-up (width >= 768px);
+@custom-media --md-only (768px <= width < 1440px);
+@custom-media --lg-up (width >= 1440px);
+@custom-media --lg-down (width < 1440px);
+
+/* Range queries (inclusive) */
+
+/* ============================================
+ BREAKPOINT VALUES (for JavaScript)
+
+ Note: CSS custom properties cannot be used in
+ @media or @custom-media queries. These are exposed
+ for documentation (to have a human-readable reference) and
+ for JavaScript access via getComputedStyle().
+
+ Example:
+ const bp = getComputedStyle(document.documentElement)
+ .getPropertyValue('--breakpoint-md');
+ ============================================ */
+
+:root {
+ --breakpoint-md: 768px;
+ --breakpoint-lg: 1440px;
+}
diff --git a/astro/src/styles/tokens/_colors.css b/astro/src/styles/tokens/_colors.css
new file mode 100644
index 0000000000..afd5e30c8f
--- /dev/null
+++ b/astro/src/styles/tokens/_colors.css
@@ -0,0 +1,160 @@
+:root {
+ /**
+ * Theme behavior:
+ * - Default: follows system preference (prefers-color-scheme)
+ * - Override: user can set [data-theme="light|dark"] on
+ */
+ color-scheme: light dark;
+
+ /* ============================================
+ PRIMITIVE TOKENS
+ ============================================ */
+
+ --white: oklch(100% 0 0); /* #FFFFFF */
+ --black: oklch(0% 0 0); /* #000000 */
+
+ --gray-50: oklch(98% 0 0); /* #FAFAFA */
+ --gray-100: oklch(97% 0 0); /* #F6F6F6 */
+ --gray-150: oklch(94% 0 0); /* #EEEEEE */
+ --gray-200: oklch(92% 0 0); /* #E5E5E5 */
+ --gray-300: oklch(87% 0 0); /* #D4D4D4 */
+ --gray-400: oklch(70% 0 0); /* #A3A3A3 */
+ --gray-500: oklch(55% 0 0); /* #737373 */
+ --gray-550: oklch(50% 0 0); /* #626262 */
+ --gray-600: oklch(45% 0 0); /* #525252 */
+ --gray-700: oklch(35% 0 0); /* #404040 */
+ --gray-800: oklch(25% 0 0); /* #262626 */
+ --gray-900: oklch(19% 0 1); /* #141414 */
+ --gray-950: oklch(13% 0 0); /* #0A0A0A */
+
+ /* Green */
+ --green-50: oklch(97% 0.02 155); /* #F0FDF4 */
+ --green-100: oklch(94% 0.04 155); /* #DCFCE7 */
+ --green-200: oklch(89% 0.08 155); /* #BBF7D0 */
+ --green-300: oklch(81% 0.13 155); /* #86EFAC */
+ --green-400: oklch(70% 0.17 155); /* #4ADE80 */
+ --green-500: oklch(62% 0.19 155); /* #22C55E */
+ --green-600: oklch(53% 0.17 155); /* #16A34A */
+ --green-700: oklch(46% 0.14 155); /* #15803D */
+ --green-800: oklch(39% 0.11 155); /* #166534 */
+ --green-900: oklch(34% 0.09 155); /* #14532D */
+ --green-950: oklch(20% 0.06 155); /* #052E16 */
+
+ /* Blue */
+ --blue-50: oklch(97% 0.01 250); /* #EFF6FF */
+ --blue-100: oklch(94% 0.03 250); /* #DBEAFE */
+ --blue-200: oklch(88% 0.06 250); /* #BFDBFE */
+ --blue-300: oklch(79% 0.11 250); /* #93C5FD */
+ --blue-400: oklch(69% 0.15 250); /* #60A5FA */
+ --blue-500: oklch(60% 0.18 250); /* #3B82F6 */
+ --blue-600: oklch(53% 0.2 250); /* #2563EB */
+ --blue-700: oklch(47% 0.19 250); /* #1D4ED8 */
+ --blue-800: oklch(41% 0.16 250); /* #1E40AF */
+ --blue-900: oklch(37% 0.13 250); /* #1E3A8A */
+ --blue-950: oklch(26% 0.1 250); /* #172554 */
+ --blue-975: oklch(18% 0.06 250);
+
+ --sky-500: oklch(71% 0.16 237); /* #0EA5E9 */
+ --sky-700: oklch(48% 0.22 237); /* #0369A1 */
+
+ /* Amber */
+ --amber-50: oklch(98% 0.03 85); /* #FFFBEB */
+ --amber-100: oklch(94% 0.07 85); /* #FEF3C7 */
+ --amber-200: oklch(89% 0.12 85); /* #FDE68A */
+ --amber-300: oklch(83% 0.16 80); /* #FCD34D */
+ --amber-400: oklch(78% 0.17 70); /* #FBBF24 */
+ --amber-500: oklch(73% 0.17 60); /* #F59E0B */
+ --amber-600: oklch(64% 0.17 50); /* #D97706 */
+ --amber-700: oklch(53% 0.15 50); /* #B45309 */
+ --amber-800: oklch(45% 0.12 50); /* #92400E */
+ --amber-900: oklch(39% 0.1 50); /* #78350F */
+ --amber-950: oklch(25% 0.07 50); /* #451A03 */
+
+ /* Red */
+ --red-50: oklch(97% 0.01 25); /* #FEF2F2 */
+ --red-100: oklch(94% 0.03 25); /* #FEE2E2 */
+ --red-200: oklch(89% 0.06 25); /* #FECACA */
+ --red-300: oklch(81% 0.11 25); /* #FCA5A5 */
+ --red-400: oklch(70% 0.17 25); /* #F87171 */
+ --red-500: oklch(62% 0.21 25); /* #EF4444 */
+ --red-600: oklch(54% 0.22 25); /* #DC2626 */
+ --red-700: oklch(47% 0.19 25); /* #B91C1C */
+ --red-800: oklch(40% 0.16 25); /* #991B1B */
+ --red-900: oklch(36% 0.13 25); /* #7F1D1D */
+ --red-950: oklch(22% 0.09 25); /* #450A0A */
+
+ /* ============================================
+ SEMANTIC TOKENS
+ Using light-dark(light-value, dark-value)
+ ============================================ */
+
+ /* Backgrounds */
+ --color-bg-primary: light-dark(var(--white), var(--black));
+ --color-bg-secondary: light-dark(var(--gray-50), var(--gray-900));
+ --color-bg-tertiary: light-dark(var(--gray-150), var(--gray-800));
+ --color-bg-inverse: light-dark(var(--gray-900), var(--gray-100));
+ --color-bg-inverse-secondary: light-dark(var(--gray-800), var(--gray-200));
+ --color-bg-mute: light-dark(var(--gray-200), var(--gray-600));
+ --color-bg-info: light-dark(var(--blue-50), var(--blue-975));
+ --color-bg-success: light-dark(var(--green-50), var(--green-950));
+ --color-bg-warning: light-dark(var(--amber-50), var(--amber-950));
+ --color-bg-error: light-dark(var(--red-50), var(--red-950));
+
+ /* Borders */
+ --color-border-primary: light-dark(var(--gray-300), var(--gray-500));
+ --color-border-secondary: light-dark(var(--gray-200), var(--gray-800));
+ --color-border-tertiary: light-dark(var(--gray-400), var(--gray-400));
+ --color-border-mute: light-dark(var(--gray-300), var(--gray-700));
+ --color-border-inverse: light-dark(var(--gray-700), var(--gray-200));
+ --color-border-info: light-dark(var(--blue-200), var(--blue-950));
+ --color-border-success: light-dark(var(--green-200), var(--green-800));
+ --color-border-warning: light-dark(var(--amber-200), var(--amber-800));
+ --color-border-error: light-dark(var(--red-200), var(--red-800));
+
+ /* Text */
+ --color-text-primary: light-dark(var(--gray-900), var(--gray-100));
+ --color-text-secondary: light-dark(var(--gray-600), var(--gray-150));
+ --color-text-tertiary: var(--gray-500, var(--gray-550));
+ --color-text-inverse: light-dark(var(--gray-100), var(--gray-900));
+ --color-text-mute: var(--gray-500, var(--gray-550));
+ --color-text-info: light-dark(var(--blue-700), var(--blue-400));
+ --color-text-success: light-dark(var(--green-700), var(--green-400));
+ --color-text-warning: light-dark(var(--amber-700), var(--amber-400));
+ --color-text-error: light-dark(var(--red-700), var(--red-400));
+
+ /* Icons */
+ --color-icon-primary: light-dark(var(--gray-900), var(--gray-50));
+ --color-icon-secondary: light-dark(var(--gray-500), var(--gray-400));
+
+ /* ============================================
+ COMPONENT TOKENS
+ ============================================ */
+
+ /* Buttons */
+ --color-button-primary-bg: light-dark(var(--gray-900), var(--white));
+ --color-button-primary-text: light-dark(var(--white), var(--black));
+ --color-button-primary-bg-hover: light-dark(var(--gray-800), var(--gray-200));
+
+ /* Links */
+ --color-link: light-dark(var(--sky-500), var(--sky-500));
+ --color-link-hover: light-dark(var(--sky-500), var(--sky-700));
+ --color-link-visited: light-dark(var(--sky-700), var(--sky-700));
+ /* Focus */
+ --color-focus-ring: light-dark(var(--gray-900), var(--white));
+
+ /* Overlay */
+ --color-overlay: color-mix(in oklch, var(--color-bg-secondary) 90%, transparent);
+}
+
+/* ============================================
+ THEME OVERRIDES
+ Force specific theme via data attribute
+ ============================================ */
+
+[data-theme='light'] {
+ color-scheme: light;
+}
+
+[data-theme='dark'] {
+ color-scheme: dark;
+}
diff --git a/astro/src/styles/tokens/_sizing.css b/astro/src/styles/tokens/_sizing.css
new file mode 100644
index 0000000000..d0eaadb528
--- /dev/null
+++ b/astro/src/styles/tokens/_sizing.css
@@ -0,0 +1,50 @@
+/**
+ * Sizing tokens
+ *
+ * Based on a 4px grid system (0.25rem)
+ * Used for width, height, max-width, max-height, etc.
+ */
+
+:root {
+ --size-0: 0;
+ --size-px: 1px;
+ --size-0-5: 0.2rem; /* 2px */
+ --size-1: 0.4rem; /* 4px */
+ --size-1-5: 0.6rem; /* 6px */
+ --size-2: 0.8rem; /* 8px */
+ --size-2-5: 1rem; /* 10px */
+ --size-3: 1.2rem; /* 12px */
+ --size-3-5: 1.4rem; /* 14px */
+ --size-4: 1.6rem; /* 16px */
+ --size-5: 2rem; /* 20px */
+ --size-6: 2.4rem; /* 24px */
+ --size-7: 2.8rem; /* 28px */
+ --size-8: 3.2rem; /* 32px */
+ --size-9: 3.6rem; /* 36px */
+ --size-10: 4rem; /* 40px */
+ --size-11: 4.4rem; /* 44px */
+ --size-12: 4.8rem; /* 48px */
+ --size-14: 5.6rem; /* 56px */
+ --size-16: 6.4rem; /* 64px */
+ --size-20: 8rem; /* 80px */
+ --size-24: 9.6rem; /* 96px */
+ --size-28: 11.2rem; /* 112px */
+ --size-32: 12.8rem; /* 128px */
+ --size-36: 14.4rem; /* 144px */
+ --size-40: 16rem; /* 160px */
+ --size-44: 17.6rem; /* 176px */
+ --size-48: 19.2rem; /* 192px */
+ --size-52: 20.8rem; /* 208px */
+ --size-56: 22.4rem; /* 224px */
+ --size-60: 24rem; /* 240px */
+ --size-64: 25.6rem; /* 256px */
+ --size-68: 27.2rem; /* 272px */
+ --size-72: 28.8rem; /* 288px */
+ --size-76: 30.4rem; /* 304px */
+ --size-80: 32rem; /* 320px */
+ --size-84: 33.6rem; /* 336px */
+ --size-88: 35.2rem; /* 352px */
+ --size-92: 36.8rem; /* 368px */
+ --size-96: 38.4rem; /* 384px */
+ --size-100: 40rem; /* 400px */
+}
diff --git a/astro/src/styles/tokens/_spacing.css b/astro/src/styles/tokens/_spacing.css
new file mode 100644
index 0000000000..6b492f6114
--- /dev/null
+++ b/astro/src/styles/tokens/_spacing.css
@@ -0,0 +1,49 @@
+/**
+ * Spacing Tokens
+ *
+ * Based on a 4px grid system (0.25rem)
+ * Used for margin, padding, gap, etc.
+ */
+
+:root {
+ --space-0: 0;
+ --space-px: 1px;
+ --space-0-5: 0.2rem; /* 2px */
+ --space-1: 0.4rem; /* 4px */
+ --space-1-5: 0.6rem; /* 6px */
+ --space-2: 0.8rem; /* 8px */
+ --space-2-5: 1rem; /* 10px */
+ --space-3: 1.2rem; /* 12px */
+ --space-3-5: 1.4rem; /* 14px */
+ --space-4: 1.6rem; /* 16px */
+ --space-5: 2rem; /* 20px */
+ --space-6: 2.4rem; /* 24px */
+ --space-7: 2.8rem; /* 28px */
+ --space-8: 3.2rem; /* 32px */
+ --space-9: 3.6rem; /* 36px */
+ --space-10: 4rem; /* 40px */
+ --space-11: 4.4rem; /* 44px */
+ --space-12: 4.8rem; /* 48px */
+ --space-14: 5.6rem; /* 56px */
+ --space-16: 6.4rem; /* 64px */
+ --space-18: 7.2rem; /* 72px */
+ --space-20: 8rem; /* 80px */
+ --space-24: 9.6rem; /* 96px */
+ --space-28: 11.2rem; /* 112px */
+ --space-32: 12.8rem; /* 128px */
+ --space-36: 14.4rem; /* 144px */
+ --space-40: 16rem; /* 160px */
+ --space-44: 17.6rem; /* 176px */
+ --space-48: 19.2rem; /* 192px */
+ --space-52: 20.8rem; /* 208px */
+ --space-56: 22.4rem; /* 224px */
+ --space-60: 24rem; /* 240px */
+ --space-64: 25.6rem; /* 256px */
+
+ /* Component specific */
+ --space-h1: var(--space-12);
+ --space-h2: var(--space-6);
+ --space-h3: var(--space-6);
+ --space-h4: var(--space-6);
+ --space-body: var(--space-5);
+}
diff --git a/astro/src/styles/tokens/_transitions.css b/astro/src/styles/tokens/_transitions.css
new file mode 100644
index 0000000000..41c7e739f8
--- /dev/null
+++ b/astro/src/styles/tokens/_transitions.css
@@ -0,0 +1,47 @@
+/**
+ * Transition & Animation Tokens
+ */
+
+:root {
+ /* Durations */
+ --duration-75: 75ms;
+ --duration-100: 100ms;
+ --duration-150: 150ms;
+ --duration-200: 200ms;
+ --duration-300: 300ms;
+ --duration-500: 500ms;
+ --duration-700: 700ms;
+ --duration-1000: 1000ms;
+
+ /* Timing Functions */
+ --ease-linear: linear;
+ --ease-in: cubic-bezier(0.4, 0, 1, 1);
+ --ease-out: cubic-bezier(0, 0, 0.2, 1);
+ --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
+
+ /* Semantic transitions */
+ --transition-fast: var(--duration-150) var(--ease-out);
+ --transition-base: var(--duration-200) var(--ease-out);
+ --transition-slow: var(--duration-300) var(--ease-out);
+
+ --transition-colors:
+ color var(--transition-fast), background-color var(--transition-fast),
+ border-color var(--transition-fast);
+ --transition-transform: transform var(--transition-base);
+ --transition-opacity: opacity var(--transition-base);
+ --transition-shadow: box-shadow var(--transition-base);
+}
+
+/* Respect reduced motion preference */
+@media (prefers-reduced-motion: reduce) {
+ :root {
+ --duration-75: 0ms;
+ --duration-100: 0ms;
+ --duration-150: 0ms;
+ --duration-200: 0ms;
+ --duration-300: 0ms;
+ --duration-500: 0ms;
+ --duration-700: 0ms;
+ --duration-1000: 0ms;
+ }
+}
diff --git a/astro/src/styles/tokens/_typography.css b/astro/src/styles/tokens/_typography.css
new file mode 100644
index 0000000000..9097495348
--- /dev/null
+++ b/astro/src/styles/tokens/_typography.css
@@ -0,0 +1,82 @@
+/**
+ * Typography Tokens
+ *
+ * Primary font: Helvetica Neue
+ * Code font: JetBrains Mono
+ */
+
+:root {
+ /* Font Families */
+ --font-family-sans:
+ 'Helvetica Neue', Helvetica, Arial, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
+ --font-family-mono:
+ 'JetBrains Mono', ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, monospace;
+
+ /* Font Sizes - Scale using a 1.2 ratio (Minor Third) */
+ --font-size-xxs: 1rem;
+ --font-size-xs: 1.2rem;
+ --font-size-sm: 1.4rem;
+ --font-size-base: 1.6rem;
+ --font-size-lg: 1.8rem;
+ --font-size-xl: 2rem;
+ --font-size-2xl: 2.4rem;
+ --font-size-3xl: 3rem;
+ --font-size-4xl: 3.6rem;
+ --font-size-5xl: 4.5rem;
+ --font-size-6xl: 5.4rem;
+
+ /* Font Weights */
+ --font-weight-light: 300;
+ --font-weight-normal: 400;
+ --font-weight-medium: 500;
+ --font-weight-semibold: 600;
+ --font-weight-bold: 700;
+
+ /* Line Heights */
+ --line-height-none: 1;
+ --line-height-tight: 1.25;
+ --line-height-snug: 1.375;
+ --line-height-normal: 1.5;
+ --line-height-relaxed: 1.625;
+ --line-height-loose: 2;
+
+ /* Letter Spacing */
+ --letter-spacing-tighter: -0.05em;
+ --letter-spacing-tight: -0.025em;
+ --letter-spacing-normal: 0em;
+ --letter-spacing-wide: 0.025em;
+ --letter-spacing-wider: 0.05em;
+ --letter-spacing-widest: 0.1em;
+
+ /* Components tokens */
+ --font-family-body: var(--font-family-sans);
+ --font-size-body: var(--font-size-base);
+ --line-height-body: var(--line-height-normal);
+ --letter-spacing-body: var(--letter-spacing-tight);
+
+ --font-family-heading: var(--font-family-sans);
+ --font-weight-heading: var(--font-weight-bold);
+ --font-line-height-heading: var(--line-height-tight);
+
+ --font-size-h1: var(--font-size-4xl);
+ --font-size-h2: var(--font-size-2xl);
+ --font-size-h3: var(--font-size-lg);
+ --font-size-h4: var(--font-size-base);
+
+ --font-family-code: var(--font-family-mono);
+ --font-size-code: 0.9em;
+
+ @media (--md-only) {
+ --font-size-h1: var(--font-size-5xl);
+ --font-size-h2: var(--font-size-5xl);
+ --font-size-h3: var(--font-size-lg);
+ --font-size-h4: var(--font-size-lg);
+ }
+
+ @media (--lg-up) {
+ --font-size-h1: var(--font-size-6xl);
+ --font-size-h2: var(--font-size-5xl);
+ --font-size-h3: var(--font-size-2xl);
+ --font-size-h4: var(--font-size-xl);
+ }
+}
diff --git a/astro/src/styles/tokens/_zindex.css b/astro/src/styles/tokens/_zindex.css
new file mode 100644
index 0000000000..8d543295e5
--- /dev/null
+++ b/astro/src/styles/tokens/_zindex.css
@@ -0,0 +1,12 @@
+/**
+ * Z-Index Scale
+ * Values are ordered from lowest to highest.
+ * Each layer is spaced by 10 to allow for intermediate values if needed.
+ */
+
+:root {
+ --z-index-sidebar-backdrop: 10;
+ --z-index-header: 20;
+ --z-index-sidebar: 30;
+ --z-index-modal-overlay: 40;
+}
diff --git a/astro/src/styles/tokens/index.css b/astro/src/styles/tokens/index.css
new file mode 100644
index 0000000000..ab1b427a2e
--- /dev/null
+++ b/astro/src/styles/tokens/index.css
@@ -0,0 +1,14 @@
+/**
+ * Design Tokens Index
+ *
+ * Import all token files
+ */
+
+@import './_breakpoints.css';
+@import './_colors.css';
+@import './_typography.css';
+@import './_spacing.css';
+@import './_sizing.css';
+@import './_zindex.css';
+@import './_borders.css';
+@import './_transitions.css';
diff --git a/astro/src/styles/utilities/_utilities.css b/astro/src/styles/utilities/_utilities.css
new file mode 100644
index 0000000000..178d00c126
--- /dev/null
+++ b/astro/src/styles/utilities/_utilities.css
@@ -0,0 +1,156 @@
+/**
+ * Utility Classes (layer: utilities)
+ *
+ * High-priority utility classes for one-off overrides.
+ * Use sparingly - prefer component styles.
+ */
+
+/* Visually hidden but accessible to screen readers */
+.sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ white-space: nowrap;
+ border: 0;
+}
+
+/* Text alignment */
+.text-left {
+ text-align: left;
+}
+.text-center {
+ text-align: center;
+}
+.text-right {
+ text-align: right;
+}
+
+/* Display */
+.hidden {
+ display: none;
+}
+.block {
+ display: block;
+}
+.inline {
+ display: inline;
+}
+.inline-block {
+ display: inline-block;
+}
+.flex {
+ display: flex;
+}
+.grid {
+ display: grid;
+}
+.contents {
+ display: contents;
+}
+
+/* Flex utilities */
+.flex-row {
+ flex-direction: row;
+}
+.flex-col {
+ flex-direction: column;
+}
+.items-center {
+ align-items: center;
+}
+.items-start {
+ align-items: flex-start;
+}
+.items-end {
+ align-items: flex-end;
+}
+.justify-center {
+ justify-content: center;
+}
+.justify-between {
+ justify-content: space-between;
+}
+.justify-end {
+ justify-content: flex-end;
+}
+.gap-1 {
+ gap: var(--space-1);
+}
+.gap-2 {
+ gap: var(--space-2);
+}
+.gap-3 {
+ gap: var(--space-3);
+}
+.gap-4 {
+ gap: var(--space-4);
+}
+.gap-6 {
+ gap: var(--space-6);
+}
+.gap-8 {
+ gap: var(--space-8);
+}
+
+.w-full {
+ width: 100%;
+}
+
+.h-full {
+ height: 100%;
+}
+
+.max-w-prose {
+ max-width: var(--content-width);
+}
+
+.mx-auto {
+ margin-inline: auto;
+}
+.my-auto {
+ margin-block: auto;
+}
+
+/* Padding shortcuts */
+.p-0 {
+ padding: var(--space-0);
+}
+.p-2 {
+ padding: var(--space-2);
+}
+.p-4 {
+ padding: var(--space-4);
+}
+.p-6 {
+ padding: var(--space-6);
+}
+.p-8 {
+ padding: var(--space-8);
+}
+
+/* Margin shortcuts */
+.m-0 {
+ margin: var(--space-0);
+}
+.m-2 {
+ margin: var(--space-2);
+}
+.m-4 {
+ margin: var(--space-4);
+}
+.m-6 {
+ margin: var(--space-6);
+}
+.m-8 {
+ margin: var(--space-8);
+}
+
+.disable-transitions *,
+.disable-transitions *::before,
+.disable-transitions *::after {
+ transition: none !important;
+}
diff --git a/astro/src/utils/content.ts b/astro/src/utils/content.ts
new file mode 100644
index 0000000000..b5b6557948
--- /dev/null
+++ b/astro/src/utils/content.ts
@@ -0,0 +1,203 @@
+import { getCollection, type CollectionEntry } from 'astro:content';
+import { mainMenu } from '@/config/menu/main';
+import { apiMenu } from '@/config/menu/api';
+import type { collections } from '@/content.config';
+import type { Menu } from '@/config/types';
+
+/**
+ * Checks if there is content at the specified path
+ * @param checkPath - The path to check (e.g., 'en/resources/middleware')
+ * @param pages - The collection of pages to search within
+ * @returns True if content exists at the specified path, false otherwise
+ */
+export function hasContentAt(
+ checkPath: string,
+ pages: CollectionEntry[]
+): boolean {
+ return pages.some((page) => page.id === checkPath);
+}
+
+export interface BreadcrumbItem {
+ label: string;
+ href?: string;
+}
+
+/**
+ * Find the label for a collection from the main menu
+ */
+function getCollectionLabel(collection: string): string {
+ for (const section of mainMenu.sections || []) {
+ for (const item of section.items) {
+ if ('submenu' in item && item.submenu?.basePath === `/${collection}`) {
+ return item.label;
+ }
+ }
+ }
+ // Fallback: capitalize the collection name
+ return collection.charAt(0).toUpperCase() + collection.slice(1);
+}
+
+/**
+ * Format a slug segment into a readable label
+ */
+function formatLabel(segment: string): string {
+ return segment
+ .split('-')
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
+ .join(' ');
+}
+
+/**
+ * Find breadcrumb labels by traversing the menu structure
+ * Returns an array of labels representing the path to the href in the menu
+ */
+function findInMenu(href: string, menu: Menu, path: string[] = []): string[] | null {
+ // Check sections
+ if (menu.sections) {
+ for (const section of menu.sections) {
+ // Add section title to path if it exists
+ const currentPath = section.title ? [...path, section.title] : path;
+
+ // Check items in this section
+ for (const item of section.items) {
+ if ('href' in item && item.href) {
+ // Normalize hrefs for comparison (remove leading slash and version)
+ const normalizedItemHref = item.href.replace(/^\//, '');
+ const normalizedSearchHref = href.replace(/^\//, '').replace(/^\d+x\//, '');
+
+ if (normalizedItemHref === normalizedSearchHref) {
+ return currentPath;
+ }
+ }
+
+ // Check submenu if it exists
+ if ('submenu' in item && item.submenu) {
+ const submenuPath = [...currentPath, item.label];
+ const result = findInMenu(href, item.submenu, submenuPath);
+ if (result) {
+ return result;
+ }
+ }
+ }
+ }
+ }
+
+ // Check items at menu root level
+ if (menu.items) {
+ for (const item of menu.items) {
+ if ('href' in item && item.href) {
+ const normalizedItemHref = item.href.replace(/^\//, '');
+ const normalizedSearchHref = href.replace(/^\//, '').replace(/^\d+x\//, '');
+
+ if (normalizedItemHref === normalizedSearchHref) {
+ return path;
+ }
+ }
+
+ if ('submenu' in item && item.submenu) {
+ const submenuPath = [...path, item.label];
+ const result = findInMenu(href, item.submenu, submenuPath);
+ if (result) {
+ return result;
+ }
+ }
+ }
+ }
+
+ return null;
+}
+
+/**
+ * Builds breadcrumb items for a documentation page
+ * @param lang - The language code (e.g., 'en')
+ * @param slug - The page slug (e.g., 'resources/middleware/compression')
+ * @param collection - The collection name to check for existing content
+ * @param version - The version to display in breadcrumbs (e.g., '5x')
+ * @returns Array of breadcrumb items with labels and optional hrefs
+ */
+export async function buildBreadcrumbs(
+ lang: string,
+ slug: string,
+ collection: keyof typeof collections,
+ version?: string
+): Promise {
+ const pages = await getCollection(collection);
+
+ const breadcrumbs: BreadcrumbItem[] = [];
+
+ const slugParts = slug.split('/');
+ const startIndex = slugParts[0] === version ? 1 : 0;
+
+ // Check if this is an API page
+ const isApiPage = slugParts.includes('api');
+
+ if (isApiPage) {
+ // For API pages: version > API > category > subsection (e.g., "5x > API > Application > Properties")
+ if (version) {
+ breadcrumbs.push({
+ label: version,
+ href: undefined,
+ });
+ }
+
+ breadcrumbs.push({
+ label: 'API',
+ href: undefined,
+ });
+
+ // Try to find the page in the API menu structure to get proper labels
+ const apiIndex = slugParts.indexOf('api');
+ const apiPath = slugParts.slice(apiIndex).join('/');
+ const menuPath = findInMenu(apiPath, apiMenu);
+
+ if (menuPath && menuPath.length > 0) {
+ // Use labels from menu structure
+ menuPath.forEach((label) => {
+ breadcrumbs.push({
+ label,
+ href: undefined,
+ });
+ });
+ } else {
+ // Fallback: use formatted path segments
+ slugParts.slice(apiIndex + 1).forEach((part, index) => {
+ const isLast = index === slugParts.slice(apiIndex + 1).length - 1;
+ const pathToSegment = `${lang}/${slugParts.slice(0, apiIndex + index + 2).join('/')}`;
+
+ if (!isLast) {
+ breadcrumbs.push({
+ label: formatLabel(part),
+ href: hasContentAt(pathToSegment, pages) ? `/${pathToSegment}` : undefined,
+ });
+ }
+ });
+ }
+ } else {
+ // For non-API pages: use the original structure
+ breadcrumbs.push({
+ label: getCollectionLabel(collection),
+ href: undefined,
+ });
+
+ if (version) {
+ breadcrumbs.push({
+ label: version,
+ href: undefined,
+ });
+ }
+
+ slugParts.slice(startIndex).forEach((part, index) => {
+ const isLast = index === slugParts.slice(startIndex).length - 1;
+ const pathToSegment = `${lang}/${slugParts.slice(0, startIndex + index + 1).join('/')}`;
+
+ if (!isLast) {
+ breadcrumbs.push({
+ label: formatLabel(part),
+ href: hasContentAt(pathToSegment, pages) ? `/${pathToSegment}` : undefined,
+ });
+ }
+ });
+ }
+
+ return breadcrumbs;
+}
diff --git a/astro/src/utils/rss.ts b/astro/src/utils/rss.ts
new file mode 100644
index 0000000000..d08510db0b
--- /dev/null
+++ b/astro/src/utils/rss.ts
@@ -0,0 +1,45 @@
+export interface FeedAuthor {
+ name: string;
+ github?: string;
+}
+
+export function getPubDateFromId(id: string): Date | undefined {
+ const filename = id.split('/').pop() ?? id;
+ const match = filename.match(/^(\d{4}-\d{2}-\d{2})/);
+ if (!match) return undefined;
+
+ const date = new Date(`${match[1]}T00:00:00.000Z`);
+ return Number.isNaN(date.getTime()) ? undefined : date;
+}
+
+export function getAuthorsCustomData(authors?: FeedAuthor[]): string | undefined {
+ if (!authors?.length) return undefined;
+
+ return authors
+ .map((author) => {
+ const uri = author.github ? `https://github.com/${author.github} ` : '';
+ return `${author.name} ${uri} `;
+ })
+ .join('');
+}
+
+export function sortByIdDateDesc(items: T[]): T[] {
+ return [...items].sort((a, b) => {
+ const aTime = getPubDateFromId(a.id)?.getTime() ?? 0;
+ const bTime = getPubDateFromId(b.id)?.getTime() ?? 0;
+
+ if (aTime === bTime) return a.id.localeCompare(b.id);
+ return bTime - aTime;
+ });
+}
+
+export function shouldIncludeInFeed(id: string): boolean {
+ const filename = id.split('/').pop() ?? id;
+ return !/^write[-_]posts?$/i.test(filename);
+}
+
+export function getLinkedTitleContent(title: string, id: string, site: URL): string {
+ const link = new URL(`/blog/${id}/`, site).href;
+
+ return `${title} `;
+}
diff --git a/astro/src/vite-env.d.ts b/astro/src/vite-env.d.ts
new file mode 100644
index 0000000000..ae43aec7c7
--- /dev/null
+++ b/astro/src/vite-env.d.ts
@@ -0,0 +1,8 @@
+///
+///
+
+declare module '*.svg?react' {
+ import type { FC, SVGProps } from 'react';
+ const ReactComponent: FC>;
+ export default ReactComponent;
+}
diff --git a/astro/tsconfig.json b/astro/tsconfig.json
new file mode 100644
index 0000000000..b1155e8670
--- /dev/null
+++ b/astro/tsconfig.json
@@ -0,0 +1,18 @@
+{
+ "extends": "astro/tsconfigs/strict",
+ "include": [".astro/types.d.ts", "**/*"],
+ "exclude": ["dist"],
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["src/*"],
+ "@components/*": ["src/components/*"],
+ "@layouts/*": ["src/layouts/*"],
+ "@assets/*": ["src/assets/*"],
+ "@styles/*": ["src/styles/*"],
+ "@config/*": ["src/config/*"],
+ "@i18n/*": ["src/i18n/*"],
+ "@utils/*": ["src/utils/*"]
+ }
+ }
+}
diff --git a/legacy/.github-legacy/CODEOWNERS b/legacy/.github-legacy/CODEOWNERS
new file mode 100644
index 0000000000..b983583855
--- /dev/null
+++ b/legacy/.github-legacy/CODEOWNERS
@@ -0,0 +1,8 @@
+# Website development
+* @expressjs/docs-collaborators
+
+# Codeowners
+.github/CODEOWNERS @expressjs/docs-captains
+
+# Blog
+_posts @expressjs/express-tc
\ No newline at end of file
diff --git a/.github/dependabot.yml b/legacy/.github-legacy/dependabot.yml
similarity index 100%
rename from .github/dependabot.yml
rename to legacy/.github-legacy/dependabot.yml
diff --git a/.github/scripts/get-contributing.sh b/legacy/.github-legacy/scripts/get-contributing.sh
similarity index 100%
rename from .github/scripts/get-contributing.sh
rename to legacy/.github-legacy/scripts/get-contributing.sh
diff --git a/.github/scripts/get-express-version.mjs b/legacy/.github-legacy/scripts/get-express-version.mjs
similarity index 100%
rename from .github/scripts/get-express-version.mjs
rename to legacy/.github-legacy/scripts/get-express-version.mjs
diff --git a/.github/scripts/get-readmes.sh b/legacy/.github-legacy/scripts/get-readmes.sh
similarity index 100%
rename from .github/scripts/get-readmes.sh
rename to legacy/.github-legacy/scripts/get-readmes.sh
diff --git a/.github/workflows/ci.yml b/legacy/.github-legacy/workflows/ci.yml
similarity index 100%
rename from .github/workflows/ci.yml
rename to legacy/.github-legacy/workflows/ci.yml
diff --git a/legacy/.github-legacy/workflows/codeql.yml b/legacy/.github-legacy/workflows/codeql.yml
new file mode 100644
index 0000000000..c01437a44e
--- /dev/null
+++ b/legacy/.github-legacy/workflows/codeql.yml
@@ -0,0 +1,73 @@
+# For most projects, this workflow file will not need changing; you simply need
+# to commit it to your repository.
+#
+# You may wish to alter this file to override the set of languages analyzed,
+# or to provide custom queries or build logic.
+#
+# ******** NOTE ********
+# We have attempted to detect the languages in your repository. Please check
+# the `language` matrix defined below to confirm you have the correct set of
+# supported CodeQL languages.
+#
+name: "CodeQL"
+
+on:
+ push:
+ branches: ["gh-pages"]
+ pull_request:
+ # The branches below must be a subset of the branches above
+ branches: ["gh-pages"]
+ schedule:
+ - cron: "0 0 * * 1"
+
+permissions:
+ contents: read
+
+jobs:
+ analyze:
+ name: Analyze
+ runs-on: ubuntu-latest
+ permissions:
+ actions: read
+ contents: read
+ security-events: write
+
+ strategy:
+ fail-fast: false
+ matrix:
+ language: ["javascript", "actions"]
+ # CodeQL supports [ $supported-codeql-languages ]
+ # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v6
+
+ # Initializes the CodeQL tools for scanning.
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v4
+ with:
+ languages: ${{ matrix.language }}
+ # If you wish to specify custom queries, you can do so here or in a config file.
+ # By default, queries listed here will override any specified in a config file.
+ # Prefix the list here with "+" to use these queries and those in the config file.
+
+ # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
+ # If this step fails, then you should remove it and run the build manually (see below)
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@v4
+
+ # ℹ️ Command-line programs to run using the OS shell.
+ # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
+
+ # If the Autobuild fails above, remove it and uncomment the following three lines.
+ # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
+
+ # - run: |
+ # echo "Run, Build Application using script"
+ # ./location_of_script_within_repo/buildscript.sh
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v4
+ with:
+ category: "/language:${{matrix.language}}"
diff --git a/legacy/.github-legacy/workflows/crowdin.yml b/legacy/.github-legacy/workflows/crowdin.yml
new file mode 100644
index 0000000000..9dc2b47846
--- /dev/null
+++ b/legacy/.github-legacy/workflows/crowdin.yml
@@ -0,0 +1,30 @@
+name: Crowdin Upload
+
+on:
+ push:
+ branches: [ gh-pages ]
+ workflow_dispatch:
+
+permissions:
+ contents: write
+ pull-requests: write
+
+jobs:
+ synchronize-with-crowdin:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v6
+ with:
+ persist-credentials: false
+
+ - name: crowdin action
+ uses: crowdin/github-action@60debf382ee245b21794321190ad0501db89d8c1 # https://github.com/crowdin/github-action/releases/tag/v2.13.0
+ with:
+ upload_sources: true
+ upload_translations: false
+ download_translations: false
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
+ CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
diff --git a/.github/workflows/deploy.yml b/legacy/.github-legacy/workflows/deploy.yml
similarity index 100%
rename from .github/workflows/deploy.yml
rename to legacy/.github-legacy/workflows/deploy.yml
diff --git a/.github/workflows/lighthouse.yml b/legacy/.github-legacy/workflows/lighthouse.yml
similarity index 100%
rename from .github/workflows/lighthouse.yml
rename to legacy/.github-legacy/workflows/lighthouse.yml
diff --git a/legacy/.github-legacy/workflows/scorecards.yml b/legacy/.github-legacy/workflows/scorecards.yml
new file mode 100644
index 0000000000..59dee089ba
--- /dev/null
+++ b/legacy/.github-legacy/workflows/scorecards.yml
@@ -0,0 +1,76 @@
+# This workflow uses actions that are not certified by GitHub. They are provided
+# by a third-party and are governed by separate terms of service, privacy
+# policy, and support documentation.
+
+name: Scorecard supply-chain security
+on:
+ # For Branch-Protection check. Only the default branch is supported. See
+ # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
+ branch_protection_rule:
+ # To guarantee Maintained check is occasionally updated. See
+ # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
+ schedule:
+ - cron: '20 7 * * 2'
+ push:
+ branches: ["gh-pages"]
+
+# Declare default permissions as read only.
+permissions: read-all
+
+jobs:
+ analysis:
+ name: Scorecard analysis
+ runs-on: ubuntu-latest
+ permissions:
+ # Needed to upload the results to code-scanning dashboard.
+ security-events: write
+ # Needed to publish results and get a badge (see publish_results below).
+ id-token: write
+ contents: read
+ actions: read
+ # To allow GraphQL ListCommits to work
+ issues: read
+ pull-requests: read
+ # To detect SAST tools
+ checks: read
+
+ steps:
+ - name: "Checkout code"
+ uses: actions/checkout@v6
+ with:
+ persist-credentials: false
+
+ - name: "Run analysis"
+ uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
+ with:
+ results_file: results.sarif
+ results_format: sarif
+ # (Optional) "write" PAT token. Uncomment the `repo_token` line below if:
+ # - you want to enable the Branch-Protection check on a *public* repository, or
+ # - you are installing Scorecards on a *private* repository
+ # To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat.
+ # repo_token: ${{ secrets.SCORECARD_TOKEN }}
+
+ # Public repositories:
+ # - Publish results to OpenSSF REST API for easy access by consumers
+ # - Allows the repository to include the Scorecard badge.
+ # - See https://github.com/ossf/scorecard-action#publishing-results.
+ # For private repositories:
+ # - `publish_results` will always be set to `false`, regardless
+ # of the value entered here.
+ publish_results: true
+
+ # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
+ # format to the repository Actions tab.
+ - name: "Upload artifact"
+ uses: actions/upload-artifact@v6
+ with:
+ name: SARIF file
+ path: results.sarif
+ retention-days: 5
+
+ # Upload the results to GitHub's code scanning dashboard.
+ - name: "Upload to code-scanning"
+ uses: github/codeql-action/upload-sarif@v4
+ with:
+ sarif_file: results.sarif
diff --git a/.github/workflows/update-external-docs.yml b/legacy/.github-legacy/workflows/update-external-docs.yml
similarity index 100%
rename from .github/workflows/update-external-docs.yml
rename to legacy/.github-legacy/workflows/update-external-docs.yml
diff --git a/.ruby-version b/legacy/.ruby-version
similarity index 100%
rename from .ruby-version
rename to legacy/.ruby-version
diff --git a/2x/applications.md b/legacy/2x/applications.md
similarity index 100%
rename from 2x/applications.md
rename to legacy/2x/applications.md
diff --git a/2x/contrib.md b/legacy/2x/contrib.md
similarity index 100%
rename from 2x/contrib.md
rename to legacy/2x/contrib.md
diff --git a/2x/docs/applications.md b/legacy/2x/docs/applications.md
similarity index 100%
rename from 2x/docs/applications.md
rename to legacy/2x/docs/applications.md
diff --git a/2x/docs/contrib.md b/legacy/2x/docs/contrib.md
similarity index 100%
rename from 2x/docs/contrib.md
rename to legacy/2x/docs/contrib.md
diff --git a/2x/docs/executable.md b/legacy/2x/docs/executable.md
similarity index 100%
rename from 2x/docs/executable.md
rename to legacy/2x/docs/executable.md
diff --git a/2x/docs/guide.md b/legacy/2x/docs/guide.md
similarity index 100%
rename from 2x/docs/guide.md
rename to legacy/2x/docs/guide.md
diff --git a/2x/docs/index.md b/legacy/2x/docs/index.md
similarity index 100%
rename from 2x/docs/index.md
rename to legacy/2x/docs/index.md
diff --git a/2x/docs/migrate.md b/legacy/2x/docs/migrate.md
similarity index 100%
rename from 2x/docs/migrate.md
rename to legacy/2x/docs/migrate.md
diff --git a/2x/docs/screencasts.md b/legacy/2x/docs/screencasts.md
similarity index 100%
rename from 2x/docs/screencasts.md
rename to legacy/2x/docs/screencasts.md
diff --git a/2x/executable.md b/legacy/2x/executable.md
similarity index 100%
rename from 2x/executable.md
rename to legacy/2x/executable.md
diff --git a/2x/guide.md b/legacy/2x/guide.md
similarity index 100%
rename from 2x/guide.md
rename to legacy/2x/guide.md
diff --git a/2x/index.md b/legacy/2x/index.md
similarity index 100%
rename from 2x/index.md
rename to legacy/2x/index.md
diff --git a/2x/migrate.md b/legacy/2x/migrate.md
similarity index 100%
rename from 2x/migrate.md
rename to legacy/2x/migrate.md
diff --git a/2x/screencasts.md b/legacy/2x/screencasts.md
similarity index 100%
rename from 2x/screencasts.md
rename to legacy/2x/screencasts.md
diff --git a/404.md b/legacy/404.md
similarity index 100%
rename from 404.md
rename to legacy/404.md
diff --git a/CNAME b/legacy/CNAME
similarity index 100%
rename from CNAME
rename to legacy/CNAME
diff --git a/CONTRIBUTING.md b/legacy/CONTRIBUTING.md
similarity index 100%
rename from CONTRIBUTING.md
rename to legacy/CONTRIBUTING.md
diff --git a/Dockerfile b/legacy/Dockerfile
similarity index 100%
rename from Dockerfile
rename to legacy/Dockerfile
diff --git a/Gemfile b/legacy/Gemfile
similarity index 100%
rename from Gemfile
rename to legacy/Gemfile
diff --git a/Gemfile.lock b/legacy/Gemfile.lock
similarity index 100%
rename from Gemfile.lock
rename to legacy/Gemfile.lock
diff --git a/Makefile b/legacy/Makefile
similarity index 100%
rename from Makefile
rename to legacy/Makefile
diff --git a/README.md b/legacy/README.md
similarity index 100%
rename from README.md
rename to legacy/README.md
diff --git a/_config.yml b/legacy/_config.yml
similarity index 100%
rename from _config.yml
rename to legacy/_config.yml
diff --git a/_data/de/footer.yml b/legacy/_data/de/footer.yml
similarity index 100%
rename from _data/de/footer.yml
rename to legacy/_data/de/footer.yml
diff --git a/_data/de/general.yml b/legacy/_data/de/general.yml
similarity index 100%
rename from _data/de/general.yml
rename to legacy/_data/de/general.yml
diff --git a/_data/de/menu.yml b/legacy/_data/de/menu.yml
similarity index 100%
rename from _data/de/menu.yml
rename to legacy/_data/de/menu.yml
diff --git a/_data/docsearch.yml b/legacy/_data/docsearch.yml
similarity index 100%
rename from _data/docsearch.yml
rename to legacy/_data/docsearch.yml
diff --git a/_data/en/footer.yml b/legacy/_data/en/footer.yml
similarity index 100%
rename from _data/en/footer.yml
rename to legacy/_data/en/footer.yml
diff --git a/_data/en/general.yml b/legacy/_data/en/general.yml
similarity index 100%
rename from _data/en/general.yml
rename to legacy/_data/en/general.yml
diff --git a/_data/en/menu.yml b/legacy/_data/en/menu.yml
similarity index 100%
rename from _data/en/menu.yml
rename to legacy/_data/en/menu.yml
diff --git a/_data/es/footer.yml b/legacy/_data/es/footer.yml
similarity index 100%
rename from _data/es/footer.yml
rename to legacy/_data/es/footer.yml
diff --git a/_data/es/general.yml b/legacy/_data/es/general.yml
similarity index 100%
rename from _data/es/general.yml
rename to legacy/_data/es/general.yml
diff --git a/_data/es/menu.yml b/legacy/_data/es/menu.yml
similarity index 100%
rename from _data/es/menu.yml
rename to legacy/_data/es/menu.yml
diff --git a/_data/express.yml b/legacy/_data/express.yml
similarity index 100%
rename from _data/express.yml
rename to legacy/_data/express.yml
diff --git a/_data/fr/footer.yml b/legacy/_data/fr/footer.yml
similarity index 100%
rename from _data/fr/footer.yml
rename to legacy/_data/fr/footer.yml
diff --git a/_data/fr/general.yml b/legacy/_data/fr/general.yml
similarity index 100%
rename from _data/fr/general.yml
rename to legacy/_data/fr/general.yml
diff --git a/_data/fr/menu.yml b/legacy/_data/fr/menu.yml
similarity index 100%
rename from _data/fr/menu.yml
rename to legacy/_data/fr/menu.yml
diff --git a/_data/it/footer.yml b/legacy/_data/it/footer.yml
similarity index 100%
rename from _data/it/footer.yml
rename to legacy/_data/it/footer.yml
diff --git a/_data/it/general.yml b/legacy/_data/it/general.yml
similarity index 100%
rename from _data/it/general.yml
rename to legacy/_data/it/general.yml
diff --git a/_data/it/menu.yml b/legacy/_data/it/menu.yml
similarity index 100%
rename from _data/it/menu.yml
rename to legacy/_data/it/menu.yml
diff --git a/_data/ja/footer.yml b/legacy/_data/ja/footer.yml
similarity index 100%
rename from _data/ja/footer.yml
rename to legacy/_data/ja/footer.yml
diff --git a/_data/ja/general.yml b/legacy/_data/ja/general.yml
similarity index 100%
rename from _data/ja/general.yml
rename to legacy/_data/ja/general.yml
diff --git a/_data/ja/menu.yml b/legacy/_data/ja/menu.yml
similarity index 100%
rename from _data/ja/menu.yml
rename to legacy/_data/ja/menu.yml
diff --git a/_data/ko/footer.yml b/legacy/_data/ko/footer.yml
similarity index 100%
rename from _data/ko/footer.yml
rename to legacy/_data/ko/footer.yml
diff --git a/_data/ko/general.yml b/legacy/_data/ko/general.yml
similarity index 100%
rename from _data/ko/general.yml
rename to legacy/_data/ko/general.yml
diff --git a/_data/ko/menu.yml b/legacy/_data/ko/menu.yml
similarity index 100%
rename from _data/ko/menu.yml
rename to legacy/_data/ko/menu.yml
diff --git a/_data/languages.yml b/legacy/_data/languages.yml
similarity index 100%
rename from _data/languages.yml
rename to legacy/_data/languages.yml
diff --git a/_data/pt-br/footer.yml b/legacy/_data/pt-br/footer.yml
similarity index 100%
rename from _data/pt-br/footer.yml
rename to legacy/_data/pt-br/footer.yml
diff --git a/_data/pt-br/general.yml b/legacy/_data/pt-br/general.yml
similarity index 100%
rename from _data/pt-br/general.yml
rename to legacy/_data/pt-br/general.yml
diff --git a/_data/pt-br/menu.yml b/legacy/_data/pt-br/menu.yml
similarity index 100%
rename from _data/pt-br/menu.yml
rename to legacy/_data/pt-br/menu.yml
diff --git a/_data/zh-cn/footer.yml b/legacy/_data/zh-cn/footer.yml
similarity index 100%
rename from _data/zh-cn/footer.yml
rename to legacy/_data/zh-cn/footer.yml
diff --git a/_data/zh-cn/general.yml b/legacy/_data/zh-cn/general.yml
similarity index 100%
rename from _data/zh-cn/general.yml
rename to legacy/_data/zh-cn/general.yml
diff --git a/_data/zh-cn/menu.yml b/legacy/_data/zh-cn/menu.yml
similarity index 100%
rename from _data/zh-cn/menu.yml
rename to legacy/_data/zh-cn/menu.yml
diff --git a/_data/zh-tw/footer.yml b/legacy/_data/zh-tw/footer.yml
similarity index 100%
rename from _data/zh-tw/footer.yml
rename to legacy/_data/zh-tw/footer.yml
diff --git a/_data/zh-tw/general.yml b/legacy/_data/zh-tw/general.yml
similarity index 100%
rename from _data/zh-tw/general.yml
rename to legacy/_data/zh-tw/general.yml
diff --git a/_data/zh-tw/menu.yml b/legacy/_data/zh-tw/menu.yml
similarity index 100%
rename from _data/zh-tw/menu.yml
rename to legacy/_data/zh-tw/menu.yml
diff --git a/_includes/admonitions/caution.html b/legacy/_includes/admonitions/caution.html
similarity index 100%
rename from _includes/admonitions/caution.html
rename to legacy/_includes/admonitions/caution.html
diff --git a/_includes/admonitions/note.html b/legacy/_includes/admonitions/note.html
similarity index 100%
rename from _includes/admonitions/note.html
rename to legacy/_includes/admonitions/note.html
diff --git a/_includes/admonitions/warning.html b/legacy/_includes/admonitions/warning.html
similarity index 100%
rename from _includes/admonitions/warning.html
rename to legacy/_includes/admonitions/warning.html
diff --git a/_includes/announcement.html b/legacy/_includes/announcement.html
similarity index 100%
rename from _includes/announcement.html
rename to legacy/_includes/announcement.html
diff --git a/_includes/api/en/3x/app-VERB.md b/legacy/_includes/api/en/3x/app-VERB.md
similarity index 100%
rename from _includes/api/en/3x/app-VERB.md
rename to legacy/_includes/api/en/3x/app-VERB.md
diff --git a/_includes/api/en/3x/app-all.md b/legacy/_includes/api/en/3x/app-all.md
similarity index 100%
rename from _includes/api/en/3x/app-all.md
rename to legacy/_includes/api/en/3x/app-all.md
diff --git a/_includes/api/en/3x/app-configure.md b/legacy/_includes/api/en/3x/app-configure.md
similarity index 100%
rename from _includes/api/en/3x/app-configure.md
rename to legacy/_includes/api/en/3x/app-configure.md
diff --git a/_includes/api/en/3x/app-disable.md b/legacy/_includes/api/en/3x/app-disable.md
similarity index 100%
rename from _includes/api/en/3x/app-disable.md
rename to legacy/_includes/api/en/3x/app-disable.md
diff --git a/_includes/api/en/3x/app-disabled.md b/legacy/_includes/api/en/3x/app-disabled.md
similarity index 100%
rename from _includes/api/en/3x/app-disabled.md
rename to legacy/_includes/api/en/3x/app-disabled.md
diff --git a/_includes/api/en/3x/app-enable.md b/legacy/_includes/api/en/3x/app-enable.md
similarity index 100%
rename from _includes/api/en/3x/app-enable.md
rename to legacy/_includes/api/en/3x/app-enable.md
diff --git a/_includes/api/en/3x/app-enabled.md b/legacy/_includes/api/en/3x/app-enabled.md
similarity index 100%
rename from _includes/api/en/3x/app-enabled.md
rename to legacy/_includes/api/en/3x/app-enabled.md
diff --git a/_includes/api/en/3x/app-engine.md b/legacy/_includes/api/en/3x/app-engine.md
similarity index 100%
rename from _includes/api/en/3x/app-engine.md
rename to legacy/_includes/api/en/3x/app-engine.md
diff --git a/_includes/api/en/3x/app-get.md b/legacy/_includes/api/en/3x/app-get.md
similarity index 100%
rename from _includes/api/en/3x/app-get.md
rename to legacy/_includes/api/en/3x/app-get.md
diff --git a/_includes/api/en/3x/app-listen.md b/legacy/_includes/api/en/3x/app-listen.md
similarity index 100%
rename from _includes/api/en/3x/app-listen.md
rename to legacy/_includes/api/en/3x/app-listen.md
diff --git a/_includes/api/en/3x/app-locals.md b/legacy/_includes/api/en/3x/app-locals.md
similarity index 100%
rename from _includes/api/en/3x/app-locals.md
rename to legacy/_includes/api/en/3x/app-locals.md
diff --git a/_includes/api/en/3x/app-param.md b/legacy/_includes/api/en/3x/app-param.md
similarity index 100%
rename from _includes/api/en/3x/app-param.md
rename to legacy/_includes/api/en/3x/app-param.md
diff --git a/_includes/api/en/3x/app-render.md b/legacy/_includes/api/en/3x/app-render.md
similarity index 100%
rename from _includes/api/en/3x/app-render.md
rename to legacy/_includes/api/en/3x/app-render.md
diff --git a/_includes/api/en/3x/app-routes.md b/legacy/_includes/api/en/3x/app-routes.md
similarity index 100%
rename from _includes/api/en/3x/app-routes.md
rename to legacy/_includes/api/en/3x/app-routes.md
diff --git a/_includes/api/en/3x/app-set.md b/legacy/_includes/api/en/3x/app-set.md
similarity index 100%
rename from _includes/api/en/3x/app-set.md
rename to legacy/_includes/api/en/3x/app-set.md
diff --git a/_includes/api/en/3x/app-settings.md b/legacy/_includes/api/en/3x/app-settings.md
similarity index 100%
rename from _includes/api/en/3x/app-settings.md
rename to legacy/_includes/api/en/3x/app-settings.md
diff --git a/_includes/api/en/3x/app-use.md b/legacy/_includes/api/en/3x/app-use.md
similarity index 100%
rename from _includes/api/en/3x/app-use.md
rename to legacy/_includes/api/en/3x/app-use.md
diff --git a/_includes/api/en/3x/app.md b/legacy/_includes/api/en/3x/app.md
similarity index 100%
rename from _includes/api/en/3x/app.md
rename to legacy/_includes/api/en/3x/app.md
diff --git a/_includes/api/en/3x/express.md b/legacy/_includes/api/en/3x/express.md
similarity index 100%
rename from _includes/api/en/3x/express.md
rename to legacy/_includes/api/en/3x/express.md
diff --git a/_includes/api/en/3x/menu.md b/legacy/_includes/api/en/3x/menu.md
similarity index 100%
rename from _includes/api/en/3x/menu.md
rename to legacy/_includes/api/en/3x/menu.md
diff --git a/_includes/api/en/3x/middleware.md b/legacy/_includes/api/en/3x/middleware.md
similarity index 100%
rename from _includes/api/en/3x/middleware.md
rename to legacy/_includes/api/en/3x/middleware.md
diff --git a/_includes/api/en/3x/mw-basicAuth.md b/legacy/_includes/api/en/3x/mw-basicAuth.md
similarity index 100%
rename from _includes/api/en/3x/mw-basicAuth.md
rename to legacy/_includes/api/en/3x/mw-basicAuth.md
diff --git a/_includes/api/en/3x/mw-bodyParser.md b/legacy/_includes/api/en/3x/mw-bodyParser.md
similarity index 100%
rename from _includes/api/en/3x/mw-bodyParser.md
rename to legacy/_includes/api/en/3x/mw-bodyParser.md
diff --git a/_includes/api/en/3x/mw-compress.md b/legacy/_includes/api/en/3x/mw-compress.md
similarity index 100%
rename from _includes/api/en/3x/mw-compress.md
rename to legacy/_includes/api/en/3x/mw-compress.md
diff --git a/_includes/api/en/3x/mw-cookieParser.md b/legacy/_includes/api/en/3x/mw-cookieParser.md
similarity index 100%
rename from _includes/api/en/3x/mw-cookieParser.md
rename to legacy/_includes/api/en/3x/mw-cookieParser.md
diff --git a/_includes/api/en/3x/mw-cookieSession.md b/legacy/_includes/api/en/3x/mw-cookieSession.md
similarity index 100%
rename from _includes/api/en/3x/mw-cookieSession.md
rename to legacy/_includes/api/en/3x/mw-cookieSession.md
diff --git a/_includes/api/en/3x/mw-csrf.md b/legacy/_includes/api/en/3x/mw-csrf.md
similarity index 100%
rename from _includes/api/en/3x/mw-csrf.md
rename to legacy/_includes/api/en/3x/mw-csrf.md
diff --git a/_includes/api/en/3x/mw-directory.md b/legacy/_includes/api/en/3x/mw-directory.md
similarity index 100%
rename from _includes/api/en/3x/mw-directory.md
rename to legacy/_includes/api/en/3x/mw-directory.md
diff --git a/_includes/api/en/3x/req-accepted.md b/legacy/_includes/api/en/3x/req-accepted.md
similarity index 100%
rename from _includes/api/en/3x/req-accepted.md
rename to legacy/_includes/api/en/3x/req-accepted.md
diff --git a/_includes/api/en/3x/req-acceptedCharsets.md b/legacy/_includes/api/en/3x/req-acceptedCharsets.md
similarity index 100%
rename from _includes/api/en/3x/req-acceptedCharsets.md
rename to legacy/_includes/api/en/3x/req-acceptedCharsets.md
diff --git a/_includes/api/en/3x/req-acceptedLanguages.md b/legacy/_includes/api/en/3x/req-acceptedLanguages.md
similarity index 100%
rename from _includes/api/en/3x/req-acceptedLanguages.md
rename to legacy/_includes/api/en/3x/req-acceptedLanguages.md
diff --git a/_includes/api/en/3x/req-accepts.md b/legacy/_includes/api/en/3x/req-accepts.md
similarity index 100%
rename from _includes/api/en/3x/req-accepts.md
rename to legacy/_includes/api/en/3x/req-accepts.md
diff --git a/_includes/api/en/3x/req-acceptsCharset.md b/legacy/_includes/api/en/3x/req-acceptsCharset.md
similarity index 100%
rename from _includes/api/en/3x/req-acceptsCharset.md
rename to legacy/_includes/api/en/3x/req-acceptsCharset.md
diff --git a/_includes/api/en/3x/req-acceptsLanguage.md b/legacy/_includes/api/en/3x/req-acceptsLanguage.md
similarity index 100%
rename from _includes/api/en/3x/req-acceptsLanguage.md
rename to legacy/_includes/api/en/3x/req-acceptsLanguage.md
diff --git a/_includes/api/en/3x/req-body.md b/legacy/_includes/api/en/3x/req-body.md
similarity index 100%
rename from _includes/api/en/3x/req-body.md
rename to legacy/_includes/api/en/3x/req-body.md
diff --git a/_includes/api/en/3x/req-cookies.md b/legacy/_includes/api/en/3x/req-cookies.md
similarity index 100%
rename from _includes/api/en/3x/req-cookies.md
rename to legacy/_includes/api/en/3x/req-cookies.md
diff --git a/_includes/api/en/3x/req-files.md b/legacy/_includes/api/en/3x/req-files.md
similarity index 100%
rename from _includes/api/en/3x/req-files.md
rename to legacy/_includes/api/en/3x/req-files.md
diff --git a/_includes/api/en/3x/req-fresh.md b/legacy/_includes/api/en/3x/req-fresh.md
similarity index 100%
rename from _includes/api/en/3x/req-fresh.md
rename to legacy/_includes/api/en/3x/req-fresh.md
diff --git a/_includes/api/en/3x/req-header.md b/legacy/_includes/api/en/3x/req-header.md
similarity index 100%
rename from _includes/api/en/3x/req-header.md
rename to legacy/_includes/api/en/3x/req-header.md
diff --git a/_includes/api/en/3x/req-host.md b/legacy/_includes/api/en/3x/req-host.md
similarity index 100%
rename from _includes/api/en/3x/req-host.md
rename to legacy/_includes/api/en/3x/req-host.md
diff --git a/_includes/api/en/3x/req-ip.md b/legacy/_includes/api/en/3x/req-ip.md
similarity index 100%
rename from _includes/api/en/3x/req-ip.md
rename to legacy/_includes/api/en/3x/req-ip.md
diff --git a/_includes/api/en/3x/req-ips.md b/legacy/_includes/api/en/3x/req-ips.md
similarity index 100%
rename from _includes/api/en/3x/req-ips.md
rename to legacy/_includes/api/en/3x/req-ips.md
diff --git a/_includes/api/en/3x/req-is.md b/legacy/_includes/api/en/3x/req-is.md
similarity index 100%
rename from _includes/api/en/3x/req-is.md
rename to legacy/_includes/api/en/3x/req-is.md
diff --git a/_includes/api/en/3x/req-originalUrl.md b/legacy/_includes/api/en/3x/req-originalUrl.md
similarity index 100%
rename from _includes/api/en/3x/req-originalUrl.md
rename to legacy/_includes/api/en/3x/req-originalUrl.md
diff --git a/_includes/api/en/3x/req-param.md b/legacy/_includes/api/en/3x/req-param.md
similarity index 100%
rename from _includes/api/en/3x/req-param.md
rename to legacy/_includes/api/en/3x/req-param.md
diff --git a/_includes/api/en/3x/req-params.md b/legacy/_includes/api/en/3x/req-params.md
similarity index 100%
rename from _includes/api/en/3x/req-params.md
rename to legacy/_includes/api/en/3x/req-params.md
diff --git a/_includes/api/en/3x/req-path.md b/legacy/_includes/api/en/3x/req-path.md
similarity index 100%
rename from _includes/api/en/3x/req-path.md
rename to legacy/_includes/api/en/3x/req-path.md
diff --git a/_includes/api/en/3x/req-protocol.md b/legacy/_includes/api/en/3x/req-protocol.md
similarity index 100%
rename from _includes/api/en/3x/req-protocol.md
rename to legacy/_includes/api/en/3x/req-protocol.md
diff --git a/_includes/api/en/3x/req-query.md b/legacy/_includes/api/en/3x/req-query.md
similarity index 100%
rename from _includes/api/en/3x/req-query.md
rename to legacy/_includes/api/en/3x/req-query.md
diff --git a/_includes/api/en/3x/req-res.md b/legacy/_includes/api/en/3x/req-res.md
similarity index 100%
rename from _includes/api/en/3x/req-res.md
rename to legacy/_includes/api/en/3x/req-res.md
diff --git a/_includes/api/en/3x/req-route.md b/legacy/_includes/api/en/3x/req-route.md
similarity index 100%
rename from _includes/api/en/3x/req-route.md
rename to legacy/_includes/api/en/3x/req-route.md
diff --git a/_includes/api/en/3x/req-secure.md b/legacy/_includes/api/en/3x/req-secure.md
similarity index 100%
rename from _includes/api/en/3x/req-secure.md
rename to legacy/_includes/api/en/3x/req-secure.md
diff --git a/_includes/api/en/3x/req-signedCookies.md b/legacy/_includes/api/en/3x/req-signedCookies.md
similarity index 100%
rename from _includes/api/en/3x/req-signedCookies.md
rename to legacy/_includes/api/en/3x/req-signedCookies.md
diff --git a/_includes/api/en/3x/req-stale.md b/legacy/_includes/api/en/3x/req-stale.md
similarity index 100%
rename from _includes/api/en/3x/req-stale.md
rename to legacy/_includes/api/en/3x/req-stale.md
diff --git a/_includes/api/en/3x/req-subdomains.md b/legacy/_includes/api/en/3x/req-subdomains.md
similarity index 100%
rename from _includes/api/en/3x/req-subdomains.md
rename to legacy/_includes/api/en/3x/req-subdomains.md
diff --git a/_includes/api/en/3x/req-xhr.md b/legacy/_includes/api/en/3x/req-xhr.md
similarity index 100%
rename from _includes/api/en/3x/req-xhr.md
rename to legacy/_includes/api/en/3x/req-xhr.md
diff --git a/_includes/api/en/3x/req.md b/legacy/_includes/api/en/3x/req.md
similarity index 100%
rename from _includes/api/en/3x/req.md
rename to legacy/_includes/api/en/3x/req.md
diff --git a/_includes/api/en/3x/res-attachment.md b/legacy/_includes/api/en/3x/res-attachment.md
similarity index 100%
rename from _includes/api/en/3x/res-attachment.md
rename to legacy/_includes/api/en/3x/res-attachment.md
diff --git a/_includes/api/en/3x/res-charset.md b/legacy/_includes/api/en/3x/res-charset.md
similarity index 100%
rename from _includes/api/en/3x/res-charset.md
rename to legacy/_includes/api/en/3x/res-charset.md
diff --git a/_includes/api/en/3x/res-clearCookie.md b/legacy/_includes/api/en/3x/res-clearCookie.md
similarity index 100%
rename from _includes/api/en/3x/res-clearCookie.md
rename to legacy/_includes/api/en/3x/res-clearCookie.md
diff --git a/_includes/api/en/3x/res-cookie.md b/legacy/_includes/api/en/3x/res-cookie.md
similarity index 100%
rename from _includes/api/en/3x/res-cookie.md
rename to legacy/_includes/api/en/3x/res-cookie.md
diff --git a/_includes/api/en/3x/res-download.md b/legacy/_includes/api/en/3x/res-download.md
similarity index 100%
rename from _includes/api/en/3x/res-download.md
rename to legacy/_includes/api/en/3x/res-download.md
diff --git a/_includes/api/en/3x/res-format.md b/legacy/_includes/api/en/3x/res-format.md
similarity index 100%
rename from _includes/api/en/3x/res-format.md
rename to legacy/_includes/api/en/3x/res-format.md
diff --git a/_includes/api/en/3x/res-get.md b/legacy/_includes/api/en/3x/res-get.md
similarity index 100%
rename from _includes/api/en/3x/res-get.md
rename to legacy/_includes/api/en/3x/res-get.md
diff --git a/_includes/api/en/3x/res-json.md b/legacy/_includes/api/en/3x/res-json.md
similarity index 100%
rename from _includes/api/en/3x/res-json.md
rename to legacy/_includes/api/en/3x/res-json.md
diff --git a/_includes/api/en/3x/res-jsonp.md b/legacy/_includes/api/en/3x/res-jsonp.md
similarity index 100%
rename from _includes/api/en/3x/res-jsonp.md
rename to legacy/_includes/api/en/3x/res-jsonp.md
diff --git a/_includes/api/en/3x/res-links.md b/legacy/_includes/api/en/3x/res-links.md
similarity index 100%
rename from _includes/api/en/3x/res-links.md
rename to legacy/_includes/api/en/3x/res-links.md
diff --git a/_includes/api/en/3x/res-locals.md b/legacy/_includes/api/en/3x/res-locals.md
similarity index 100%
rename from _includes/api/en/3x/res-locals.md
rename to legacy/_includes/api/en/3x/res-locals.md
diff --git a/_includes/api/en/3x/res-location.md b/legacy/_includes/api/en/3x/res-location.md
similarity index 100%
rename from _includes/api/en/3x/res-location.md
rename to legacy/_includes/api/en/3x/res-location.md
diff --git a/_includes/api/en/3x/res-redirect.md b/legacy/_includes/api/en/3x/res-redirect.md
similarity index 100%
rename from _includes/api/en/3x/res-redirect.md
rename to legacy/_includes/api/en/3x/res-redirect.md
diff --git a/_includes/api/en/3x/res-render.md b/legacy/_includes/api/en/3x/res-render.md
similarity index 100%
rename from _includes/api/en/3x/res-render.md
rename to legacy/_includes/api/en/3x/res-render.md
diff --git a/_includes/api/en/3x/res-req.md b/legacy/_includes/api/en/3x/res-req.md
similarity index 100%
rename from _includes/api/en/3x/res-req.md
rename to legacy/_includes/api/en/3x/res-req.md
diff --git a/_includes/api/en/3x/res-send.md b/legacy/_includes/api/en/3x/res-send.md
similarity index 100%
rename from _includes/api/en/3x/res-send.md
rename to legacy/_includes/api/en/3x/res-send.md
diff --git a/_includes/api/en/3x/res-sendfile.md b/legacy/_includes/api/en/3x/res-sendfile.md
similarity index 100%
rename from _includes/api/en/3x/res-sendfile.md
rename to legacy/_includes/api/en/3x/res-sendfile.md
diff --git a/_includes/api/en/3x/res-set.md b/legacy/_includes/api/en/3x/res-set.md
similarity index 100%
rename from _includes/api/en/3x/res-set.md
rename to legacy/_includes/api/en/3x/res-set.md
diff --git a/_includes/api/en/3x/res-status.md b/legacy/_includes/api/en/3x/res-status.md
similarity index 100%
rename from _includes/api/en/3x/res-status.md
rename to legacy/_includes/api/en/3x/res-status.md
diff --git a/_includes/api/en/3x/res-type.md b/legacy/_includes/api/en/3x/res-type.md
similarity index 100%
rename from _includes/api/en/3x/res-type.md
rename to legacy/_includes/api/en/3x/res-type.md
diff --git a/_includes/api/en/3x/res.md b/legacy/_includes/api/en/3x/res.md
similarity index 100%
rename from _includes/api/en/3x/res.md
rename to legacy/_includes/api/en/3x/res.md
diff --git a/_includes/api/en/4x/app-METHOD.md b/legacy/_includes/api/en/4x/app-METHOD.md
similarity index 100%
rename from _includes/api/en/4x/app-METHOD.md
rename to legacy/_includes/api/en/4x/app-METHOD.md
diff --git a/_includes/api/en/4x/app-all.md b/legacy/_includes/api/en/4x/app-all.md
similarity index 100%
rename from _includes/api/en/4x/app-all.md
rename to legacy/_includes/api/en/4x/app-all.md
diff --git a/_includes/api/en/4x/app-delete-method.md b/legacy/_includes/api/en/4x/app-delete-method.md
similarity index 100%
rename from _includes/api/en/4x/app-delete-method.md
rename to legacy/_includes/api/en/4x/app-delete-method.md
diff --git a/_includes/api/en/4x/app-disable.md b/legacy/_includes/api/en/4x/app-disable.md
similarity index 100%
rename from _includes/api/en/4x/app-disable.md
rename to legacy/_includes/api/en/4x/app-disable.md
diff --git a/_includes/api/en/4x/app-disabled.md b/legacy/_includes/api/en/4x/app-disabled.md
similarity index 100%
rename from _includes/api/en/4x/app-disabled.md
rename to legacy/_includes/api/en/4x/app-disabled.md
diff --git a/_includes/api/en/4x/app-enable.md b/legacy/_includes/api/en/4x/app-enable.md
similarity index 100%
rename from _includes/api/en/4x/app-enable.md
rename to legacy/_includes/api/en/4x/app-enable.md
diff --git a/_includes/api/en/4x/app-enabled.md b/legacy/_includes/api/en/4x/app-enabled.md
similarity index 100%
rename from _includes/api/en/4x/app-enabled.md
rename to legacy/_includes/api/en/4x/app-enabled.md
diff --git a/_includes/api/en/4x/app-engine.md b/legacy/_includes/api/en/4x/app-engine.md
similarity index 100%
rename from _includes/api/en/4x/app-engine.md
rename to legacy/_includes/api/en/4x/app-engine.md
diff --git a/_includes/api/en/4x/app-get-method.md b/legacy/_includes/api/en/4x/app-get-method.md
similarity index 100%
rename from _includes/api/en/4x/app-get-method.md
rename to legacy/_includes/api/en/4x/app-get-method.md
diff --git a/_includes/api/en/4x/app-get.md b/legacy/_includes/api/en/4x/app-get.md
similarity index 100%
rename from _includes/api/en/4x/app-get.md
rename to legacy/_includes/api/en/4x/app-get.md
diff --git a/_includes/api/en/4x/app-listen.md b/legacy/_includes/api/en/4x/app-listen.md
similarity index 100%
rename from _includes/api/en/4x/app-listen.md
rename to legacy/_includes/api/en/4x/app-listen.md
diff --git a/_includes/api/en/4x/app-locals.md b/legacy/_includes/api/en/4x/app-locals.md
similarity index 100%
rename from _includes/api/en/4x/app-locals.md
rename to legacy/_includes/api/en/4x/app-locals.md
diff --git a/_includes/api/en/4x/app-mountpath.md b/legacy/_includes/api/en/4x/app-mountpath.md
similarity index 100%
rename from _includes/api/en/4x/app-mountpath.md
rename to legacy/_includes/api/en/4x/app-mountpath.md
diff --git a/_includes/api/en/4x/app-onmount.md b/legacy/_includes/api/en/4x/app-onmount.md
similarity index 100%
rename from _includes/api/en/4x/app-onmount.md
rename to legacy/_includes/api/en/4x/app-onmount.md
diff --git a/_includes/api/en/4x/app-param.md b/legacy/_includes/api/en/4x/app-param.md
similarity index 100%
rename from _includes/api/en/4x/app-param.md
rename to legacy/_includes/api/en/4x/app-param.md
diff --git a/_includes/api/en/4x/app-path.md b/legacy/_includes/api/en/4x/app-path.md
similarity index 100%
rename from _includes/api/en/4x/app-path.md
rename to legacy/_includes/api/en/4x/app-path.md
diff --git a/_includes/api/en/4x/app-post-method.md b/legacy/_includes/api/en/4x/app-post-method.md
similarity index 100%
rename from _includes/api/en/4x/app-post-method.md
rename to legacy/_includes/api/en/4x/app-post-method.md
diff --git a/_includes/api/en/4x/app-put-method.md b/legacy/_includes/api/en/4x/app-put-method.md
similarity index 100%
rename from _includes/api/en/4x/app-put-method.md
rename to legacy/_includes/api/en/4x/app-put-method.md
diff --git a/_includes/api/en/4x/app-render.md b/legacy/_includes/api/en/4x/app-render.md
similarity index 100%
rename from _includes/api/en/4x/app-render.md
rename to legacy/_includes/api/en/4x/app-render.md
diff --git a/_includes/api/en/4x/app-route.md b/legacy/_includes/api/en/4x/app-route.md
similarity index 100%
rename from _includes/api/en/4x/app-route.md
rename to legacy/_includes/api/en/4x/app-route.md
diff --git a/_includes/api/en/4x/app-set.md b/legacy/_includes/api/en/4x/app-set.md
similarity index 100%
rename from _includes/api/en/4x/app-set.md
rename to legacy/_includes/api/en/4x/app-set.md
diff --git a/_includes/api/en/4x/app-settings.md b/legacy/_includes/api/en/4x/app-settings.md
similarity index 100%
rename from _includes/api/en/4x/app-settings.md
rename to legacy/_includes/api/en/4x/app-settings.md
diff --git a/_includes/api/en/4x/app-use.md b/legacy/_includes/api/en/4x/app-use.md
similarity index 100%
rename from _includes/api/en/4x/app-use.md
rename to legacy/_includes/api/en/4x/app-use.md
diff --git a/_includes/api/en/4x/app.md b/legacy/_includes/api/en/4x/app.md
similarity index 100%
rename from _includes/api/en/4x/app.md
rename to legacy/_includes/api/en/4x/app.md
diff --git a/_includes/api/en/4x/express.json.md b/legacy/_includes/api/en/4x/express.json.md
similarity index 100%
rename from _includes/api/en/4x/express.json.md
rename to legacy/_includes/api/en/4x/express.json.md
diff --git a/_includes/api/en/4x/express.md b/legacy/_includes/api/en/4x/express.md
similarity index 100%
rename from _includes/api/en/4x/express.md
rename to legacy/_includes/api/en/4x/express.md
diff --git a/_includes/api/en/4x/express.raw.md b/legacy/_includes/api/en/4x/express.raw.md
similarity index 100%
rename from _includes/api/en/4x/express.raw.md
rename to legacy/_includes/api/en/4x/express.raw.md
diff --git a/_includes/api/en/4x/express.router.md b/legacy/_includes/api/en/4x/express.router.md
similarity index 100%
rename from _includes/api/en/4x/express.router.md
rename to legacy/_includes/api/en/4x/express.router.md
diff --git a/_includes/api/en/4x/express.static.md b/legacy/_includes/api/en/4x/express.static.md
similarity index 100%
rename from _includes/api/en/4x/express.static.md
rename to legacy/_includes/api/en/4x/express.static.md
diff --git a/_includes/api/en/4x/express.text.md b/legacy/_includes/api/en/4x/express.text.md
similarity index 100%
rename from _includes/api/en/4x/express.text.md
rename to legacy/_includes/api/en/4x/express.text.md
diff --git a/_includes/api/en/4x/express.urlencoded.md b/legacy/_includes/api/en/4x/express.urlencoded.md
similarity index 100%
rename from _includes/api/en/4x/express.urlencoded.md
rename to legacy/_includes/api/en/4x/express.urlencoded.md
diff --git a/_includes/api/en/4x/menu.md b/legacy/_includes/api/en/4x/menu.md
similarity index 100%
rename from _includes/api/en/4x/menu.md
rename to legacy/_includes/api/en/4x/menu.md
diff --git a/_includes/api/en/4x/req-accepts.md b/legacy/_includes/api/en/4x/req-accepts.md
similarity index 100%
rename from _includes/api/en/4x/req-accepts.md
rename to legacy/_includes/api/en/4x/req-accepts.md
diff --git a/_includes/api/en/4x/req-acceptsCharsets.md b/legacy/_includes/api/en/4x/req-acceptsCharsets.md
similarity index 100%
rename from _includes/api/en/4x/req-acceptsCharsets.md
rename to legacy/_includes/api/en/4x/req-acceptsCharsets.md
diff --git a/_includes/api/en/4x/req-acceptsEncodings.md b/legacy/_includes/api/en/4x/req-acceptsEncodings.md
similarity index 100%
rename from _includes/api/en/4x/req-acceptsEncodings.md
rename to legacy/_includes/api/en/4x/req-acceptsEncodings.md
diff --git a/_includes/api/en/4x/req-acceptsLanguages.md b/legacy/_includes/api/en/4x/req-acceptsLanguages.md
similarity index 100%
rename from _includes/api/en/4x/req-acceptsLanguages.md
rename to legacy/_includes/api/en/4x/req-acceptsLanguages.md
diff --git a/_includes/api/en/4x/req-app.md b/legacy/_includes/api/en/4x/req-app.md
similarity index 100%
rename from _includes/api/en/4x/req-app.md
rename to legacy/_includes/api/en/4x/req-app.md
diff --git a/_includes/api/en/4x/req-baseUrl.md b/legacy/_includes/api/en/4x/req-baseUrl.md
similarity index 100%
rename from _includes/api/en/4x/req-baseUrl.md
rename to legacy/_includes/api/en/4x/req-baseUrl.md
diff --git a/_includes/api/en/4x/req-body.md b/legacy/_includes/api/en/4x/req-body.md
similarity index 100%
rename from _includes/api/en/4x/req-body.md
rename to legacy/_includes/api/en/4x/req-body.md
diff --git a/_includes/api/en/4x/req-cookies.md b/legacy/_includes/api/en/4x/req-cookies.md
similarity index 100%
rename from _includes/api/en/4x/req-cookies.md
rename to legacy/_includes/api/en/4x/req-cookies.md
diff --git a/_includes/api/en/4x/req-fresh.md b/legacy/_includes/api/en/4x/req-fresh.md
similarity index 100%
rename from _includes/api/en/4x/req-fresh.md
rename to legacy/_includes/api/en/4x/req-fresh.md
diff --git a/_includes/api/en/4x/req-get.md b/legacy/_includes/api/en/4x/req-get.md
similarity index 100%
rename from _includes/api/en/4x/req-get.md
rename to legacy/_includes/api/en/4x/req-get.md
diff --git a/_includes/api/en/4x/req-hostname.md b/legacy/_includes/api/en/4x/req-hostname.md
similarity index 100%
rename from _includes/api/en/4x/req-hostname.md
rename to legacy/_includes/api/en/4x/req-hostname.md
diff --git a/_includes/api/en/4x/req-ip.md b/legacy/_includes/api/en/4x/req-ip.md
similarity index 100%
rename from _includes/api/en/4x/req-ip.md
rename to legacy/_includes/api/en/4x/req-ip.md
diff --git a/_includes/api/en/4x/req-ips.md b/legacy/_includes/api/en/4x/req-ips.md
similarity index 100%
rename from _includes/api/en/4x/req-ips.md
rename to legacy/_includes/api/en/4x/req-ips.md
diff --git a/_includes/api/en/4x/req-is.md b/legacy/_includes/api/en/4x/req-is.md
similarity index 100%
rename from _includes/api/en/4x/req-is.md
rename to legacy/_includes/api/en/4x/req-is.md
diff --git a/_includes/api/en/4x/req-method.md b/legacy/_includes/api/en/4x/req-method.md
similarity index 100%
rename from _includes/api/en/4x/req-method.md
rename to legacy/_includes/api/en/4x/req-method.md
diff --git a/_includes/api/en/4x/req-originalUrl.md b/legacy/_includes/api/en/4x/req-originalUrl.md
similarity index 100%
rename from _includes/api/en/4x/req-originalUrl.md
rename to legacy/_includes/api/en/4x/req-originalUrl.md
diff --git a/_includes/api/en/4x/req-param.md b/legacy/_includes/api/en/4x/req-param.md
similarity index 100%
rename from _includes/api/en/4x/req-param.md
rename to legacy/_includes/api/en/4x/req-param.md
diff --git a/_includes/api/en/4x/req-params.md b/legacy/_includes/api/en/4x/req-params.md
similarity index 100%
rename from _includes/api/en/4x/req-params.md
rename to legacy/_includes/api/en/4x/req-params.md
diff --git a/_includes/api/en/4x/req-path.md b/legacy/_includes/api/en/4x/req-path.md
similarity index 100%
rename from _includes/api/en/4x/req-path.md
rename to legacy/_includes/api/en/4x/req-path.md
diff --git a/_includes/api/en/4x/req-protocol.md b/legacy/_includes/api/en/4x/req-protocol.md
similarity index 100%
rename from _includes/api/en/4x/req-protocol.md
rename to legacy/_includes/api/en/4x/req-protocol.md
diff --git a/_includes/api/en/4x/req-query.md b/legacy/_includes/api/en/4x/req-query.md
similarity index 100%
rename from _includes/api/en/4x/req-query.md
rename to legacy/_includes/api/en/4x/req-query.md
diff --git a/_includes/api/en/4x/req-range.md b/legacy/_includes/api/en/4x/req-range.md
similarity index 100%
rename from _includes/api/en/4x/req-range.md
rename to legacy/_includes/api/en/4x/req-range.md
diff --git a/_includes/api/en/4x/req-res.md b/legacy/_includes/api/en/4x/req-res.md
similarity index 100%
rename from _includes/api/en/4x/req-res.md
rename to legacy/_includes/api/en/4x/req-res.md
diff --git a/_includes/api/en/4x/req-route.md b/legacy/_includes/api/en/4x/req-route.md
similarity index 100%
rename from _includes/api/en/4x/req-route.md
rename to legacy/_includes/api/en/4x/req-route.md
diff --git a/_includes/api/en/4x/req-secure.md b/legacy/_includes/api/en/4x/req-secure.md
similarity index 100%
rename from _includes/api/en/4x/req-secure.md
rename to legacy/_includes/api/en/4x/req-secure.md
diff --git a/_includes/api/en/4x/req-signedCookies.md b/legacy/_includes/api/en/4x/req-signedCookies.md
similarity index 100%
rename from _includes/api/en/4x/req-signedCookies.md
rename to legacy/_includes/api/en/4x/req-signedCookies.md
diff --git a/_includes/api/en/4x/req-stale.md b/legacy/_includes/api/en/4x/req-stale.md
similarity index 100%
rename from _includes/api/en/4x/req-stale.md
rename to legacy/_includes/api/en/4x/req-stale.md
diff --git a/_includes/api/en/4x/req-subdomains.md b/legacy/_includes/api/en/4x/req-subdomains.md
similarity index 100%
rename from _includes/api/en/4x/req-subdomains.md
rename to legacy/_includes/api/en/4x/req-subdomains.md
diff --git a/_includes/api/en/4x/req-xhr.md b/legacy/_includes/api/en/4x/req-xhr.md
similarity index 100%
rename from _includes/api/en/4x/req-xhr.md
rename to legacy/_includes/api/en/4x/req-xhr.md
diff --git a/_includes/api/en/4x/req.md b/legacy/_includes/api/en/4x/req.md
similarity index 100%
rename from _includes/api/en/4x/req.md
rename to legacy/_includes/api/en/4x/req.md
diff --git a/_includes/api/en/4x/res-app.md b/legacy/_includes/api/en/4x/res-app.md
similarity index 100%
rename from _includes/api/en/4x/res-app.md
rename to legacy/_includes/api/en/4x/res-app.md
diff --git a/_includes/api/en/4x/res-append.md b/legacy/_includes/api/en/4x/res-append.md
similarity index 100%
rename from _includes/api/en/4x/res-append.md
rename to legacy/_includes/api/en/4x/res-append.md
diff --git a/_includes/api/en/4x/res-attachment.md b/legacy/_includes/api/en/4x/res-attachment.md
similarity index 100%
rename from _includes/api/en/4x/res-attachment.md
rename to legacy/_includes/api/en/4x/res-attachment.md
diff --git a/_includes/api/en/4x/res-clearCookie.md b/legacy/_includes/api/en/4x/res-clearCookie.md
similarity index 100%
rename from _includes/api/en/4x/res-clearCookie.md
rename to legacy/_includes/api/en/4x/res-clearCookie.md
diff --git a/_includes/api/en/4x/res-cookie.md b/legacy/_includes/api/en/4x/res-cookie.md
similarity index 100%
rename from _includes/api/en/4x/res-cookie.md
rename to legacy/_includes/api/en/4x/res-cookie.md
diff --git a/_includes/api/en/4x/res-download.md b/legacy/_includes/api/en/4x/res-download.md
similarity index 100%
rename from _includes/api/en/4x/res-download.md
rename to legacy/_includes/api/en/4x/res-download.md
diff --git a/_includes/api/en/4x/res-end.md b/legacy/_includes/api/en/4x/res-end.md
similarity index 100%
rename from _includes/api/en/4x/res-end.md
rename to legacy/_includes/api/en/4x/res-end.md
diff --git a/_includes/api/en/4x/res-format.md b/legacy/_includes/api/en/4x/res-format.md
similarity index 100%
rename from _includes/api/en/4x/res-format.md
rename to legacy/_includes/api/en/4x/res-format.md
diff --git a/_includes/api/en/4x/res-get.md b/legacy/_includes/api/en/4x/res-get.md
similarity index 100%
rename from _includes/api/en/4x/res-get.md
rename to legacy/_includes/api/en/4x/res-get.md
diff --git a/_includes/api/en/4x/res-headersSent.md b/legacy/_includes/api/en/4x/res-headersSent.md
similarity index 100%
rename from _includes/api/en/4x/res-headersSent.md
rename to legacy/_includes/api/en/4x/res-headersSent.md
diff --git a/_includes/api/en/4x/res-json.md b/legacy/_includes/api/en/4x/res-json.md
similarity index 100%
rename from _includes/api/en/4x/res-json.md
rename to legacy/_includes/api/en/4x/res-json.md
diff --git a/_includes/api/en/4x/res-jsonp.md b/legacy/_includes/api/en/4x/res-jsonp.md
similarity index 100%
rename from _includes/api/en/4x/res-jsonp.md
rename to legacy/_includes/api/en/4x/res-jsonp.md
diff --git a/_includes/api/en/4x/res-links.md b/legacy/_includes/api/en/4x/res-links.md
similarity index 100%
rename from _includes/api/en/4x/res-links.md
rename to legacy/_includes/api/en/4x/res-links.md
diff --git a/_includes/api/en/4x/res-locals.md b/legacy/_includes/api/en/4x/res-locals.md
similarity index 100%
rename from _includes/api/en/4x/res-locals.md
rename to legacy/_includes/api/en/4x/res-locals.md
diff --git a/_includes/api/en/4x/res-location.md b/legacy/_includes/api/en/4x/res-location.md
similarity index 100%
rename from _includes/api/en/4x/res-location.md
rename to legacy/_includes/api/en/4x/res-location.md
diff --git a/_includes/api/en/4x/res-redirect.md b/legacy/_includes/api/en/4x/res-redirect.md
similarity index 100%
rename from _includes/api/en/4x/res-redirect.md
rename to legacy/_includes/api/en/4x/res-redirect.md
diff --git a/_includes/api/en/4x/res-render.md b/legacy/_includes/api/en/4x/res-render.md
similarity index 100%
rename from _includes/api/en/4x/res-render.md
rename to legacy/_includes/api/en/4x/res-render.md
diff --git a/_includes/api/en/4x/res-req.md b/legacy/_includes/api/en/4x/res-req.md
similarity index 100%
rename from _includes/api/en/4x/res-req.md
rename to legacy/_includes/api/en/4x/res-req.md
diff --git a/_includes/api/en/4x/res-send.md b/legacy/_includes/api/en/4x/res-send.md
similarity index 100%
rename from _includes/api/en/4x/res-send.md
rename to legacy/_includes/api/en/4x/res-send.md
diff --git a/_includes/api/en/4x/res-sendFile.md b/legacy/_includes/api/en/4x/res-sendFile.md
similarity index 100%
rename from _includes/api/en/4x/res-sendFile.md
rename to legacy/_includes/api/en/4x/res-sendFile.md
diff --git a/_includes/api/en/4x/res-sendStatus.md b/legacy/_includes/api/en/4x/res-sendStatus.md
similarity index 100%
rename from _includes/api/en/4x/res-sendStatus.md
rename to legacy/_includes/api/en/4x/res-sendStatus.md
diff --git a/_includes/api/en/4x/res-set.md b/legacy/_includes/api/en/4x/res-set.md
similarity index 100%
rename from _includes/api/en/4x/res-set.md
rename to legacy/_includes/api/en/4x/res-set.md
diff --git a/_includes/api/en/4x/res-status.md b/legacy/_includes/api/en/4x/res-status.md
similarity index 100%
rename from _includes/api/en/4x/res-status.md
rename to legacy/_includes/api/en/4x/res-status.md
diff --git a/_includes/api/en/4x/res-type.md b/legacy/_includes/api/en/4x/res-type.md
similarity index 100%
rename from _includes/api/en/4x/res-type.md
rename to legacy/_includes/api/en/4x/res-type.md
diff --git a/_includes/api/en/4x/res-vary.md b/legacy/_includes/api/en/4x/res-vary.md
similarity index 100%
rename from _includes/api/en/4x/res-vary.md
rename to legacy/_includes/api/en/4x/res-vary.md
diff --git a/_includes/api/en/4x/res.md b/legacy/_includes/api/en/4x/res.md
similarity index 100%
rename from _includes/api/en/4x/res.md
rename to legacy/_includes/api/en/4x/res.md
diff --git a/_includes/api/en/4x/router-METHOD.md b/legacy/_includes/api/en/4x/router-METHOD.md
similarity index 100%
rename from _includes/api/en/4x/router-METHOD.md
rename to legacy/_includes/api/en/4x/router-METHOD.md
diff --git a/_includes/api/en/4x/router-Router.md b/legacy/_includes/api/en/4x/router-Router.md
similarity index 100%
rename from _includes/api/en/4x/router-Router.md
rename to legacy/_includes/api/en/4x/router-Router.md
diff --git a/_includes/api/en/4x/router-all.md b/legacy/_includes/api/en/4x/router-all.md
similarity index 100%
rename from _includes/api/en/4x/router-all.md
rename to legacy/_includes/api/en/4x/router-all.md
diff --git a/_includes/api/en/4x/router-param.md b/legacy/_includes/api/en/4x/router-param.md
similarity index 100%
rename from _includes/api/en/4x/router-param.md
rename to legacy/_includes/api/en/4x/router-param.md
diff --git a/_includes/api/en/4x/router-route.md b/legacy/_includes/api/en/4x/router-route.md
similarity index 100%
rename from _includes/api/en/4x/router-route.md
rename to legacy/_includes/api/en/4x/router-route.md
diff --git a/_includes/api/en/4x/router-use.md b/legacy/_includes/api/en/4x/router-use.md
similarity index 100%
rename from _includes/api/en/4x/router-use.md
rename to legacy/_includes/api/en/4x/router-use.md
diff --git a/_includes/api/en/4x/router.md b/legacy/_includes/api/en/4x/router.md
similarity index 100%
rename from _includes/api/en/4x/router.md
rename to legacy/_includes/api/en/4x/router.md
diff --git a/_includes/api/en/4x/routing-args.html b/legacy/_includes/api/en/4x/routing-args.html
similarity index 100%
rename from _includes/api/en/4x/routing-args.html
rename to legacy/_includes/api/en/4x/routing-args.html
diff --git a/_includes/api/en/5x/app-METHOD.md b/legacy/_includes/api/en/5x/app-METHOD.md
similarity index 100%
rename from _includes/api/en/5x/app-METHOD.md
rename to legacy/_includes/api/en/5x/app-METHOD.md
diff --git a/_includes/api/en/5x/app-all.md b/legacy/_includes/api/en/5x/app-all.md
similarity index 100%
rename from _includes/api/en/5x/app-all.md
rename to legacy/_includes/api/en/5x/app-all.md
diff --git a/_includes/api/en/5x/app-delete-method.md b/legacy/_includes/api/en/5x/app-delete-method.md
similarity index 100%
rename from _includes/api/en/5x/app-delete-method.md
rename to legacy/_includes/api/en/5x/app-delete-method.md
diff --git a/_includes/api/en/5x/app-disable.md b/legacy/_includes/api/en/5x/app-disable.md
similarity index 100%
rename from _includes/api/en/5x/app-disable.md
rename to legacy/_includes/api/en/5x/app-disable.md
diff --git a/_includes/api/en/5x/app-disabled.md b/legacy/_includes/api/en/5x/app-disabled.md
similarity index 100%
rename from _includes/api/en/5x/app-disabled.md
rename to legacy/_includes/api/en/5x/app-disabled.md
diff --git a/_includes/api/en/5x/app-enable.md b/legacy/_includes/api/en/5x/app-enable.md
similarity index 100%
rename from _includes/api/en/5x/app-enable.md
rename to legacy/_includes/api/en/5x/app-enable.md
diff --git a/_includes/api/en/5x/app-enabled.md b/legacy/_includes/api/en/5x/app-enabled.md
similarity index 100%
rename from _includes/api/en/5x/app-enabled.md
rename to legacy/_includes/api/en/5x/app-enabled.md
diff --git a/_includes/api/en/5x/app-engine.md b/legacy/_includes/api/en/5x/app-engine.md
similarity index 100%
rename from _includes/api/en/5x/app-engine.md
rename to legacy/_includes/api/en/5x/app-engine.md
diff --git a/_includes/api/en/5x/app-get-method.md b/legacy/_includes/api/en/5x/app-get-method.md
similarity index 100%
rename from _includes/api/en/5x/app-get-method.md
rename to legacy/_includes/api/en/5x/app-get-method.md
diff --git a/_includes/api/en/5x/app-get.md b/legacy/_includes/api/en/5x/app-get.md
similarity index 100%
rename from _includes/api/en/5x/app-get.md
rename to legacy/_includes/api/en/5x/app-get.md
diff --git a/_includes/api/en/5x/app-listen.md b/legacy/_includes/api/en/5x/app-listen.md
similarity index 100%
rename from _includes/api/en/5x/app-listen.md
rename to legacy/_includes/api/en/5x/app-listen.md
diff --git a/_includes/api/en/5x/app-locals.md b/legacy/_includes/api/en/5x/app-locals.md
similarity index 100%
rename from _includes/api/en/5x/app-locals.md
rename to legacy/_includes/api/en/5x/app-locals.md
diff --git a/_includes/api/en/5x/app-mountpath.md b/legacy/_includes/api/en/5x/app-mountpath.md
similarity index 100%
rename from _includes/api/en/5x/app-mountpath.md
rename to legacy/_includes/api/en/5x/app-mountpath.md
diff --git a/_includes/api/en/5x/app-onmount.md b/legacy/_includes/api/en/5x/app-onmount.md
similarity index 100%
rename from _includes/api/en/5x/app-onmount.md
rename to legacy/_includes/api/en/5x/app-onmount.md
diff --git a/_includes/api/en/5x/app-param.md b/legacy/_includes/api/en/5x/app-param.md
similarity index 100%
rename from _includes/api/en/5x/app-param.md
rename to legacy/_includes/api/en/5x/app-param.md
diff --git a/_includes/api/en/5x/app-path.md b/legacy/_includes/api/en/5x/app-path.md
similarity index 100%
rename from _includes/api/en/5x/app-path.md
rename to legacy/_includes/api/en/5x/app-path.md
diff --git a/_includes/api/en/5x/app-post-method.md b/legacy/_includes/api/en/5x/app-post-method.md
similarity index 100%
rename from _includes/api/en/5x/app-post-method.md
rename to legacy/_includes/api/en/5x/app-post-method.md
diff --git a/_includes/api/en/5x/app-put-method.md b/legacy/_includes/api/en/5x/app-put-method.md
similarity index 100%
rename from _includes/api/en/5x/app-put-method.md
rename to legacy/_includes/api/en/5x/app-put-method.md
diff --git a/_includes/api/en/5x/app-render.md b/legacy/_includes/api/en/5x/app-render.md
similarity index 100%
rename from _includes/api/en/5x/app-render.md
rename to legacy/_includes/api/en/5x/app-render.md
diff --git a/_includes/api/en/5x/app-route.md b/legacy/_includes/api/en/5x/app-route.md
similarity index 100%
rename from _includes/api/en/5x/app-route.md
rename to legacy/_includes/api/en/5x/app-route.md
diff --git a/_includes/api/en/5x/app-router.md b/legacy/_includes/api/en/5x/app-router.md
similarity index 100%
rename from _includes/api/en/5x/app-router.md
rename to legacy/_includes/api/en/5x/app-router.md
diff --git a/_includes/api/en/5x/app-set.md b/legacy/_includes/api/en/5x/app-set.md
similarity index 100%
rename from _includes/api/en/5x/app-set.md
rename to legacy/_includes/api/en/5x/app-set.md
diff --git a/_includes/api/en/5x/app-settings.md b/legacy/_includes/api/en/5x/app-settings.md
similarity index 100%
rename from _includes/api/en/5x/app-settings.md
rename to legacy/_includes/api/en/5x/app-settings.md
diff --git a/_includes/api/en/5x/app-use.md b/legacy/_includes/api/en/5x/app-use.md
similarity index 100%
rename from _includes/api/en/5x/app-use.md
rename to legacy/_includes/api/en/5x/app-use.md
diff --git a/_includes/api/en/5x/app.md b/legacy/_includes/api/en/5x/app.md
similarity index 100%
rename from _includes/api/en/5x/app.md
rename to legacy/_includes/api/en/5x/app.md
diff --git a/_includes/api/en/5x/express.json.md b/legacy/_includes/api/en/5x/express.json.md
similarity index 100%
rename from _includes/api/en/5x/express.json.md
rename to legacy/_includes/api/en/5x/express.json.md
diff --git a/_includes/api/en/5x/express.md b/legacy/_includes/api/en/5x/express.md
similarity index 100%
rename from _includes/api/en/5x/express.md
rename to legacy/_includes/api/en/5x/express.md
diff --git a/_includes/api/en/5x/express.raw.md b/legacy/_includes/api/en/5x/express.raw.md
similarity index 100%
rename from _includes/api/en/5x/express.raw.md
rename to legacy/_includes/api/en/5x/express.raw.md
diff --git a/_includes/api/en/5x/express.router.md b/legacy/_includes/api/en/5x/express.router.md
similarity index 100%
rename from _includes/api/en/5x/express.router.md
rename to legacy/_includes/api/en/5x/express.router.md
diff --git a/_includes/api/en/5x/express.static.md b/legacy/_includes/api/en/5x/express.static.md
similarity index 100%
rename from _includes/api/en/5x/express.static.md
rename to legacy/_includes/api/en/5x/express.static.md
diff --git a/_includes/api/en/5x/express.text.md b/legacy/_includes/api/en/5x/express.text.md
similarity index 100%
rename from _includes/api/en/5x/express.text.md
rename to legacy/_includes/api/en/5x/express.text.md
diff --git a/_includes/api/en/5x/express.urlencoded.md b/legacy/_includes/api/en/5x/express.urlencoded.md
similarity index 100%
rename from _includes/api/en/5x/express.urlencoded.md
rename to legacy/_includes/api/en/5x/express.urlencoded.md
diff --git a/_includes/api/en/5x/menu.md b/legacy/_includes/api/en/5x/menu.md
similarity index 100%
rename from _includes/api/en/5x/menu.md
rename to legacy/_includes/api/en/5x/menu.md
diff --git a/_includes/api/en/5x/req-accepts.md b/legacy/_includes/api/en/5x/req-accepts.md
similarity index 100%
rename from _includes/api/en/5x/req-accepts.md
rename to legacy/_includes/api/en/5x/req-accepts.md
diff --git a/_includes/api/en/5x/req-acceptsCharsets.md b/legacy/_includes/api/en/5x/req-acceptsCharsets.md
similarity index 100%
rename from _includes/api/en/5x/req-acceptsCharsets.md
rename to legacy/_includes/api/en/5x/req-acceptsCharsets.md
diff --git a/_includes/api/en/5x/req-acceptsEncodings.md b/legacy/_includes/api/en/5x/req-acceptsEncodings.md
similarity index 100%
rename from _includes/api/en/5x/req-acceptsEncodings.md
rename to legacy/_includes/api/en/5x/req-acceptsEncodings.md
diff --git a/_includes/api/en/5x/req-acceptsLanguages.md b/legacy/_includes/api/en/5x/req-acceptsLanguages.md
similarity index 100%
rename from _includes/api/en/5x/req-acceptsLanguages.md
rename to legacy/_includes/api/en/5x/req-acceptsLanguages.md
diff --git a/_includes/api/en/5x/req-app.md b/legacy/_includes/api/en/5x/req-app.md
similarity index 100%
rename from _includes/api/en/5x/req-app.md
rename to legacy/_includes/api/en/5x/req-app.md
diff --git a/_includes/api/en/5x/req-baseUrl.md b/legacy/_includes/api/en/5x/req-baseUrl.md
similarity index 100%
rename from _includes/api/en/5x/req-baseUrl.md
rename to legacy/_includes/api/en/5x/req-baseUrl.md
diff --git a/_includes/api/en/5x/req-body.md b/legacy/_includes/api/en/5x/req-body.md
similarity index 100%
rename from _includes/api/en/5x/req-body.md
rename to legacy/_includes/api/en/5x/req-body.md
diff --git a/_includes/api/en/5x/req-cookies.md b/legacy/_includes/api/en/5x/req-cookies.md
similarity index 100%
rename from _includes/api/en/5x/req-cookies.md
rename to legacy/_includes/api/en/5x/req-cookies.md
diff --git a/_includes/api/en/5x/req-fresh.md b/legacy/_includes/api/en/5x/req-fresh.md
similarity index 100%
rename from _includes/api/en/5x/req-fresh.md
rename to legacy/_includes/api/en/5x/req-fresh.md
diff --git a/_includes/api/en/5x/req-get.md b/legacy/_includes/api/en/5x/req-get.md
similarity index 100%
rename from _includes/api/en/5x/req-get.md
rename to legacy/_includes/api/en/5x/req-get.md
diff --git a/_includes/api/en/5x/req-host.md b/legacy/_includes/api/en/5x/req-host.md
similarity index 100%
rename from _includes/api/en/5x/req-host.md
rename to legacy/_includes/api/en/5x/req-host.md
diff --git a/_includes/api/en/5x/req-hostname.md b/legacy/_includes/api/en/5x/req-hostname.md
similarity index 100%
rename from _includes/api/en/5x/req-hostname.md
rename to legacy/_includes/api/en/5x/req-hostname.md
diff --git a/_includes/api/en/5x/req-ip.md b/legacy/_includes/api/en/5x/req-ip.md
similarity index 100%
rename from _includes/api/en/5x/req-ip.md
rename to legacy/_includes/api/en/5x/req-ip.md
diff --git a/_includes/api/en/5x/req-ips.md b/legacy/_includes/api/en/5x/req-ips.md
similarity index 100%
rename from _includes/api/en/5x/req-ips.md
rename to legacy/_includes/api/en/5x/req-ips.md
diff --git a/_includes/api/en/5x/req-is.md b/legacy/_includes/api/en/5x/req-is.md
similarity index 100%
rename from _includes/api/en/5x/req-is.md
rename to legacy/_includes/api/en/5x/req-is.md
diff --git a/_includes/api/en/5x/req-method.md b/legacy/_includes/api/en/5x/req-method.md
similarity index 100%
rename from _includes/api/en/5x/req-method.md
rename to legacy/_includes/api/en/5x/req-method.md
diff --git a/_includes/api/en/5x/req-originalUrl.md b/legacy/_includes/api/en/5x/req-originalUrl.md
similarity index 100%
rename from _includes/api/en/5x/req-originalUrl.md
rename to legacy/_includes/api/en/5x/req-originalUrl.md
diff --git a/_includes/api/en/5x/req-params.md b/legacy/_includes/api/en/5x/req-params.md
similarity index 100%
rename from _includes/api/en/5x/req-params.md
rename to legacy/_includes/api/en/5x/req-params.md
diff --git a/_includes/api/en/5x/req-path.md b/legacy/_includes/api/en/5x/req-path.md
similarity index 100%
rename from _includes/api/en/5x/req-path.md
rename to legacy/_includes/api/en/5x/req-path.md
diff --git a/_includes/api/en/5x/req-protocol.md b/legacy/_includes/api/en/5x/req-protocol.md
similarity index 100%
rename from _includes/api/en/5x/req-protocol.md
rename to legacy/_includes/api/en/5x/req-protocol.md
diff --git a/_includes/api/en/5x/req-query.md b/legacy/_includes/api/en/5x/req-query.md
similarity index 100%
rename from _includes/api/en/5x/req-query.md
rename to legacy/_includes/api/en/5x/req-query.md
diff --git a/_includes/api/en/5x/req-range.md b/legacy/_includes/api/en/5x/req-range.md
similarity index 100%
rename from _includes/api/en/5x/req-range.md
rename to legacy/_includes/api/en/5x/req-range.md
diff --git a/_includes/api/en/5x/req-res.md b/legacy/_includes/api/en/5x/req-res.md
similarity index 100%
rename from _includes/api/en/5x/req-res.md
rename to legacy/_includes/api/en/5x/req-res.md
diff --git a/_includes/api/en/5x/req-route.md b/legacy/_includes/api/en/5x/req-route.md
similarity index 100%
rename from _includes/api/en/5x/req-route.md
rename to legacy/_includes/api/en/5x/req-route.md
diff --git a/_includes/api/en/5x/req-secure.md b/legacy/_includes/api/en/5x/req-secure.md
similarity index 100%
rename from _includes/api/en/5x/req-secure.md
rename to legacy/_includes/api/en/5x/req-secure.md
diff --git a/_includes/api/en/5x/req-signedCookies.md b/legacy/_includes/api/en/5x/req-signedCookies.md
similarity index 100%
rename from _includes/api/en/5x/req-signedCookies.md
rename to legacy/_includes/api/en/5x/req-signedCookies.md
diff --git a/_includes/api/en/5x/req-stale.md b/legacy/_includes/api/en/5x/req-stale.md
similarity index 100%
rename from _includes/api/en/5x/req-stale.md
rename to legacy/_includes/api/en/5x/req-stale.md
diff --git a/_includes/api/en/5x/req-subdomains.md b/legacy/_includes/api/en/5x/req-subdomains.md
similarity index 100%
rename from _includes/api/en/5x/req-subdomains.md
rename to legacy/_includes/api/en/5x/req-subdomains.md
diff --git a/_includes/api/en/5x/req-xhr.md b/legacy/_includes/api/en/5x/req-xhr.md
similarity index 100%
rename from _includes/api/en/5x/req-xhr.md
rename to legacy/_includes/api/en/5x/req-xhr.md
diff --git a/_includes/api/en/5x/req.md b/legacy/_includes/api/en/5x/req.md
similarity index 100%
rename from _includes/api/en/5x/req.md
rename to legacy/_includes/api/en/5x/req.md
diff --git a/_includes/api/en/5x/res-app.md b/legacy/_includes/api/en/5x/res-app.md
similarity index 100%
rename from _includes/api/en/5x/res-app.md
rename to legacy/_includes/api/en/5x/res-app.md
diff --git a/_includes/api/en/5x/res-append.md b/legacy/_includes/api/en/5x/res-append.md
similarity index 100%
rename from _includes/api/en/5x/res-append.md
rename to legacy/_includes/api/en/5x/res-append.md
diff --git a/_includes/api/en/5x/res-attachment.md b/legacy/_includes/api/en/5x/res-attachment.md
similarity index 100%
rename from _includes/api/en/5x/res-attachment.md
rename to legacy/_includes/api/en/5x/res-attachment.md
diff --git a/_includes/api/en/5x/res-clearCookie.md b/legacy/_includes/api/en/5x/res-clearCookie.md
similarity index 100%
rename from _includes/api/en/5x/res-clearCookie.md
rename to legacy/_includes/api/en/5x/res-clearCookie.md
diff --git a/_includes/api/en/5x/res-cookie.md b/legacy/_includes/api/en/5x/res-cookie.md
similarity index 100%
rename from _includes/api/en/5x/res-cookie.md
rename to legacy/_includes/api/en/5x/res-cookie.md
diff --git a/_includes/api/en/5x/res-download.md b/legacy/_includes/api/en/5x/res-download.md
similarity index 100%
rename from _includes/api/en/5x/res-download.md
rename to legacy/_includes/api/en/5x/res-download.md
diff --git a/_includes/api/en/5x/res-end.md b/legacy/_includes/api/en/5x/res-end.md
similarity index 100%
rename from _includes/api/en/5x/res-end.md
rename to legacy/_includes/api/en/5x/res-end.md
diff --git a/_includes/api/en/5x/res-format.md b/legacy/_includes/api/en/5x/res-format.md
similarity index 100%
rename from _includes/api/en/5x/res-format.md
rename to legacy/_includes/api/en/5x/res-format.md
diff --git a/_includes/api/en/5x/res-get.md b/legacy/_includes/api/en/5x/res-get.md
similarity index 100%
rename from _includes/api/en/5x/res-get.md
rename to legacy/_includes/api/en/5x/res-get.md
diff --git a/_includes/api/en/5x/res-headersSent.md b/legacy/_includes/api/en/5x/res-headersSent.md
similarity index 100%
rename from _includes/api/en/5x/res-headersSent.md
rename to legacy/_includes/api/en/5x/res-headersSent.md
diff --git a/_includes/api/en/5x/res-json.md b/legacy/_includes/api/en/5x/res-json.md
similarity index 100%
rename from _includes/api/en/5x/res-json.md
rename to legacy/_includes/api/en/5x/res-json.md
diff --git a/_includes/api/en/5x/res-jsonp.md b/legacy/_includes/api/en/5x/res-jsonp.md
similarity index 100%
rename from _includes/api/en/5x/res-jsonp.md
rename to legacy/_includes/api/en/5x/res-jsonp.md
diff --git a/_includes/api/en/5x/res-links.md b/legacy/_includes/api/en/5x/res-links.md
similarity index 100%
rename from _includes/api/en/5x/res-links.md
rename to legacy/_includes/api/en/5x/res-links.md
diff --git a/_includes/api/en/5x/res-locals.md b/legacy/_includes/api/en/5x/res-locals.md
similarity index 100%
rename from _includes/api/en/5x/res-locals.md
rename to legacy/_includes/api/en/5x/res-locals.md
diff --git a/_includes/api/en/5x/res-location.md b/legacy/_includes/api/en/5x/res-location.md
similarity index 100%
rename from _includes/api/en/5x/res-location.md
rename to legacy/_includes/api/en/5x/res-location.md
diff --git a/_includes/api/en/5x/res-redirect.md b/legacy/_includes/api/en/5x/res-redirect.md
similarity index 100%
rename from _includes/api/en/5x/res-redirect.md
rename to legacy/_includes/api/en/5x/res-redirect.md
diff --git a/_includes/api/en/5x/res-render.md b/legacy/_includes/api/en/5x/res-render.md
similarity index 100%
rename from _includes/api/en/5x/res-render.md
rename to legacy/_includes/api/en/5x/res-render.md
diff --git a/_includes/api/en/5x/res-req.md b/legacy/_includes/api/en/5x/res-req.md
similarity index 100%
rename from _includes/api/en/5x/res-req.md
rename to legacy/_includes/api/en/5x/res-req.md
diff --git a/_includes/api/en/5x/res-send.md b/legacy/_includes/api/en/5x/res-send.md
similarity index 100%
rename from _includes/api/en/5x/res-send.md
rename to legacy/_includes/api/en/5x/res-send.md
diff --git a/_includes/api/en/5x/res-sendFile.md b/legacy/_includes/api/en/5x/res-sendFile.md
similarity index 100%
rename from _includes/api/en/5x/res-sendFile.md
rename to legacy/_includes/api/en/5x/res-sendFile.md
diff --git a/_includes/api/en/5x/res-sendStatus.md b/legacy/_includes/api/en/5x/res-sendStatus.md
similarity index 100%
rename from _includes/api/en/5x/res-sendStatus.md
rename to legacy/_includes/api/en/5x/res-sendStatus.md
diff --git a/_includes/api/en/5x/res-set.md b/legacy/_includes/api/en/5x/res-set.md
similarity index 100%
rename from _includes/api/en/5x/res-set.md
rename to legacy/_includes/api/en/5x/res-set.md
diff --git a/_includes/api/en/5x/res-status.md b/legacy/_includes/api/en/5x/res-status.md
similarity index 100%
rename from _includes/api/en/5x/res-status.md
rename to legacy/_includes/api/en/5x/res-status.md
diff --git a/_includes/api/en/5x/res-type.md b/legacy/_includes/api/en/5x/res-type.md
similarity index 100%
rename from _includes/api/en/5x/res-type.md
rename to legacy/_includes/api/en/5x/res-type.md
diff --git a/_includes/api/en/5x/res-vary.md b/legacy/_includes/api/en/5x/res-vary.md
similarity index 100%
rename from _includes/api/en/5x/res-vary.md
rename to legacy/_includes/api/en/5x/res-vary.md
diff --git a/_includes/api/en/5x/res.md b/legacy/_includes/api/en/5x/res.md
similarity index 100%
rename from _includes/api/en/5x/res.md
rename to legacy/_includes/api/en/5x/res.md
diff --git a/_includes/api/en/5x/router-METHOD.md b/legacy/_includes/api/en/5x/router-METHOD.md
similarity index 100%
rename from _includes/api/en/5x/router-METHOD.md
rename to legacy/_includes/api/en/5x/router-METHOD.md
diff --git a/_includes/api/en/5x/router-Router.md b/legacy/_includes/api/en/5x/router-Router.md
similarity index 100%
rename from _includes/api/en/5x/router-Router.md
rename to legacy/_includes/api/en/5x/router-Router.md
diff --git a/_includes/api/en/5x/router-all.md b/legacy/_includes/api/en/5x/router-all.md
similarity index 100%
rename from _includes/api/en/5x/router-all.md
rename to legacy/_includes/api/en/5x/router-all.md
diff --git a/_includes/api/en/5x/router-param.md b/legacy/_includes/api/en/5x/router-param.md
similarity index 100%
rename from _includes/api/en/5x/router-param.md
rename to legacy/_includes/api/en/5x/router-param.md
diff --git a/_includes/api/en/5x/router-route.md b/legacy/_includes/api/en/5x/router-route.md
similarity index 100%
rename from _includes/api/en/5x/router-route.md
rename to legacy/_includes/api/en/5x/router-route.md
diff --git a/_includes/api/en/5x/router-use.md b/legacy/_includes/api/en/5x/router-use.md
similarity index 100%
rename from _includes/api/en/5x/router-use.md
rename to legacy/_includes/api/en/5x/router-use.md
diff --git a/_includes/api/en/5x/router.md b/legacy/_includes/api/en/5x/router.md
similarity index 100%
rename from _includes/api/en/5x/router.md
rename to legacy/_includes/api/en/5x/router.md
diff --git a/_includes/api/en/5x/routing-args.html b/legacy/_includes/api/en/5x/routing-args.html
similarity index 100%
rename from _includes/api/en/5x/routing-args.html
rename to legacy/_includes/api/en/5x/routing-args.html
diff --git a/_includes/blog/authors.html b/legacy/_includes/blog/authors.html
similarity index 100%
rename from _includes/blog/authors.html
rename to legacy/_includes/blog/authors.html
diff --git a/_includes/blog/posts-menu.md b/legacy/_includes/blog/posts-menu.md
similarity index 100%
rename from _includes/blog/posts-menu.md
rename to legacy/_includes/blog/posts-menu.md
diff --git a/_includes/bottom-navigation.html b/legacy/_includes/bottom-navigation.html
similarity index 100%
rename from _includes/bottom-navigation.html
rename to legacy/_includes/bottom-navigation.html
diff --git a/_includes/changelog/menu.md b/legacy/_includes/changelog/menu.md
similarity index 100%
rename from _includes/changelog/menu.md
rename to legacy/_includes/changelog/menu.md
diff --git a/_includes/community-caveat.html b/legacy/_includes/community-caveat.html
similarity index 100%
rename from _includes/community-caveat.html
rename to legacy/_includes/community-caveat.html
diff --git a/_includes/feed-entry.xml b/legacy/_includes/feed-entry.xml
similarity index 100%
rename from _includes/feed-entry.xml
rename to legacy/_includes/feed-entry.xml
diff --git a/_includes/footer.html b/legacy/_includes/footer.html
similarity index 100%
rename from _includes/footer.html
rename to legacy/_includes/footer.html
diff --git a/_includes/github-edit-btn.html b/legacy/_includes/github-edit-btn.html
similarity index 100%
rename from _includes/github-edit-btn.html
rename to legacy/_includes/github-edit-btn.html
diff --git a/_includes/head.html b/legacy/_includes/head.html
similarity index 100%
rename from _includes/head.html
rename to legacy/_includes/head.html
diff --git a/_includes/header.html b/legacy/_includes/header.html
similarity index 100%
rename from _includes/header.html
rename to legacy/_includes/header.html
diff --git a/_includes/i18n-notice.html b/legacy/_includes/i18n-notice.html
similarity index 100%
rename from _includes/i18n-notice.html
rename to legacy/_includes/i18n-notice.html
diff --git a/_includes/icons/X.svg b/legacy/_includes/icons/X.svg
similarity index 100%
rename from _includes/icons/X.svg
rename to legacy/_includes/icons/X.svg
diff --git a/_includes/icons/announcement.svg b/legacy/_includes/icons/announcement.svg
similarity index 100%
rename from _includes/icons/announcement.svg
rename to legacy/_includes/icons/announcement.svg
diff --git a/_includes/icons/arrow.svg b/legacy/_includes/icons/arrow.svg
similarity index 100%
rename from _includes/icons/arrow.svg
rename to legacy/_includes/icons/arrow.svg
diff --git a/_includes/icons/bluesky.svg b/legacy/_includes/icons/bluesky.svg
similarity index 100%
rename from _includes/icons/bluesky.svg
rename to legacy/_includes/icons/bluesky.svg
diff --git a/_includes/icons/caution.svg b/legacy/_includes/icons/caution.svg
similarity index 100%
rename from _includes/icons/caution.svg
rename to legacy/_includes/icons/caution.svg
diff --git a/_includes/icons/express-logo.svg b/legacy/_includes/icons/express-logo.svg
similarity index 100%
rename from _includes/icons/express-logo.svg
rename to legacy/_includes/icons/express-logo.svg
diff --git a/_includes/icons/github.svg b/legacy/_includes/icons/github.svg
similarity index 100%
rename from _includes/icons/github.svg
rename to legacy/_includes/icons/github.svg
diff --git a/_includes/icons/hamburger.svg b/legacy/_includes/icons/hamburger.svg
similarity index 100%
rename from _includes/icons/hamburger.svg
rename to legacy/_includes/icons/hamburger.svg
diff --git a/_includes/icons/i18n.svg b/legacy/_includes/icons/i18n.svg
similarity index 100%
rename from _includes/icons/i18n.svg
rename to legacy/_includes/icons/i18n.svg
diff --git a/_includes/icons/moon.svg b/legacy/_includes/icons/moon.svg
similarity index 100%
rename from _includes/icons/moon.svg
rename to legacy/_includes/icons/moon.svg
diff --git a/_includes/icons/note.svg b/legacy/_includes/icons/note.svg
similarity index 100%
rename from _includes/icons/note.svg
rename to legacy/_includes/icons/note.svg
diff --git a/_includes/icons/opencollective.svg b/legacy/_includes/icons/opencollective.svg
similarity index 100%
rename from _includes/icons/opencollective.svg
rename to legacy/_includes/icons/opencollective.svg
diff --git a/_includes/icons/openjs_foundation-logo-horizontal-white.svg b/legacy/_includes/icons/openjs_foundation-logo-horizontal-white.svg
similarity index 100%
rename from _includes/icons/openjs_foundation-logo-horizontal-white.svg
rename to legacy/_includes/icons/openjs_foundation-logo-horizontal-white.svg
diff --git a/_includes/icons/slack.svg b/legacy/_includes/icons/slack.svg
similarity index 100%
rename from _includes/icons/slack.svg
rename to legacy/_includes/icons/slack.svg
diff --git a/_includes/icons/sun.svg b/legacy/_includes/icons/sun.svg
similarity index 100%
rename from _includes/icons/sun.svg
rename to legacy/_includes/icons/sun.svg
diff --git a/_includes/icons/warning.svg b/legacy/_includes/icons/warning.svg
similarity index 100%
rename from _includes/icons/warning.svg
rename to legacy/_includes/icons/warning.svg
diff --git a/_includes/icons/youtube.svg b/legacy/_includes/icons/youtube.svg
similarity index 100%
rename from _includes/icons/youtube.svg
rename to legacy/_includes/icons/youtube.svg
diff --git a/_includes/language-picker.html b/legacy/_includes/language-picker.html
similarity index 100%
rename from _includes/language-picker.html
rename to legacy/_includes/language-picker.html
diff --git a/_includes/mw-list.md b/legacy/_includes/mw-list.md
similarity index 100%
rename from _includes/mw-list.md
rename to legacy/_includes/mw-list.md
diff --git a/_includes/readmes/body-parser.md b/legacy/_includes/readmes/body-parser.md
similarity index 100%
rename from _includes/readmes/body-parser.md
rename to legacy/_includes/readmes/body-parser.md
diff --git a/_includes/readmes/compression.md b/legacy/_includes/readmes/compression.md
similarity index 100%
rename from _includes/readmes/compression.md
rename to legacy/_includes/readmes/compression.md
diff --git a/_includes/readmes/connect-rid.md b/legacy/_includes/readmes/connect-rid.md
similarity index 100%
rename from _includes/readmes/connect-rid.md
rename to legacy/_includes/readmes/connect-rid.md
diff --git a/_includes/readmes/cookie-parser.md b/legacy/_includes/readmes/cookie-parser.md
similarity index 100%
rename from _includes/readmes/cookie-parser.md
rename to legacy/_includes/readmes/cookie-parser.md
diff --git a/_includes/readmes/cookie-session.md b/legacy/_includes/readmes/cookie-session.md
similarity index 100%
rename from _includes/readmes/cookie-session.md
rename to legacy/_includes/readmes/cookie-session.md
diff --git a/_includes/readmes/cors.md b/legacy/_includes/readmes/cors.md
similarity index 100%
rename from _includes/readmes/cors.md
rename to legacy/_includes/readmes/cors.md
diff --git a/_includes/readmes/errorhandler.md b/legacy/_includes/readmes/errorhandler.md
similarity index 100%
rename from _includes/readmes/errorhandler.md
rename to legacy/_includes/readmes/errorhandler.md
diff --git a/_includes/readmes/express-master/examples.md b/legacy/_includes/readmes/express-master/examples.md
similarity index 100%
rename from _includes/readmes/express-master/examples.md
rename to legacy/_includes/readmes/express-master/examples.md
diff --git a/_includes/readmes/method-override.md b/legacy/_includes/readmes/method-override.md
similarity index 100%
rename from _includes/readmes/method-override.md
rename to legacy/_includes/readmes/method-override.md
diff --git a/_includes/readmes/morgan.md b/legacy/_includes/readmes/morgan.md
similarity index 100%
rename from _includes/readmes/morgan.md
rename to legacy/_includes/readmes/morgan.md
diff --git a/_includes/readmes/multer.md b/legacy/_includes/readmes/multer.md
similarity index 100%
rename from _includes/readmes/multer.md
rename to legacy/_includes/readmes/multer.md
diff --git a/_includes/readmes/response-time.md b/legacy/_includes/readmes/response-time.md
similarity index 100%
rename from _includes/readmes/response-time.md
rename to legacy/_includes/readmes/response-time.md
diff --git a/_includes/readmes/serve-favicon.md b/legacy/_includes/readmes/serve-favicon.md
similarity index 100%
rename from _includes/readmes/serve-favicon.md
rename to legacy/_includes/readmes/serve-favicon.md
diff --git a/_includes/readmes/serve-index.md b/legacy/_includes/readmes/serve-index.md
similarity index 100%
rename from _includes/readmes/serve-index.md
rename to legacy/_includes/readmes/serve-index.md
diff --git a/_includes/readmes/serve-static.md b/legacy/_includes/readmes/serve-static.md
similarity index 100%
rename from _includes/readmes/serve-static.md
rename to legacy/_includes/readmes/serve-static.md
diff --git a/_includes/readmes/session.md b/legacy/_includes/readmes/session.md
similarity index 100%
rename from _includes/readmes/session.md
rename to legacy/_includes/readmes/session.md
diff --git a/_includes/readmes/timeout.md b/legacy/_includes/readmes/timeout.md
similarity index 100%
rename from _includes/readmes/timeout.md
rename to legacy/_includes/readmes/timeout.md
diff --git a/_includes/readmes/vhost.md b/legacy/_includes/readmes/vhost.md
similarity index 100%
rename from _includes/readmes/vhost.md
rename to legacy/_includes/readmes/vhost.md
diff --git a/_includes/util-list.md b/legacy/_includes/util-list.md
similarity index 100%
rename from _includes/util-list.md
rename to legacy/_includes/util-list.md
diff --git a/_layouts/404.html b/legacy/_layouts/404.html
similarity index 100%
rename from _layouts/404.html
rename to legacy/_layouts/404.html
diff --git a/_layouts/api.html b/legacy/_layouts/api.html
similarity index 100%
rename from _layouts/api.html
rename to legacy/_layouts/api.html
diff --git a/_layouts/feed.xml b/legacy/_layouts/feed.xml
similarity index 100%
rename from _layouts/feed.xml
rename to legacy/_layouts/feed.xml
diff --git a/_layouts/home.html b/legacy/_layouts/home.html
similarity index 100%
rename from _layouts/home.html
rename to legacy/_layouts/home.html
diff --git a/_layouts/middleware.html b/legacy/_layouts/middleware.html
similarity index 100%
rename from _layouts/middleware.html
rename to legacy/_layouts/middleware.html
diff --git a/_layouts/page.html b/legacy/_layouts/page.html
similarity index 100%
rename from _layouts/page.html
rename to legacy/_layouts/page.html
diff --git a/_layouts/post.html b/legacy/_layouts/post.html
similarity index 100%
rename from _layouts/post.html
rename to legacy/_layouts/post.html
diff --git a/_posts/2024-07-16-welcome-post.md b/legacy/_posts/2024-07-16-welcome-post.md
similarity index 100%
rename from _posts/2024-07-16-welcome-post.md
rename to legacy/_posts/2024-07-16-welcome-post.md
diff --git a/_posts/2024-09-29-security-releases.md b/legacy/_posts/2024-09-29-security-releases.md
similarity index 100%
rename from _posts/2024-09-29-security-releases.md
rename to legacy/_posts/2024-09-29-security-releases.md
diff --git a/_posts/2024-10-01-HeroDevs-partnership-announcement.md b/legacy/_posts/2024-10-01-HeroDevs-partnership-announcement.md
similarity index 100%
rename from _posts/2024-10-01-HeroDevs-partnership-announcement.md
rename to legacy/_posts/2024-10-01-HeroDevs-partnership-announcement.md
diff --git a/_posts/2024-10-15-v5-release.md b/legacy/_posts/2024-10-15-v5-release.md
similarity index 100%
rename from _posts/2024-10-15-v5-release.md
rename to legacy/_posts/2024-10-15-v5-release.md
diff --git a/_posts/2024-10-22-security-audit-milestone-achievement.md b/legacy/_posts/2024-10-22-security-audit-milestone-achievement.md
similarity index 100%
rename from _posts/2024-10-22-security-audit-milestone-achievement.md
rename to legacy/_posts/2024-10-22-security-audit-milestone-achievement.md
diff --git a/_posts/2025-01-09-rewind-2024-triumphs-and-2025-vision.md b/legacy/_posts/2025-01-09-rewind-2024-triumphs-and-2025-vision.md
similarity index 100%
rename from _posts/2025-01-09-rewind-2024-triumphs-and-2025-vision.md
rename to legacy/_posts/2025-01-09-rewind-2024-triumphs-and-2025-vision.md
diff --git a/_posts/2025-03-31-v5-1-latest-release.md b/legacy/_posts/2025-03-31-v5-1-latest-release.md
similarity index 100%
rename from _posts/2025-03-31-v5-1-latest-release.md
rename to legacy/_posts/2025-03-31-v5-1-latest-release.md
diff --git a/_posts/2025-05-16-express-cleanup-legacy-packages.md b/legacy/_posts/2025-05-16-express-cleanup-legacy-packages.md
similarity index 100%
rename from _posts/2025-05-16-express-cleanup-legacy-packages.md
rename to legacy/_posts/2025-05-16-express-cleanup-legacy-packages.md
diff --git a/_posts/2025-05-19-security-releases.md b/legacy/_posts/2025-05-19-security-releases.md
similarity index 100%
rename from _posts/2025-05-19-security-releases.md
rename to legacy/_posts/2025-05-19-security-releases.md
diff --git a/_posts/2025-06-05-vulnerability-reporting-process-overhaul.md b/legacy/_posts/2025-06-05-vulnerability-reporting-process-overhaul.md
similarity index 100%
rename from _posts/2025-06-05-vulnerability-reporting-process-overhaul.md
rename to legacy/_posts/2025-06-05-vulnerability-reporting-process-overhaul.md
diff --git a/_posts/2025-07-18-security-releases.md b/legacy/_posts/2025-07-18-security-releases.md
similarity index 100%
rename from _posts/2025-07-18-security-releases.md
rename to legacy/_posts/2025-07-18-security-releases.md
diff --git a/_posts/2025-07-31-security-releases.md b/legacy/_posts/2025-07-31-security-releases.md
similarity index 100%
rename from _posts/2025-07-31-security-releases.md
rename to legacy/_posts/2025-07-31-security-releases.md
diff --git a/_posts/2025-12-01-security-releases.md b/legacy/_posts/2025-12-01-security-releases.md
similarity index 100%
rename from _posts/2025-12-01-security-releases.md
rename to legacy/_posts/2025-12-01-security-releases.md
diff --git a/crowdin.yml b/legacy/crowdin.yml
similarity index 100%
rename from crowdin.yml
rename to legacy/crowdin.yml
diff --git a/css/langs/de.css b/legacy/css/langs/de.css
similarity index 100%
rename from css/langs/de.css
rename to legacy/css/langs/de.css
diff --git a/css/langs/en.css b/legacy/css/langs/en.css
similarity index 100%
rename from css/langs/en.css
rename to legacy/css/langs/en.css
diff --git a/css/langs/es.css b/legacy/css/langs/es.css
similarity index 100%
rename from css/langs/es.css
rename to legacy/css/langs/es.css
diff --git a/css/langs/fr.css b/legacy/css/langs/fr.css
similarity index 100%
rename from css/langs/fr.css
rename to legacy/css/langs/fr.css
diff --git a/css/langs/it.css b/legacy/css/langs/it.css
similarity index 100%
rename from css/langs/it.css
rename to legacy/css/langs/it.css
diff --git a/css/langs/ja.css b/legacy/css/langs/ja.css
similarity index 100%
rename from css/langs/ja.css
rename to legacy/css/langs/ja.css
diff --git a/css/langs/ko.css b/legacy/css/langs/ko.css
similarity index 100%
rename from css/langs/ko.css
rename to legacy/css/langs/ko.css
diff --git a/css/langs/pt-br.css b/legacy/css/langs/pt-br.css
similarity index 100%
rename from css/langs/pt-br.css
rename to legacy/css/langs/pt-br.css
diff --git a/css/langs/zh-cn.css b/legacy/css/langs/zh-cn.css
similarity index 100%
rename from css/langs/zh-cn.css
rename to legacy/css/langs/zh-cn.css
diff --git a/css/langs/zh-tw.css b/legacy/css/langs/zh-tw.css
similarity index 100%
rename from css/langs/zh-tw.css
rename to legacy/css/langs/zh-tw.css
diff --git a/css/search.css b/legacy/css/search.css
similarity index 100%
rename from css/search.css
rename to legacy/css/search.css
diff --git a/css/sintax.css b/legacy/css/sintax.css
similarity index 100%
rename from css/sintax.css
rename to legacy/css/sintax.css
diff --git a/css/style.css b/legacy/css/style.css
similarity index 100%
rename from css/style.css
rename to legacy/css/style.css
diff --git a/css/themes/dark-theme.css b/legacy/css/themes/dark-theme.css
similarity index 100%
rename from css/themes/dark-theme.css
rename to legacy/css/themes/dark-theme.css
diff --git a/css/variables.css b/legacy/css/variables.css
similarity index 100%
rename from css/variables.css
rename to legacy/css/variables.css
diff --git a/de/3x/api.md b/legacy/de/3x/api.md
similarity index 100%
rename from de/3x/api.md
rename to legacy/de/3x/api.md
diff --git a/de/4x/api.md b/legacy/de/4x/api.md
similarity index 100%
rename from de/4x/api.md
rename to legacy/de/4x/api.md
diff --git a/de/5x/api.md b/legacy/de/5x/api.md
similarity index 100%
rename from de/5x/api.md
rename to legacy/de/5x/api.md
diff --git a/de/advanced/best-practice-performance.md b/legacy/de/advanced/best-practice-performance.md
similarity index 100%
rename from de/advanced/best-practice-performance.md
rename to legacy/de/advanced/best-practice-performance.md
diff --git a/de/advanced/best-practice-security.md b/legacy/de/advanced/best-practice-security.md
similarity index 100%
rename from de/advanced/best-practice-security.md
rename to legacy/de/advanced/best-practice-security.md
diff --git a/de/advanced/developing-template-engines.md b/legacy/de/advanced/developing-template-engines.md
similarity index 100%
rename from de/advanced/developing-template-engines.md
rename to legacy/de/advanced/developing-template-engines.md
diff --git a/de/advanced/healthcheck-graceful-shutdown.md b/legacy/de/advanced/healthcheck-graceful-shutdown.md
similarity index 100%
rename from de/advanced/healthcheck-graceful-shutdown.md
rename to legacy/de/advanced/healthcheck-graceful-shutdown.md
diff --git a/de/advanced/security-updates.md b/legacy/de/advanced/security-updates.md
similarity index 100%
rename from de/advanced/security-updates.md
rename to legacy/de/advanced/security-updates.md
diff --git a/de/api.md b/legacy/de/api.md
similarity index 100%
rename from de/api.md
rename to legacy/de/api.md
diff --git a/de/changelog/index.md b/legacy/de/changelog/index.md
similarity index 100%
rename from de/changelog/index.md
rename to legacy/de/changelog/index.md
diff --git a/de/guide/behind-proxies.md b/legacy/de/guide/behind-proxies.md
similarity index 100%
rename from de/guide/behind-proxies.md
rename to legacy/de/guide/behind-proxies.md
diff --git a/de/guide/database-integration.md b/legacy/de/guide/database-integration.md
similarity index 100%
rename from de/guide/database-integration.md
rename to legacy/de/guide/database-integration.md
diff --git a/de/guide/debugging.md b/legacy/de/guide/debugging.md
similarity index 100%
rename from de/guide/debugging.md
rename to legacy/de/guide/debugging.md
diff --git a/de/guide/error-handling.md b/legacy/de/guide/error-handling.md
similarity index 100%
rename from de/guide/error-handling.md
rename to legacy/de/guide/error-handling.md
diff --git a/de/guide/migrating-4.md b/legacy/de/guide/migrating-4.md
similarity index 100%
rename from de/guide/migrating-4.md
rename to legacy/de/guide/migrating-4.md
diff --git a/legacy/de/guide/migrating-5.md b/legacy/de/guide/migrating-5.md
new file mode 100644
index 0000000000..8dcd0cd461
--- /dev/null
+++ b/legacy/de/guide/migrating-5.md
@@ -0,0 +1,594 @@
+---
+layout: page
+title: Migration auf Express 5
+description: A comprehensive guide to migrating your Express.js applications from version 4 to 5, detailing breaking changes, deprecated methods, and new improvements.
+menu: guide
+order: 10
+redirect_from: " "
+---
+
+# Wechsel zu Express 5
+
+Überblick
+
+Express 5.0 befindet sich noch in der Beta-Release-Phase. Hier finden Sie jedoch bereits eine Vorschau zu den Änderungen in diesem Release und zur Migration Ihrer Express 4-Anwendung auf Express 5.
+
+To install this version, you need to have a Node.js version 18 or higher. Then, execute the following command in your application directory:
+
+```sh
+npm install "express@5"
+```
+
+Sie können Ihre automatisierten Tests ausführen, um zu sehen, was fehlschlägt, und Probleme gemäß den folgenden Updates beheben. Nachdem Sie alle Testfehler behoben haben, führen Sie Ihre Anwendung aus, um zu sehen, welche Fehler noch auftreten. Sie werden sofort feststellen, ob die Anwendung Methoden oder Eigenschaften verwendet, die nicht unterstützt werden.
+
+## Express 5 Codemods
+
+To help you migrate your express server, we have created a set of codemods that will help you automatically update your code to the latest version of Express.
+
+Run the following command for run all the codemods available:
+
+```sh
+npx @expressjs/codemod upgrade
+```
+
+If you want to run a specific codemod, you can run the following command:
+
+```sh
+npx @expressjs/codemod name-of-the-codemod
+```
+
+You can find the list of available codemods [here](https://github.com/expressjs/codemod?tab=readme-ov-file#available-codemods).
+
+Änderungen in Express 5
+
+**Entfernte Methoden und Eigenschaften**
+
+
+
+**Verbesserungen**
+
+
+
+**Geändert**
+
+
+
+## Entfernte Methoden und Eigenschaften
+
+Wenn Sie eine dieser Methoden oder Eigenschaften in Ihrer Anwendung verwenden, stürzt die Anwendung ab. Sie müssen also Ihre Anwendung ändern, wenn Sie auf Version 5 umgestellt haben.
+
+app.del()
+
+Express 5 unterstützt die Funktion `app.del()` nicht mehr. Wenn Sie diese Funktion verwenden, wird ein Fehler ausgelöst. Für die Registrierung von HTTP DELETE-Weiterleitungen verwenden Sie stattdessen die Funktion `app.delete()`.
+
+Anfänglich wurde `del` statt `delete` verwendet, weil `delete` in JavaScript ein reserviertes Schlüsselwort ist. Ab ECMAScript 6 jedoch können `delete` und andere reservierte Schlüsselwörter legal als Eigenschaftsnamen verwendet werden.
+
+{% capture codemod-deprecated-signatures %}
+You can replace the deprecated signatures with the following command:
+
+```plaintext
+npx @expressjs/codemod v4-deprecated-signatures
+```
+
+{% endcapture %}
+
+{% include admonitions/note.html content=codemod-deprecated-signatures %}
+
+```js
+// v4
+app.del("/user/:id", (req, res) => {
+ res.send(`DELETE /user/${req.params.id}`);
+});
+
+// v5
+app.delete("/user/:id", (req, res) => {
+ res.send(`DELETE /user/${req.params.id}`);
+});
+```
+
+app.param(fn)
+
+Die Signatur `app.param(fn)` wurde für die Änderung der Verhaltensweise der Funktion `app.param(name, fn)` verwendet. Seit v4.11.0 wurde sie nicht mehr verwendet. In Express 5 wird sie überhaupt nicht mehr unterstützt.
+
+Pluralisierte Methodennamen
+
+Die folgenden Methodennamen wurden pluralisiert. In Express 4 wurde bei Verwendung der alten Methoden eine Warnung zur Einstellung der Unterstützung ausgegeben. Express 5 unterstützt diese Methoden nicht mehr.
+
+`req.acceptsLanguage()` wird durch `req.acceptsLanguages()` ersetzt.
+
+`req.acceptsCharset()` wird durch `req.acceptsCharsets()` ersetzt.
+
+`req.acceptsEncoding()` wird durch `req.acceptsEncodings()` ersetzt.
+
+{% capture codemod-pluralized-methods %}
+You can replace the deprecated signatures with the following command:
+
+```plaintext
+npx @expressjs/codemod pluralized-methods
+```
+
+{% endcapture %}
+
+{% include admonitions/note.html content=codemod-pluralized-methods %}
+
+```js
+// v4
+app.all("/", (req, res) => {
+ req.acceptsCharset("utf-8");
+ req.acceptsEncoding("br");
+ req.acceptsLanguage("en");
+
+ // ...
+});
+
+// v5
+app.all("/", (req, res) => {
+ req.acceptsCharsets("utf-8");
+ req.acceptsEncodings("br");
+ req.acceptsLanguages("en");
+
+ // ...
+});
+```
+
+Führender Doppelpunkt (:) im Namen für app.param(name, fn)
+
+Ein führendes Doppelpunktzeichen (:) im Namen für die Funktion `app.param(name, fn)` ist ein Überbleibsel aus Express 3. Aus Gründen der Abwärtskompatibilität wurde dieser Name in Express 4 mit einem Hinweis zu veralteten Versionen weiter unterstützt. In Express 5 wird dieser Name stillschwiegend ignoriert und der Namensparameter ohne einen vorangestellten Doppelpunkt verwendet.
+
+Dies dürfte keine Auswirkungen auf Ihren Code haben, wenn Sie die Express 4-Dokumentation zu [app.param](/{{ page.lang }}/4x/api.html#app.param) befolgen, da dort der führende Doppelpunkt nicht erwähnt wird.
+
+req.param(name)
+
+Dieses potenziell verwirrende und durchaus riskante Verfahren des Abrufens von Formulardaten wurde entfernt. Sie müssen nun ganz speziell nach dem übergebenen Parameternamen im Objekt `req.params`, `req.body` oder `req.query` suchen.
+
+{% capture codemod-req-param %}
+You can replace the deprecated signatures with the following command:
+
+```plaintext
+npx @expressjs/codemod req-param
+```
+
+{% endcapture %}
+
+{% include admonitions/note.html content=codemod-req-param %}
+
+```js
+// v4
+app.post("/user", (req, res) => {
+ const id = req.param("id");
+ const body = req.param("body");
+ const query = req.param("query");
+
+ // ...
+});
+
+// v5
+app.post("/user", (req, res) => {
+ const id = req.params.id;
+ const body = req.body;
+ const query = req.query;
+
+ // ...
+});
+```
+
+res.json(obj, status)
+
+Express 5 unterstützt die Signatur `res.json(obj, status)` nicht mehr. Stattdessen müssen Sie den Status festlegen und diesen dann mit `res.json()`-Methoden wie dieser verketten: `res.status(status).json(obj)`.
+
+{% include admonitions/note.html content=codemod-deprecated-signatures %}
+
+```js
+// v4
+app.post("/user", (req, res) => {
+ res.json({ name: "Ruben" }, 201);
+});
+
+// v5
+app.post("/user", (req, res) => {
+ res.status(201).json({ name: "Ruben" });
+});
+```
+
+res.jsonp(obj, status)
+
+Express 5 unterstützt die Signatur `res.jsonp(obj, status)` nicht mehr. Stattdessen müssen Sie den Status festlegen und diesen dann mit `res.jsonp()`-Methoden wie dieser verketten: `res.status(status).jsonp(obj)`.
+
+{% include admonitions/note.html content=codemod-deprecated-signatures %}
+
+```js
+// v4
+app.post("/user", (req, res) => {
+ res.jsonp({ name: "Ruben" }, 201);
+});
+
+// v5
+app.post("/user", (req, res) => {
+ res.status(201).jsonp({ name: "Ruben" });
+});
+```
+
+res.redirect(url, status)
+
+Express 5 unterstützt die Signatur `res.send(obj, status)` nicht mehr. Stattdessen müssen Sie den Status festlegen und diesen dann mit `res.send()`-Methoden wie dieser verketten: `res.status(status).send(obj)`.
+
+{% include admonitions/note.html content=codemod-deprecated-signatures %}
+
+```js
+// v4
+app.get("/user", (req, res) => {
+ res.redirect("/users", 301);
+});
+
+// v5
+app.get("/user", (req, res) => {
+ res.redirect(301, "/users");
+});
+```
+
+res.redirect('back') and res.location('back')
+
+Express 5 no longer supports the magic string `back` in the `res.redirect()` and `res.location()` methods. Instead, use the `req.get('Referrer') || '/'` value to redirect back to the previous page. In Express 4, the `res.redirect('back')` and `res.location('back')` methods were deprecated.
+
+{% capture codemod-magic-redirect %}
+You can replace the deprecated signatures with the following command:
+
+```plaintext
+npx @expressjs/codemod magic-redirect
+```
+
+{% endcapture %}
+
+{% include admonitions/note.html content=codemod-magic-redirect %}
+
+```js
+// v4
+app.get("/user", (req, res) => {
+ res.redirect("back");
+});
+
+// v5
+app.get("/user", (req, res) => {
+ res.redirect(req.get("Referrer") || "/");
+});
+```
+
+res.send(body, status)
+
+Express 5 no longer supports the signature `res.send(obj, status)`. Instead, set the status and then chain it to the `res.send()` method like this: `res.status(status).send(obj)`.
+
+{% include admonitions/note.html content=codemod-deprecated-signatures %}
+
+```js
+// v4
+app.get("/user", (req, res) => {
+ res.send({ name: "Ruben" }, 200);
+});
+
+// v5
+app.get("/user", (req, res) => {
+ res.status(200).send({ name: "Ruben" });
+});
+```
+
+res.send(status)
+
+Express 5 unterstützt die Signatur res.send(status ), nicht mehr, wobei _`status`_ für eine Zahl steht. Verwenden Sie stattdessen die Funktion `res.sendStatus(statusCode)`, mit der der Statuscode für den HTTP-Antwort-Header festgelegt und die Textversion des Codes gesendet wird: "Not Found" (Nicht gefunden), "Internal Server Error" (Interner Serverfehler) usw.
+Wenn Sie eine Zahl senden und hierfür die Funktion `res.send()` verwenden müssen, müssen Sie die Zahl in Anführungszeichen setzen, um diese in eine Zeichenfolge zu konvertieren. Dadurch interpretiert Express diese Zahl nicht als Versuch, die nicht mehr unterstützte alte Signatur zu verwenden.
+
+{% include admonitions/note.html content=codemod-deprecated-signatures %}
+
+```js
+// v4
+app.get("/user", (req, res) => {
+ res.send(200);
+});
+
+// v5
+app.get("/user", (req, res) => {
+ res.sendStatus(200);
+});
+```
+
+res.sendfile()
+
+Die Funktion `res.sendfile()` wurde durch eine Version in Camel-Schreibweise von `res.sendFile()` in Express 5 ersetzt.
+
+**Note:** In Express 5, `res.sendFile()` uses the `mime-types` package for MIME type detection, which returns different Content-Type values than Express 4 for several common file types:
+
+- JavaScript files (.js): now "text/javascript" instead of "application/javascript"
+- JSON files (.json): now "application/json" instead of "text/json"
+- CSS files (.css): now "text/css" instead of "text/plain"
+- XML files (.xml): now "application/xml" instead of "text/xml"
+- Font files (.woff): now "font/woff" instead of "application/font-woff"
+- SVG files (.svg): now "image/svg+xml" instead of "application/svg+xml"
+
+{% include admonitions/note.html content=codemod-deprecated-signatures %}
+
+```js
+// v4
+app.get("/user", (req, res) => {
+ res.sendfile("/path/to/file");
+});
+
+// v5
+app.get("/user", (req, res) => {
+ res.sendFile("/path/to/file");
+});
+```
+
+router.param(fn)
+
+The `router.param(fn)` signature was used for modifying the behavior of the `router.param(name, fn)` function. Seit v4.11.0 wurde sie nicht mehr verwendet. In Express 5 wird sie überhaupt nicht mehr unterstützt.
+
+express.static.mime
+
+In Express 5, `mime` is no longer an exported property of the `static` field.
+Use the [`mime-types` package](https://github.com/jshttp/mime-types) to work with MIME type values.
+
+**Important:** This change affects not only direct usage of `express.static.mime` but also other Express methods that rely on MIME type detection, such as `res.sendFile()`. The following MIME types have changed from Express 4:
+
+- JavaScript files (.js): now served as "text/javascript" instead of "application/javascript"
+- JSON files (.json): now served as "application/json" instead of "text/json"
+- CSS files (.css): now served as "text/css" instead of "text/plain"
+- HTML files (.html): now served as "text/html; charset=utf-8" instead of just "text/html"
+- XML files (.xml): now served as "application/xml" instead of "text/xml"
+- Font files (.woff): now served as "font/woff" instead of "application/font-woff"
+
+```js
+// v4
+express.static.mime.lookup("json");
+
+// v5
+const mime = require("mime-types");
+mime.lookup("json");
+```
+
+express:router debug logs
+
+In Express 5, router handling logic is performed by a dependency. Therefore, the
+debug logs for the router are no longer available under the `express:` namespace.
+In v4, the logs were available under the namespaces `express:router`, `express:router:layer`,
+and `express:router:route`. All of these were included under the namespace `express:*`.
+In v5.1+, the logs are available under the namespaces `router`, `router:layer`, and `router:route`.
+The logs from `router:layer` and `router:route` are included in the namespace `router:*`.
+To achieve the same detail of debug logging when using `express:*` in v4, use a conjunction of
+`express:*`, `router`, and `router:*`.
+
+```sh
+# v4
+DEBUG=express:* node index.js
+
+# v5
+DEBUG=express:*,router,router:* node index.js
+```
+
+## Geändert
+
+Path route matching syntax
+
+Path route matching syntax is when a string is supplied as the first parameter to the `app.all()`, `app.use()`, `app.METHOD()`, `router.all()`, `router.METHOD()`, and `router.use()` APIs. The following changes have been made to how the path string is matched to an incoming request:
+
+- The wildcard `*` must have a name, matching the behavior of parameters `:`, use `/*splat` instead of `/*`
+
+```js
+// v4
+app.get("/*", async (req, res) => {
+ res.send("ok");
+});
+
+// v5
+app.get("/*splat", async (req, res) => {
+ res.send("ok");
+});
+```
+
+{% capture note_wildcard %}
+`*splat` matches any path without the root path. If you need to match the root path as well `/`, you can use `/{*splat}`, wrapping the wildcard in braces.
+
+```js
+// v5
+app.get("/{*splat}", async (req, res) => {
+ res.send("ok");
+});
+```
+
+{% endcapture %}
+{% include admonitions/note.html content=note_wildcard %}
+
+- The optional character `?` is no longer supported, use braces instead.
+
+```js
+// v4
+app.get("/:file.:ext?", async (req, res) => {
+ res.send("ok");
+});
+
+// v5
+app.get("/:file{.:ext}", async (req, res) => {
+ res.send("ok");
+});
+```
+
+- Regexp characters are not supported. Beispiel:
+
+```js
+app.get("/[discussion|page]/:slug", async (req, res) => {
+ res.status(200).send("ok");
+});
+```
+
+should be changed to:
+
+```js
+app.get(["/discussion/:slug", "/page/:slug"], async (req, res) => {
+ res.status(200).send("ok");
+});
+```
+
+- Some characters have been reserved to avoid confusion during upgrade (`()[]?+!`), use `\` to escape them.
+- Parameter names now support valid JavaScript identifiers, or quoted like `:"this"`.
+
+Rejected promises handled from middleware and handlers
+
+Request middleware and handlers that return rejected promises are now handled by forwarding the rejected value as an `Error` to the error handling middleware. This means that using `async` functions as middleware and handlers are easier than ever. When an error is thrown in an `async` function or a rejected promise is `await`ed inside an async function, those errors will be passed to the error handler as if calling `next(err)`.
+
+Details of how Express handles errors is covered in the [error handling documentation](/en/guide/error-handling.html).
+
+express.urlencoded
+
+The `express.urlencoded` method makes the `extended` option `false` by default.
+
+express.static dotfiles
+
+In Express 5, the `express.static` middleware's `dotfiles` option now defaults to `"ignore"`. This is a change from Express 4, where dotfiles were served by default. As a result, files inside a directory that starts with a dot (`.`), such as `.well-known`, will no longer be accessible and will return a **404 Not Found** error. This can break functionality that depends on serving dot-directories, such as Android App Links, and Apple Universal Links.
+
+Example of breaking code:
+
+```js
+// v4
+app.use(express.static("public"));
+```
+
+After migrating to Express 5, a request to `/.well-known/assetlinks.json` will result in a **404 Not Found**.
+
+To fix this, serve specific dot-directories explicitly using the `dotfiles: "allow"` option:
+
+```js
+// v5
+app.use(
+ "/.well-known",
+ express.static("public/.well-known", { dotfiles: "allow" }),
+);
+app.use(express.static("public"));
+```
+
+This approach allows you to safely serve only the intended dot-directories while keeping the default secure behavior for other dotfiles, which remain inaccessible.
+
+app.listen
+
+In Express 5, the `app.listen` method will invoke the user-provided callback function (if provided) when the server receives an error event. In Express 4, such errors would be thrown. This change shifts error-handling responsibility to the callback function in Express 5. If there is an error, it will be passed to the callback as an argument.
+Beispiel:
+
+```js
+const server = app.listen(8080, "0.0.0.0", (error) => {
+ if (error) {
+ throw error; // e.g. EADDRINUSE
+ }
+ console.log(`Listening on ${JSON.stringify(server.address())}`);
+});
+```
+
+app.router
+
+Das Objekt `app.router`, das in Express 4 entfernt wurde, ist in Express 5 wieder verfügbar. In der neuen Version fungiert dieses Objekt nur als Referenz zum Express-Basisrouter – im Gegensatz zu Express 3, wo die Anwendung dieses Objekt explizit laden musste.
+
+req.body
+
+The `req.body` property returns `undefined` when the body has not been parsed. In Express 4, it returns `{}` by default.
+
+req.host
+
+In Express 4 übergab die Funktion `req.host` nicht ordnungsgemäß eine eventuell vorhandene Portnummer. In Express 5 wird die Portnummer beibehalten.
+
+req.params
+
+The `req.params` object now has a **null prototype** when using string paths. However, if the path is defined with a regular expression, `req.params` remains a standard object with a normal prototype. Additionally, there are two important behavioral changes:
+
+**Wildcard parameters are now arrays:**
+
+Wildcards (e.g., `/*splat`) capture path segments as an array instead of a single string.
+
+```js
+app.get("/*splat", (req, res) => {
+ // GET /foo/bar
+ console.dir(req.params);
+ // => [Object: null prototype] { splat: [ 'foo', 'bar' ] }
+});
+```
+
+**Unmatched parameters are omitted:**
+
+In Express 4, unmatched wildcards were empty strings (`''`) and optional `:` parameters (using `?`) had a key with value `undefined`. In Express 5, unmatched parameters are completely omitted from `req.params`.
+
+```js
+// v4: unmatched wildcard is empty string
+app.get("/*", (req, res) => {
+ // GET /
+ console.dir(req.params);
+ // => { '0': '' }
+});
+
+// v4: unmatched optional param is undefined
+app.get("/:file.:ext?", (req, res) => {
+ // GET /image
+ console.dir(req.params);
+ // => { file: 'image', ext: undefined }
+});
+
+// v5: unmatched optional param is omitted
+app.get("/:file{.:ext}", (req, res) => {
+ // GET /image
+ console.dir(req.params);
+ // => [Object: null prototype] { file: 'image' }
+});
+```
+
+req.query
+
+The `req.query` property is no longer a writable property and is instead a getter. The default query parser has been changed from "extended" to "simple".
+
+res.clearCookie
+
+The `res.clearCookie` method ignores the `maxAge` and `expires` options provided by the user.
+
+res.status
+
+The `res.status` method only accepts integers in the range of `100` to `999`, following the behavior defined by Node.js, and it returns an error when the status code is not an integer.
+
+res.vary
+
+The `res.vary` throws an error when the `field` argument is missing. In Express 4, if the argument was omitted, it gave a warning in the console
+
+## Verbesserungen
+
+res.render()
+
+Diese Methode erzwingt nun asynchrones Verhalten für alle View-Engines, sodass durch View-Engines mit synchroner Implementierung verursachte Fehler vermieden werden, durch die die empfohlene Schnittstelle nicht verwendet werden konnte.
+
+Brotli encoding support
+
+Express 5 supports Brotli encoding for requests received from clients that support it.
diff --git a/de/guide/overriding-express-api.md b/legacy/de/guide/overriding-express-api.md
similarity index 100%
rename from de/guide/overriding-express-api.md
rename to legacy/de/guide/overriding-express-api.md
diff --git a/de/guide/routing.md b/legacy/de/guide/routing.md
similarity index 100%
rename from de/guide/routing.md
rename to legacy/de/guide/routing.md
diff --git a/de/guide/using-middleware.md b/legacy/de/guide/using-middleware.md
similarity index 100%
rename from de/guide/using-middleware.md
rename to legacy/de/guide/using-middleware.md
diff --git a/de/guide/using-template-engines.md b/legacy/de/guide/using-template-engines.md
similarity index 100%
rename from de/guide/using-template-engines.md
rename to legacy/de/guide/using-template-engines.md
diff --git a/de/guide/writing-middleware.md b/legacy/de/guide/writing-middleware.md
similarity index 100%
rename from de/guide/writing-middleware.md
rename to legacy/de/guide/writing-middleware.md
diff --git a/de/index.md b/legacy/de/index.md
similarity index 100%
rename from de/index.md
rename to legacy/de/index.md
diff --git a/de/resources/community.md b/legacy/de/resources/community.md
similarity index 100%
rename from de/resources/community.md
rename to legacy/de/resources/community.md
diff --git a/de/resources/contributing.md b/legacy/de/resources/contributing.md
similarity index 100%
rename from de/resources/contributing.md
rename to legacy/de/resources/contributing.md
diff --git a/de/resources/glossary.md b/legacy/de/resources/glossary.md
similarity index 100%
rename from de/resources/glossary.md
rename to legacy/de/resources/glossary.md
diff --git a/de/resources/middleware.md b/legacy/de/resources/middleware.md
similarity index 100%
rename from de/resources/middleware.md
rename to legacy/de/resources/middleware.md
diff --git a/de/resources/middleware/body-parser.md b/legacy/de/resources/middleware/body-parser.md
similarity index 100%
rename from de/resources/middleware/body-parser.md
rename to legacy/de/resources/middleware/body-parser.md
diff --git a/de/resources/middleware/compression.md b/legacy/de/resources/middleware/compression.md
similarity index 100%
rename from de/resources/middleware/compression.md
rename to legacy/de/resources/middleware/compression.md
diff --git a/de/resources/middleware/connect-rid.md b/legacy/de/resources/middleware/connect-rid.md
similarity index 100%
rename from de/resources/middleware/connect-rid.md
rename to legacy/de/resources/middleware/connect-rid.md
diff --git a/de/resources/middleware/cookie-parser.md b/legacy/de/resources/middleware/cookie-parser.md
similarity index 100%
rename from de/resources/middleware/cookie-parser.md
rename to legacy/de/resources/middleware/cookie-parser.md
diff --git a/de/resources/middleware/cookie-session.md b/legacy/de/resources/middleware/cookie-session.md
similarity index 100%
rename from de/resources/middleware/cookie-session.md
rename to legacy/de/resources/middleware/cookie-session.md
diff --git a/de/resources/middleware/cors.md b/legacy/de/resources/middleware/cors.md
similarity index 100%
rename from de/resources/middleware/cors.md
rename to legacy/de/resources/middleware/cors.md
diff --git a/de/resources/middleware/errorhandler.md b/legacy/de/resources/middleware/errorhandler.md
similarity index 100%
rename from de/resources/middleware/errorhandler.md
rename to legacy/de/resources/middleware/errorhandler.md
diff --git a/de/resources/middleware/method-override.md b/legacy/de/resources/middleware/method-override.md
similarity index 100%
rename from de/resources/middleware/method-override.md
rename to legacy/de/resources/middleware/method-override.md
diff --git a/de/resources/middleware/morgan.md b/legacy/de/resources/middleware/morgan.md
similarity index 100%
rename from de/resources/middleware/morgan.md
rename to legacy/de/resources/middleware/morgan.md
diff --git a/de/resources/middleware/multer.md b/legacy/de/resources/middleware/multer.md
similarity index 100%
rename from de/resources/middleware/multer.md
rename to legacy/de/resources/middleware/multer.md
diff --git a/de/resources/middleware/response-time.md b/legacy/de/resources/middleware/response-time.md
similarity index 100%
rename from de/resources/middleware/response-time.md
rename to legacy/de/resources/middleware/response-time.md
diff --git a/de/resources/middleware/serve-favicon.md b/legacy/de/resources/middleware/serve-favicon.md
similarity index 100%
rename from de/resources/middleware/serve-favicon.md
rename to legacy/de/resources/middleware/serve-favicon.md
diff --git a/de/resources/middleware/serve-index.md b/legacy/de/resources/middleware/serve-index.md
similarity index 100%
rename from de/resources/middleware/serve-index.md
rename to legacy/de/resources/middleware/serve-index.md
diff --git a/de/resources/middleware/serve-static.md b/legacy/de/resources/middleware/serve-static.md
similarity index 100%
rename from de/resources/middleware/serve-static.md
rename to legacy/de/resources/middleware/serve-static.md
diff --git a/de/resources/middleware/session.md b/legacy/de/resources/middleware/session.md
similarity index 100%
rename from de/resources/middleware/session.md
rename to legacy/de/resources/middleware/session.md
diff --git a/de/resources/middleware/timeout.md b/legacy/de/resources/middleware/timeout.md
similarity index 100%
rename from de/resources/middleware/timeout.md
rename to legacy/de/resources/middleware/timeout.md
diff --git a/de/resources/middleware/vhost.md b/legacy/de/resources/middleware/vhost.md
similarity index 100%
rename from de/resources/middleware/vhost.md
rename to legacy/de/resources/middleware/vhost.md
diff --git a/de/resources/utils.md b/legacy/de/resources/utils.md
similarity index 100%
rename from de/resources/utils.md
rename to legacy/de/resources/utils.md
diff --git a/de/starter/basic-routing.md b/legacy/de/starter/basic-routing.md
similarity index 100%
rename from de/starter/basic-routing.md
rename to legacy/de/starter/basic-routing.md
diff --git a/de/starter/examples.md b/legacy/de/starter/examples.md
similarity index 100%
rename from de/starter/examples.md
rename to legacy/de/starter/examples.md
diff --git a/de/starter/faq.md b/legacy/de/starter/faq.md
similarity index 100%
rename from de/starter/faq.md
rename to legacy/de/starter/faq.md
diff --git a/de/starter/generator.md b/legacy/de/starter/generator.md
similarity index 100%
rename from de/starter/generator.md
rename to legacy/de/starter/generator.md
diff --git a/de/starter/hello-world.md b/legacy/de/starter/hello-world.md
similarity index 100%
rename from de/starter/hello-world.md
rename to legacy/de/starter/hello-world.md
diff --git a/de/starter/installing.md b/legacy/de/starter/installing.md
similarity index 100%
rename from de/starter/installing.md
rename to legacy/de/starter/installing.md
diff --git a/de/starter/static-files.md b/legacy/de/starter/static-files.md
similarity index 100%
rename from de/starter/static-files.md
rename to legacy/de/starter/static-files.md
diff --git a/de/support/index.md b/legacy/de/support/index.md
similarity index 100%
rename from de/support/index.md
rename to legacy/de/support/index.md
diff --git a/en/3x/api.md b/legacy/en/3x/api.md
similarity index 100%
rename from en/3x/api.md
rename to legacy/en/3x/api.md
diff --git a/en/4x/api.md b/legacy/en/4x/api.md
similarity index 100%
rename from en/4x/api.md
rename to legacy/en/4x/api.md
diff --git a/en/5x/api.md b/legacy/en/5x/api.md
similarity index 100%
rename from en/5x/api.md
rename to legacy/en/5x/api.md
diff --git a/en/advanced/best-practice-performance.md b/legacy/en/advanced/best-practice-performance.md
similarity index 100%
rename from en/advanced/best-practice-performance.md
rename to legacy/en/advanced/best-practice-performance.md
diff --git a/en/advanced/best-practice-security.md b/legacy/en/advanced/best-practice-security.md
similarity index 100%
rename from en/advanced/best-practice-security.md
rename to legacy/en/advanced/best-practice-security.md
diff --git a/en/advanced/developing-template-engines.md b/legacy/en/advanced/developing-template-engines.md
similarity index 100%
rename from en/advanced/developing-template-engines.md
rename to legacy/en/advanced/developing-template-engines.md
diff --git a/en/advanced/healthcheck-graceful-shutdown.md b/legacy/en/advanced/healthcheck-graceful-shutdown.md
similarity index 100%
rename from en/advanced/healthcheck-graceful-shutdown.md
rename to legacy/en/advanced/healthcheck-graceful-shutdown.md
diff --git a/en/advanced/security-updates.md b/legacy/en/advanced/security-updates.md
similarity index 100%
rename from en/advanced/security-updates.md
rename to legacy/en/advanced/security-updates.md
diff --git a/en/api.md b/legacy/en/api.md
similarity index 100%
rename from en/api.md
rename to legacy/en/api.md
diff --git a/en/blog/posts.md b/legacy/en/blog/posts.md
similarity index 100%
rename from en/blog/posts.md
rename to legacy/en/blog/posts.md
diff --git a/en/blog/write-post.md b/legacy/en/blog/write-post.md
similarity index 100%
rename from en/blog/write-post.md
rename to legacy/en/blog/write-post.md
diff --git a/en/changelog/index.md b/legacy/en/changelog/index.md
similarity index 100%
rename from en/changelog/index.md
rename to legacy/en/changelog/index.md
diff --git a/en/guide/behind-proxies.md b/legacy/en/guide/behind-proxies.md
similarity index 100%
rename from en/guide/behind-proxies.md
rename to legacy/en/guide/behind-proxies.md
diff --git a/en/guide/database-integration.md b/legacy/en/guide/database-integration.md
similarity index 100%
rename from en/guide/database-integration.md
rename to legacy/en/guide/database-integration.md
diff --git a/en/guide/debugging.md b/legacy/en/guide/debugging.md
similarity index 100%
rename from en/guide/debugging.md
rename to legacy/en/guide/debugging.md
diff --git a/en/guide/error-handling.md b/legacy/en/guide/error-handling.md
similarity index 100%
rename from en/guide/error-handling.md
rename to legacy/en/guide/error-handling.md
diff --git a/en/guide/migrating-4.md b/legacy/en/guide/migrating-4.md
similarity index 100%
rename from en/guide/migrating-4.md
rename to legacy/en/guide/migrating-4.md
diff --git a/legacy/en/guide/migrating-5.md b/legacy/en/guide/migrating-5.md
new file mode 100755
index 0000000000..d12c829af8
--- /dev/null
+++ b/legacy/en/guide/migrating-5.md
@@ -0,0 +1,621 @@
+---
+layout: page
+title: Migrating to Express 5
+description: A comprehensive guide to migrating your Express.js applications from version 4 to 5, detailing breaking changes, deprecated methods, and new improvements.
+menu: guide
+order: 10
+redirect_from: "/guide/migrating-5.html"
+---
+
+# Moving to Express 5
+
+Overview
+
+Express 5 is not very different from Express 4; although it maintains the same basic API, there are still changes that break compatibility with the previous version. Therefore, an application built with Express 4 might not work if you update it to use Express 5.
+
+To install this version, you need to have a Node.js version 18 or higher. Then, execute the following command in your application directory:
+
+```sh
+npm install "express@5"
+```
+
+You can then run your automated tests to see what fails, and fix problems according to the updates listed below. After addressing test failures, run your app to see what errors occur. You'll find out right away if the app uses any methods or properties that are not supported.
+
+## Express 5 Codemods
+
+To help you migrate your express server, we have created a set of codemods that will help you automatically update your code to the latest version of Express.
+
+Run the following command for run all the codemods available:
+
+```sh
+npx codemod@latest @expressjs/v5-migration-recipe
+```
+
+If you want to run a specific codemod, you can run the following command:
+
+```sh
+npx codemod@latest @expressjs/name-of-the-codemod
+```
+
+You can find the list of available codemods [here](https://codemod.link/express).
+
+Changes in Express 5
+
+**Removed methods and properties**
+
+
+
+**Changed**
+
+
+
+**Improvements**
+
+
+
+## Removed methods and properties
+
+If you use any of these methods or properties in your app, it will crash. So, you'll need to change your app after you update to version 5.
+
+app.del()
+
+Express 5 no longer supports the `app.del()` function. If you use this function, an error is thrown. For registering HTTP DELETE routes, use the `app.delete()` function instead.
+
+Initially, `del` was used instead of `delete`, because `delete` is a reserved keyword in JavaScript. However, as of ECMAScript 6, `delete` and other reserved keywords can legally be used as property names.
+
+{% capture codemod-route-del-to-delete %}
+You can replace the deprecated signatures with the following command:
+
+```plaintext
+npx codemod@latest @expressjs/route-del-to-delete
+```
+
+{% endcapture %}
+
+{% include admonitions/note.html content=codemod-route-del-to-delete %}
+
+```js
+// v4
+app.del("/user/:id", (req, res) => {
+ res.send(`DELETE /user/${req.params.id}`);
+});
+
+// v5
+app.delete("/user/:id", (req, res) => {
+ res.send(`DELETE /user/${req.params.id}`);
+});
+```
+
+app.param(fn)
+
+The `app.param(fn)` signature was used for modifying the behavior of the `app.param(name, fn)` function. It has been deprecated since v4.11.0, and Express 5 no longer supports it at all.
+
+Pluralized method names
+
+The following method names have been pluralized. In Express 4, using the old methods resulted in a deprecation warning. Express 5 no longer supports them at all:
+
+`req.acceptsCharset()` is replaced by `req.acceptsCharsets()`.
+
+`req.acceptsEncoding()` is replaced by `req.acceptsEncodings()`.
+
+`req.acceptsLanguage()` is replaced by `req.acceptsLanguages()`.
+
+{% capture codemod-pluralized-methods %}
+You can replace the deprecated signatures with the following command:
+
+```plaintext
+npx codemod@latest @expressjs/pluralize-method-names
+```
+
+{% endcapture %}
+
+{% include admonitions/note.html content=codemod-pluralized-methods %}
+
+```js
+// v4
+app.all("/", (req, res) => {
+ req.acceptsCharset("utf-8");
+ req.acceptsEncoding("br");
+ req.acceptsLanguage("en");
+
+ // ...
+});
+
+// v5
+app.all("/", (req, res) => {
+ req.acceptsCharsets("utf-8");
+ req.acceptsEncodings("br");
+ req.acceptsLanguages("en");
+
+ // ...
+});
+```
+
+Leading colon (:) in the name for app.param(name, fn)
+
+A leading colon character (:) in the name for the `app.param(name, fn)` function is a remnant of Express 3, and for the sake of backwards compatibility, Express 4 supported it with a deprecation notice. Express 5 will silently ignore it and use the name parameter without prefixing it with a colon.
+
+This should not affect your code if you follow the Express 4 documentation of [app.param](/{{ page.lang }}/4x/api.html#app.param), as it makes no mention of the leading colon.
+
+req.param(name)
+
+This potentially confusing and dangerous method of retrieving form data has been removed. You will now need to specifically look for the submitted parameter name in the `req.params`, `req.body`, or `req.query` object.
+
+{% capture codemod-req-param %}
+You can replace the deprecated signatures with the following command:
+
+```plaintext
+npx codemod@latest @expressjs/explicit-request-params
+```
+
+{% endcapture %}
+
+{% include admonitions/note.html content=codemod-req-param %}
+
+```js
+// v4
+app.post("/user", (req, res) => {
+ const id = req.param("id");
+ const body = req.param("body");
+ const query = req.param("query");
+
+ // ...
+});
+
+// v5
+app.post("/user", (req, res) => {
+ const id = req.params.id;
+ const body = req.body;
+ const query = req.query;
+
+ // ...
+});
+```
+
+res.json(obj, status)
+
+Express 5 no longer supports the signature `res.json(obj, status)`. Instead, set the status and then chain it to the `res.json()` method like this: `res.status(status).json(obj)`.
+
+{% capture codemod-status-send-order %}
+You can replace the deprecated signatures with the following command:
+
+```plaintext
+npx codemod@latest @expressjs/status-send-order
+```
+
+{% endcapture %}
+
+{% include admonitions/note.html content=codemod-status-send-order %}
+
+```js
+// v4
+app.post("/user", (req, res) => {
+ res.json({ name: "Ruben" }, 201);
+});
+
+// v5
+app.post("/user", (req, res) => {
+ res.status(201).json({ name: "Ruben" });
+});
+```
+
+res.jsonp(obj, status)
+
+Express 5 no longer supports the signature `res.jsonp(obj, status)`. Instead, set the status and then chain it to the `res.jsonp()` method like this: `res.status(status).jsonp(obj)`.
+
+{% include admonitions/note.html content=codemod-status-send-order %}
+
+```js
+// v4
+app.post("/user", (req, res) => {
+ res.jsonp({ name: "Ruben" }, 201);
+});
+
+// v5
+app.post("/user", (req, res) => {
+ res.status(201).jsonp({ name: "Ruben" });
+});
+```
+
+res.redirect(url, status)
+
+Express 5 no longer supports the signature `res.redirect(url, status)`. Instead, use the following signature: `res.redirect(status, url)`.
+
+{% capture codemod-redirect-arg-order %}
+You can replace the deprecated signatures with the following command:
+
+```plaintext
+npx codemod@latest @expressjs/redirect-arg-order
+```
+
+{% endcapture %}
+
+{% include admonitions/note.html content=codemod-redirect-arg-order %}
+
+```js
+// v4
+app.get("/user", (req, res) => {
+ res.redirect("/users", 301);
+});
+
+// v5
+app.get("/user", (req, res) => {
+ res.redirect(301, "/users");
+});
+```
+
+res.redirect('back') and res.location('back')
+
+Express 5 no longer supports the magic string `back` in the `res.redirect()` and `res.location()` methods. Instead, use the `req.get('Referrer') || '/'` value to redirect back to the previous page. In Express 4, the `res.redirect('back')` and `res.location('back')` methods were deprecated.
+
+{% capture codemod-back-redirect-deprecated %}
+You can replace the deprecated signatures with the following command:
+
+```plaintext
+npx codemod@latest @expressjs/back-redirect-deprecated
+```
+
+{% endcapture %}
+
+{% include admonitions/note.html content=codemod-back-redirect-deprecated %}
+
+```js
+// v4
+app.get("/user", (req, res) => {
+ res.redirect("back");
+});
+
+// v5
+app.get("/user", (req, res) => {
+ res.redirect(req.get("Referrer") || "/");
+});
+```
+
+res.send(body, status)
+
+Express 5 no longer supports the signature `res.send(obj, status)`. Instead, set the status and then chain it to the `res.send()` method like this: `res.status(status).send(obj)`.
+
+{% include admonitions/note.html content=codemod-status-send-order %}
+
+```js
+// v4
+app.get("/user", (req, res) => {
+ res.send({ name: "Ruben" }, 200);
+});
+
+// v5
+app.get("/user", (req, res) => {
+ res.status(200).send({ name: "Ruben" });
+});
+```
+
+res.send(status)
+
+Express 5 no longer supports the signature `res.send(status)`, where `status` is a number. Instead, use the `res.sendStatus(statusCode)` function, which sets the HTTP response header status code and sends the text version of the code: "Not Found", "Internal Server Error", and so on.
+If you need to send a number by using the `res.send()` function, quote the number to convert it to a string, so that Express does not interpret it as an attempt to use the unsupported old signature.
+
+{% include admonitions/note.html content=codemod-status-send-order %}
+
+```js
+// v4
+app.get("/user", (req, res) => {
+ res.send(200);
+});
+
+// v5
+app.get("/user", (req, res) => {
+ res.sendStatus(200);
+});
+```
+
+res.sendfile()
+
+The `res.sendfile()` function has been replaced by a camel-cased version `res.sendFile()` in Express 5.
+
+**Note:** In Express 5, `res.sendFile()` uses the `mime-types` package for MIME type detection, which returns different Content-Type values than Express 4 for several common file types:
+
+- JavaScript files (.js): now "text/javascript" instead of "application/javascript"
+- JSON files (.json): now "application/json" instead of "text/json"
+- CSS files (.css): now "text/css" instead of "text/plain"
+- XML files (.xml): now "application/xml" instead of "text/xml"
+- Font files (.woff): now "font/woff" instead of "application/font-woff"
+- SVG files (.svg): now "image/svg+xml" instead of "application/svg+xml"
+
+{% capture codemod-camelcase-sendfile %}
+You can replace the deprecated signatures with the following command:
+
+```plaintext
+npx codemod@latest @expressjs/camelcase-sendfile
+```
+
+{% endcapture %}
+
+{% include admonitions/note.html content=codemod-camelcase-sendfile %}
+
+```js
+// v4
+app.get("/user", (req, res) => {
+ res.sendfile("/path/to/file");
+});
+
+// v5
+app.get("/user", (req, res) => {
+ res.sendFile("/path/to/file");
+});
+```
+
+router.param(fn)
+
+The `router.param(fn)` signature was used for modifying the behavior of the `router.param(name, fn)` function. It has been deprecated since v4.11.0, and Express 5 no longer supports it at all.
+
+express.static.mime
+
+In Express 5, `mime` is no longer an exported property of the `static` field.
+Use the [`mime-types` package](https://github.com/jshttp/mime-types) to work with MIME type values.
+
+**Important:** This change affects not only direct usage of `express.static.mime` but also other Express methods that rely on MIME type detection, such as `res.sendFile()`. The following MIME types have changed from Express 4:
+
+- JavaScript files (.js): now served as "text/javascript" instead of "application/javascript"
+- JSON files (.json): now served as "application/json" instead of "text/json"
+- CSS files (.css): now served as "text/css" instead of "text/plain"
+- HTML files (.html): now served as "text/html; charset=utf-8" instead of just "text/html"
+- XML files (.xml): now served as "application/xml" instead of "text/xml"
+- Font files (.woff): now served as "font/woff" instead of "application/font-woff"
+
+```js
+// v4
+express.static.mime.lookup("json");
+
+// v5
+const mime = require("mime-types");
+mime.lookup("json");
+```
+
+express:router debug logs
+
+In Express 5, router handling logic is performed by a dependency. Therefore, the
+debug logs for the router are no longer available under the `express:` namespace.
+In v4, the logs were available under the namespaces `express:router`, `express:router:layer`,
+and `express:router:route`. All of these were included under the namespace `express:*`.
+In v5.1+, the logs are available under the namespaces `router`, `router:layer`, and `router:route`.
+The logs from `router:layer` and `router:route` are included in the namespace `router:*`.
+To achieve the same detail of debug logging when using `express:*` in v4, use a conjunction of
+`express:*`, `router`, and `router:*`.
+
+```sh
+# v4
+DEBUG=express:* node index.js
+
+# v5
+DEBUG=express:*,router,router:* node index.js
+```
+
+## Changed
+
+Path route matching syntax
+
+Path route matching syntax is when a string is supplied as the first parameter to the `app.all()`, `app.use()`, `app.METHOD()`, `router.all()`, `router.METHOD()`, and `router.use()` APIs. The following changes have been made to how the path string is matched to an incoming request:
+
+- The wildcard `*` must have a name, matching the behavior of parameters `:`, use `/*splat` instead of `/*`
+
+```js
+// v4
+app.get("/*", async (req, res) => {
+ res.send("ok");
+});
+
+// v5
+app.get("/*splat", async (req, res) => {
+ res.send("ok");
+});
+```
+
+{% capture note_wildcard %}
+`*splat` matches any path without the root path. If you need to match the root path as well `/`, you can use `/{*splat}`, wrapping the wildcard in braces.
+
+```js
+// v5
+app.get("/{*splat}", async (req, res) => {
+ res.send("ok");
+});
+```
+
+{% endcapture %}
+{% include admonitions/note.html content=note_wildcard %}
+
+- The optional character `?` is no longer supported, use braces instead.
+
+```js
+// v4
+app.get("/:file.:ext?", async (req, res) => {
+ res.send("ok");
+});
+
+// v5
+app.get("/:file{.:ext}", async (req, res) => {
+ res.send("ok");
+});
+```
+
+- Regexp characters are not supported. For example:
+
+```js
+app.get("/[discussion|page]/:slug", async (req, res) => {
+ res.status(200).send("ok");
+});
+```
+
+should be changed to:
+
+```js
+app.get(["/discussion/:slug", "/page/:slug"], async (req, res) => {
+ res.status(200).send("ok");
+});
+```
+
+- Some characters have been reserved to avoid confusion during upgrade (`()[]?+!`), use `\` to escape them.
+- Parameter names now support valid JavaScript identifiers, or quoted like `:"this"`.
+
+Rejected promises handled from middleware and handlers
+
+Request middleware and handlers that return rejected promises are now handled by forwarding the rejected value as an `Error` to the error handling middleware. This means that using `async` functions as middleware and handlers are easier than ever. When an error is thrown in an `async` function or a rejected promise is `await`ed inside an async function, those errors will be passed to the error handler as if calling `next(err)`.
+
+Details of how Express handles errors is covered in the [error handling documentation](/en/guide/error-handling.html).
+
+express.urlencoded
+
+The `express.urlencoded` method makes the `extended` option `false` by default.
+
+express.static dotfiles
+
+In Express 5, the `express.static` middleware's `dotfiles` option now defaults to `"ignore"`. This is a change from Express 4, where dotfiles were served by default. As a result, files inside a directory that starts with a dot (`.`), such as `.well-known`, will no longer be accessible and will return a **404 Not Found** error. This can break functionality that depends on serving dot-directories, such as Android App Links, and Apple Universal Links.
+
+Example of breaking code:
+
+```js
+// v4
+app.use(express.static("public"));
+```
+
+After migrating to Express 5, a request to `/.well-known/assetlinks.json` will result in a **404 Not Found**.
+
+To fix this, serve specific dot-directories explicitly using the `dotfiles: "allow"` option:
+
+```js
+// v5
+app.use(
+ "/.well-known",
+ express.static("public/.well-known", { dotfiles: "allow" }),
+);
+app.use(express.static("public"));
+```
+
+This approach allows you to safely serve only the intended dot-directories while keeping the default secure behavior for other dotfiles, which remain inaccessible.
+
+app.listen
+
+In Express 5, the `app.listen` method will invoke the user-provided callback function (if provided) when the server receives an error event. In Express 4, such errors would be thrown. This change shifts error-handling responsibility to the callback function in Express 5. If there is an error, it will be passed to the callback as an argument.
+For example:
+
+```js
+const server = app.listen(8080, "0.0.0.0", (error) => {
+ if (error) {
+ throw error; // e.g. EADDRINUSE
+ }
+ console.log(`Listening on ${JSON.stringify(server.address())}`);
+});
+```
+
+app.router
+
+The `app.router` object, which was removed in Express 4, has made a comeback in Express 5. In the new version, this object is a just a reference to the base Express router, unlike in Express 3, where an app had to explicitly load it.
+
+req.body
+
+The `req.body` property returns `undefined` when the body has not been parsed. In Express 4, it returns `{}` by default.
+
+req.host
+
+In Express 4, the `req.host` function incorrectly stripped off the port number if it was present. In Express 5, the port number is maintained.
+
+req.params
+
+The `req.params` object now has a **null prototype** when using string paths. However, if the path is defined with a regular expression, `req.params` remains a standard object with a normal prototype. Additionally, there are two important behavioral changes:
+
+**Wildcard parameters are now arrays:**
+
+Wildcards (e.g., `/*splat`) capture path segments as an array instead of a single string.
+
+```js
+app.get("/*splat", (req, res) => {
+ // GET /foo/bar
+ console.dir(req.params);
+ // => [Object: null prototype] { splat: [ 'foo', 'bar' ] }
+});
+```
+
+**Unmatched parameters are omitted:**
+
+In Express 4, unmatched wildcards were empty strings (`''`) and optional `:` parameters (using `?`) had a key with value `undefined`. In Express 5, unmatched parameters are completely omitted from `req.params`.
+
+```js
+// v4: unmatched wildcard is empty string
+app.get("/*", (req, res) => {
+ // GET /
+ console.dir(req.params);
+ // => { '0': '' }
+});
+
+// v4: unmatched optional param is undefined
+app.get("/:file.:ext?", (req, res) => {
+ // GET /image
+ console.dir(req.params);
+ // => { file: 'image', ext: undefined }
+});
+
+// v5: unmatched optional param is omitted
+app.get("/:file{.:ext}", (req, res) => {
+ // GET /image
+ console.dir(req.params);
+ // => [Object: null prototype] { file: 'image' }
+});
+```
+
+req.query
+
+The `req.query` property is no longer a writable property and is instead a getter. The default query parser has been changed from "extended" to "simple".
+
+res.clearCookie
+
+The `res.clearCookie` method ignores the `maxAge` and `expires` options provided by the user.
+
+res.status
+
+The `res.status` method only accepts integers in the range of `100` to `999`, following the behavior defined by Node.js, and it returns an error when the status code is not an integer.
+
+res.vary
+
+The `res.vary` throws an error when the `field` argument is missing. In Express 4, if the argument was omitted, it gave a warning in the console
+
+## Improvements
+
+res.render()
+
+This method now enforces asynchronous behavior for all view engines, avoiding bugs caused by view engines that had a synchronous implementation and that violated the recommended interface.
+
+Brotli encoding support
+
+Express 5 supports Brotli encoding for requests received from clients that support it.
diff --git a/en/guide/overriding-express-api.md b/legacy/en/guide/overriding-express-api.md
similarity index 100%
rename from en/guide/overriding-express-api.md
rename to legacy/en/guide/overriding-express-api.md
diff --git a/en/guide/routing.md b/legacy/en/guide/routing.md
similarity index 100%
rename from en/guide/routing.md
rename to legacy/en/guide/routing.md
diff --git a/en/guide/using-middleware.md b/legacy/en/guide/using-middleware.md
similarity index 100%
rename from en/guide/using-middleware.md
rename to legacy/en/guide/using-middleware.md
diff --git a/en/guide/using-template-engines.md b/legacy/en/guide/using-template-engines.md
similarity index 100%
rename from en/guide/using-template-engines.md
rename to legacy/en/guide/using-template-engines.md
diff --git a/en/guide/writing-middleware.md b/legacy/en/guide/writing-middleware.md
similarity index 100%
rename from en/guide/writing-middleware.md
rename to legacy/en/guide/writing-middleware.md
diff --git a/en/resources/community.md b/legacy/en/resources/community.md
similarity index 100%
rename from en/resources/community.md
rename to legacy/en/resources/community.md
diff --git a/en/resources/contributing.md b/legacy/en/resources/contributing.md
similarity index 100%
rename from en/resources/contributing.md
rename to legacy/en/resources/contributing.md
diff --git a/en/resources/glossary.md b/legacy/en/resources/glossary.md
similarity index 100%
rename from en/resources/glossary.md
rename to legacy/en/resources/glossary.md
diff --git a/en/resources/middleware.md b/legacy/en/resources/middleware.md
similarity index 100%
rename from en/resources/middleware.md
rename to legacy/en/resources/middleware.md
diff --git a/en/resources/middleware/body-parser.md b/legacy/en/resources/middleware/body-parser.md
similarity index 100%
rename from en/resources/middleware/body-parser.md
rename to legacy/en/resources/middleware/body-parser.md
diff --git a/en/resources/middleware/compression.md b/legacy/en/resources/middleware/compression.md
similarity index 100%
rename from en/resources/middleware/compression.md
rename to legacy/en/resources/middleware/compression.md
diff --git a/en/resources/middleware/connect-rid.md b/legacy/en/resources/middleware/connect-rid.md
similarity index 100%
rename from en/resources/middleware/connect-rid.md
rename to legacy/en/resources/middleware/connect-rid.md
diff --git a/en/resources/middleware/cookie-parser.md b/legacy/en/resources/middleware/cookie-parser.md
similarity index 100%
rename from en/resources/middleware/cookie-parser.md
rename to legacy/en/resources/middleware/cookie-parser.md
diff --git a/en/resources/middleware/cookie-session.md b/legacy/en/resources/middleware/cookie-session.md
similarity index 100%
rename from en/resources/middleware/cookie-session.md
rename to legacy/en/resources/middleware/cookie-session.md
diff --git a/en/resources/middleware/cors.md b/legacy/en/resources/middleware/cors.md
similarity index 100%
rename from en/resources/middleware/cors.md
rename to legacy/en/resources/middleware/cors.md
diff --git a/en/resources/middleware/errorhandler.md b/legacy/en/resources/middleware/errorhandler.md
similarity index 100%
rename from en/resources/middleware/errorhandler.md
rename to legacy/en/resources/middleware/errorhandler.md
diff --git a/en/resources/middleware/method-override.md b/legacy/en/resources/middleware/method-override.md
similarity index 100%
rename from en/resources/middleware/method-override.md
rename to legacy/en/resources/middleware/method-override.md
diff --git a/en/resources/middleware/morgan.md b/legacy/en/resources/middleware/morgan.md
similarity index 100%
rename from en/resources/middleware/morgan.md
rename to legacy/en/resources/middleware/morgan.md
diff --git a/en/resources/middleware/multer.md b/legacy/en/resources/middleware/multer.md
similarity index 100%
rename from en/resources/middleware/multer.md
rename to legacy/en/resources/middleware/multer.md
diff --git a/en/resources/middleware/response-time.md b/legacy/en/resources/middleware/response-time.md
similarity index 100%
rename from en/resources/middleware/response-time.md
rename to legacy/en/resources/middleware/response-time.md
diff --git a/en/resources/middleware/serve-favicon.md b/legacy/en/resources/middleware/serve-favicon.md
similarity index 100%
rename from en/resources/middleware/serve-favicon.md
rename to legacy/en/resources/middleware/serve-favicon.md
diff --git a/en/resources/middleware/serve-index.md b/legacy/en/resources/middleware/serve-index.md
similarity index 100%
rename from en/resources/middleware/serve-index.md
rename to legacy/en/resources/middleware/serve-index.md
diff --git a/en/resources/middleware/serve-static.md b/legacy/en/resources/middleware/serve-static.md
similarity index 100%
rename from en/resources/middleware/serve-static.md
rename to legacy/en/resources/middleware/serve-static.md
diff --git a/en/resources/middleware/session.md b/legacy/en/resources/middleware/session.md
similarity index 100%
rename from en/resources/middleware/session.md
rename to legacy/en/resources/middleware/session.md
diff --git a/en/resources/middleware/timeout.md b/legacy/en/resources/middleware/timeout.md
similarity index 100%
rename from en/resources/middleware/timeout.md
rename to legacy/en/resources/middleware/timeout.md
diff --git a/en/resources/middleware/vhost.md b/legacy/en/resources/middleware/vhost.md
similarity index 100%
rename from en/resources/middleware/vhost.md
rename to legacy/en/resources/middleware/vhost.md
diff --git a/en/resources/utils.md b/legacy/en/resources/utils.md
similarity index 100%
rename from en/resources/utils.md
rename to legacy/en/resources/utils.md
diff --git a/en/starter/basic-routing.md b/legacy/en/starter/basic-routing.md
similarity index 100%
rename from en/starter/basic-routing.md
rename to legacy/en/starter/basic-routing.md
diff --git a/en/starter/examples.md b/legacy/en/starter/examples.md
similarity index 100%
rename from en/starter/examples.md
rename to legacy/en/starter/examples.md
diff --git a/en/starter/faq.md b/legacy/en/starter/faq.md
similarity index 100%
rename from en/starter/faq.md
rename to legacy/en/starter/faq.md
diff --git a/en/starter/generator.md b/legacy/en/starter/generator.md
similarity index 100%
rename from en/starter/generator.md
rename to legacy/en/starter/generator.md
diff --git a/en/starter/hello-world.md b/legacy/en/starter/hello-world.md
similarity index 100%
rename from en/starter/hello-world.md
rename to legacy/en/starter/hello-world.md
diff --git a/en/starter/installing.md b/legacy/en/starter/installing.md
similarity index 100%
rename from en/starter/installing.md
rename to legacy/en/starter/installing.md
diff --git a/en/starter/static-files.md b/legacy/en/starter/static-files.md
similarity index 100%
rename from en/starter/static-files.md
rename to legacy/en/starter/static-files.md
diff --git a/en/support/index.md b/legacy/en/support/index.md
similarity index 100%
rename from en/support/index.md
rename to legacy/en/support/index.md
diff --git a/es/3x/api.md b/legacy/es/3x/api.md
similarity index 100%
rename from es/3x/api.md
rename to legacy/es/3x/api.md
diff --git a/es/4x/api.md b/legacy/es/4x/api.md
similarity index 100%
rename from es/4x/api.md
rename to legacy/es/4x/api.md
diff --git a/es/5x/api.md b/legacy/es/5x/api.md
similarity index 100%
rename from es/5x/api.md
rename to legacy/es/5x/api.md
diff --git a/es/advanced/best-practice-performance.md b/legacy/es/advanced/best-practice-performance.md
similarity index 100%
rename from es/advanced/best-practice-performance.md
rename to legacy/es/advanced/best-practice-performance.md
diff --git a/es/advanced/best-practice-security.md b/legacy/es/advanced/best-practice-security.md
similarity index 100%
rename from es/advanced/best-practice-security.md
rename to legacy/es/advanced/best-practice-security.md
diff --git a/es/advanced/developing-template-engines.md b/legacy/es/advanced/developing-template-engines.md
similarity index 100%
rename from es/advanced/developing-template-engines.md
rename to legacy/es/advanced/developing-template-engines.md
diff --git a/es/advanced/healthcheck-graceful-shutdown.md b/legacy/es/advanced/healthcheck-graceful-shutdown.md
similarity index 100%
rename from es/advanced/healthcheck-graceful-shutdown.md
rename to legacy/es/advanced/healthcheck-graceful-shutdown.md
diff --git a/es/advanced/security-updates.md b/legacy/es/advanced/security-updates.md
similarity index 100%
rename from es/advanced/security-updates.md
rename to legacy/es/advanced/security-updates.md
diff --git a/es/api.md b/legacy/es/api.md
similarity index 100%
rename from es/api.md
rename to legacy/es/api.md
diff --git a/es/changelog/index.md b/legacy/es/changelog/index.md
similarity index 100%
rename from es/changelog/index.md
rename to legacy/es/changelog/index.md
diff --git a/es/guide/behind-proxies.md b/legacy/es/guide/behind-proxies.md
similarity index 100%
rename from es/guide/behind-proxies.md
rename to legacy/es/guide/behind-proxies.md
diff --git a/es/guide/database-integration.md b/legacy/es/guide/database-integration.md
similarity index 100%
rename from es/guide/database-integration.md
rename to legacy/es/guide/database-integration.md
diff --git a/es/guide/debugging.md b/legacy/es/guide/debugging.md
similarity index 100%
rename from es/guide/debugging.md
rename to legacy/es/guide/debugging.md
diff --git a/es/guide/error-handling.md b/legacy/es/guide/error-handling.md
similarity index 100%
rename from es/guide/error-handling.md
rename to legacy/es/guide/error-handling.md
diff --git a/es/guide/migrating-4.md b/legacy/es/guide/migrating-4.md
similarity index 100%
rename from es/guide/migrating-4.md
rename to legacy/es/guide/migrating-4.md
diff --git a/es/guide/migrating-5.md b/legacy/es/guide/migrating-5.md
similarity index 86%
rename from es/guide/migrating-5.md
rename to legacy/es/guide/migrating-5.md
index 889c0a18db..40c2316b91 100644
--- a/es/guide/migrating-5.md
+++ b/legacy/es/guide/migrating-5.md
@@ -99,7 +99,7 @@ Inicialmente, se utilizaba `del` en lugar de `delete`, porque `delete` es una pa
{% capture codemod-deprecated-signatures %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod v4-deprecated-signatures
```
@@ -109,14 +109,14 @@ npx @expressjs/codemod v4-deprecated-signatures
```js
// v4
-app.del('/user/:id', (req, res) => {
- res.send(`DELETE /user/${req.params.id}`)
-})
+app.del("/user/:id", (req, res) => {
+ res.send(`DELETE /user/${req.params.id}`);
+});
// v5
-app.delete('/user/:id', (req, res) => {
- res.send(`DELETE /user/${req.params.id}`)
-})
+app.delete("/user/:id", (req, res) => {
+ res.send(`DELETE /user/${req.params.id}`);
+});
```
app.param(fn)
@@ -136,7 +136,7 @@ Los siguientes nombres de métodos se han pluralizado. En Express 4, el uso de l
{% capture codemod-pluralized-methods %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod pluralized-methods
```
@@ -146,22 +146,22 @@ npx @expressjs/codemod pluralized-methods
```js
// v4
-app.all('/', (req, res) => {
- req.acceptsCharset('utf-8')
- req.acceptsEncoding('br')
- req.acceptsLanguage('en')
+app.all("/", (req, res) => {
+ req.acceptsCharset("utf-8");
+ req.acceptsEncoding("br");
+ req.acceptsLanguage("en");
// ...
-})
+});
// v5
-app.all('/', (req, res) => {
- req.acceptsCharsets('utf-8')
- req.acceptsEncodings('br')
- req.acceptsLanguages('en')
+app.all("/", (req, res) => {
+ req.acceptsCharsets("utf-8");
+ req.acceptsEncodings("br");
+ req.acceptsLanguages("en");
// ...
-})
+});
```
Dos puntos (:) delanteros en el nombre de app.param(name, fn)
@@ -177,7 +177,7 @@ Este método potencialmente confuso y peligroso de recuperar datos de formulario
{% capture codemod-req-param %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod req-param
```
@@ -187,22 +187,22 @@ npx @expressjs/codemod req-param
```js
// v4
-app.post('/user', (req, res) => {
- const id = req.param('id')
- const body = req.param('body')
- const query = req.param('query')
+app.post("/user", (req, res) => {
+ const id = req.param("id");
+ const body = req.param("body");
+ const query = req.param("query");
// ...
-})
+});
// v5
-app.post('/user', (req, res) => {
- const id = req.params.id
- const body = req.body
- const query = req.query
+app.post("/user", (req, res) => {
+ const id = req.params.id;
+ const body = req.body;
+ const query = req.query;
// ...
-})
+});
```
res.json(obj, status)
@@ -213,14 +213,14 @@ Express 5 ya no da soporte a la firma `res.json(obj, status)`. En su lugar, esta
```js
// v4
-app.post('/user', (req, res) => {
- res.json({ name: 'Ruben' }, 201)
-})
+app.post("/user", (req, res) => {
+ res.json({ name: "Ruben" }, 201);
+});
// v5
-app.post('/user', (req, res) => {
- res.status(201).json({ name: 'Ruben' })
-})
+app.post("/user", (req, res) => {
+ res.status(201).json({ name: "Ruben" });
+});
```
res.jsonp(obj, status)
@@ -231,14 +231,14 @@ Express 5 ya no da soporte a la firma `res.jsonp(obj, status)`. En su lugar, est
```js
// v4
-app.post('/user', (req, res) => {
- res.jsonp({ name: 'Ruben' }, 201)
-})
+app.post("/user", (req, res) => {
+ res.jsonp({ name: "Ruben" }, 201);
+});
// v5
-app.post('/user', (req, res) => {
- res.status(201).jsonp({ name: 'Ruben' })
-})
+app.post("/user", (req, res) => {
+ res.status(201).jsonp({ name: "Ruben" });
+});
```
res.redirect(url, status)
@@ -249,14 +249,14 @@ Express 5 ya no da soporte a la firma `res.send(obj, status)`. En su lugar, esta
```js
// v4
-app.get('/user', (req, res) => {
- res.redirect('/users', 301)
-})
+app.get("/user", (req, res) => {
+ res.redirect("/users", 301);
+});
// v5
-app.get('/user', (req, res) => {
- res.redirect(301, '/users')
-})
+app.get("/user", (req, res) => {
+ res.redirect(301, "/users");
+});
```
res.redirect('back') and res.location('back')
@@ -266,7 +266,7 @@ Express 5 no longer supports the magic string `back` in the `res.redirect()` and
{% capture codemod-magic-redirect %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod magic-redirect
```
@@ -276,14 +276,14 @@ npx @expressjs/codemod magic-redirect
```js
// v4
-app.get('/user', (req, res) => {
- res.redirect('back')
-})
+app.get("/user", (req, res) => {
+ res.redirect("back");
+});
// v5
-app.get('/user', (req, res) => {
- res.redirect(req.get('Referrer') || '/')
-})
+app.get("/user", (req, res) => {
+ res.redirect(req.get("Referrer") || "/");
+});
```
res.send(body, status)
@@ -294,14 +294,14 @@ Express 5 no longer supports the signature `res.send(obj, status)`. Instead, set
```js
// v4
-app.get('/user', (req, res) => {
- res.send({ name: 'Ruben' }, 200)
-})
+app.get("/user", (req, res) => {
+ res.send({ name: "Ruben" }, 200);
+});
// v5
-app.get('/user', (req, res) => {
- res.status(200).send({ name: 'Ruben' })
-})
+app.get("/user", (req, res) => {
+ res.status(200).send({ name: "Ruben" });
+});
```
res.send(status)
@@ -313,14 +313,14 @@ Si necesita enviar un número utilizando la función `res.send()`, escríbalo en
```js
// v4
-app.get('/user', (req, res) => {
- res.send(200)
-})
+app.get("/user", (req, res) => {
+ res.send(200);
+});
// v5
-app.get('/user', (req, res) => {
- res.sendStatus(200)
-})
+app.get("/user", (req, res) => {
+ res.sendStatus(200);
+});
```
res.sendfile()
@@ -340,14 +340,14 @@ La función `res.sendfile()` se ha sustituido por una versión de la función `r
```js
// v4
-app.get('/user', (req, res) => {
- res.sendfile('/path/to/file')
-})
+app.get("/user", (req, res) => {
+ res.sendfile("/path/to/file");
+});
// v5
-app.get('/user', (req, res) => {
- res.sendFile('/path/to/file')
-})
+app.get("/user", (req, res) => {
+ res.sendFile("/path/to/file");
+});
```
router.param(fn)
@@ -370,11 +370,11 @@ Use the [`mime-types` package](https://github.com/jshttp/mime-types) to work wit
```js
// v4
-express.static.mime.lookup('json')
+express.static.mime.lookup("json");
// v5
-const mime = require('mime-types')
-mime.lookup('json')
+const mime = require("mime-types");
+mime.lookup("json");
```
express:router debug logs
@@ -406,14 +406,14 @@ Path route matching syntax is when a string is supplied as the first parameter t
```js
// v4
-app.get('/*', async (req, res) => {
- res.send('ok')
-})
+app.get("/*", async (req, res) => {
+ res.send("ok");
+});
// v5
-app.get('/*splat', async (req, res) => {
- res.send('ok')
-})
+app.get("/*splat", async (req, res) => {
+ res.send("ok");
+});
```
{% capture note_wildcard %}
@@ -421,9 +421,9 @@ app.get('/*splat', async (req, res) => {
```js
// v5
-app.get('/{*splat}', async (req, res) => {
- res.send('ok')
-})
+app.get("/{*splat}", async (req, res) => {
+ res.send("ok");
+});
```
{% endcapture %}
@@ -433,30 +433,30 @@ app.get('/{*splat}', async (req, res) => {
```js
// v4
-app.get('/:file.:ext?', async (req, res) => {
- res.send('ok')
-})
+app.get("/:file.:ext?", async (req, res) => {
+ res.send("ok");
+});
// v5
-app.get('/:file{.:ext}', async (req, res) => {
- res.send('ok')
-})
+app.get("/:file{.:ext}", async (req, res) => {
+ res.send("ok");
+});
```
- Regexp characters are not supported. For example:
```js
-app.get('/[discussion|page]/:slug', async (req, res) => {
- res.status(200).send('ok')
-})
+app.get("/[discussion|page]/:slug", async (req, res) => {
+ res.status(200).send("ok");
+});
```
should be changed to:
```js
-app.get(['/discussion/:slug', '/page/:slug'], async (req, res) => {
- res.status(200).send('ok')
-})
+app.get(["/discussion/:slug", "/page/:slug"], async (req, res) => {
+ res.status(200).send("ok");
+});
```
- Some characters have been reserved to avoid confusion during upgrade (`()[]?+!`), use `\` to escape them.
@@ -480,7 +480,7 @@ Example of breaking code:
```js
// v4
-app.use(express.static('public'))
+app.use(express.static("public"));
```
After migrating to Express 5, a request to `/.well-known/assetlinks.json` will result in a **404 Not Found**.
@@ -489,8 +489,11 @@ To fix this, serve specific dot-directories explicitly using the `dotfiles: "all
```js
// v5
-app.use('/.well-known', express.static('public/.well-known', { dotfiles: 'allow' }))
-app.use(express.static('public'))
+app.use(
+ "/.well-known",
+ express.static("public/.well-known", { dotfiles: "allow" }),
+);
+app.use(express.static("public"));
```
This approach allows you to safely serve only the intended dot-directories while keeping the default secure behavior for other dotfiles, which remain inaccessible.
@@ -501,12 +504,12 @@ In Express 5, the `app.listen` method will invoke the user-provided callback fun
For example:
```js
-const server = app.listen(8080, '0.0.0.0', (error) => {
+const server = app.listen(8080, "0.0.0.0", (error) => {
if (error) {
- throw error // e.g. EADDRINUSE
+ throw error; // e.g. EADDRINUSE
}
- console.log(`Listening on ${JSON.stringify(server.address())}`)
-})
+ console.log(`Listening on ${JSON.stringify(server.address())}`);
+});
```
app.router
@@ -530,11 +533,11 @@ The `req.params` object now has a **null prototype** when using string paths. Ho
Wildcards (e.g., `/*splat`) capture path segments as an array instead of a single string.
```js
-app.get('/*splat', (req, res) => {
+app.get("/*splat", (req, res) => {
// GET /foo/bar
- console.dir(req.params)
+ console.dir(req.params);
// => [Object: null prototype] { splat: [ 'foo', 'bar' ] }
-})
+});
```
**Unmatched parameters are omitted:**
@@ -543,25 +546,25 @@ In Express 4, unmatched wildcards were empty strings (`''`) and optional `:` par
```js
// v4: unmatched wildcard is empty string
-app.get('/*', (req, res) => {
+app.get("/*", (req, res) => {
// GET /
- console.dir(req.params)
+ console.dir(req.params);
// => { '0': '' }
-})
+});
// v4: unmatched optional param is undefined
-app.get('/:file.:ext?', (req, res) => {
+app.get("/:file.:ext?", (req, res) => {
// GET /image
- console.dir(req.params)
+ console.dir(req.params);
// => { file: 'image', ext: undefined }
-})
+});
// v5: unmatched optional param is omitted
-app.get('/:file{.:ext}', (req, res) => {
+app.get("/:file{.:ext}", (req, res) => {
// GET /image
- console.dir(req.params)
+ console.dir(req.params);
// => [Object: null prototype] { file: 'image' }
-})
+});
```
req.query
diff --git a/es/guide/overriding-express-api.md b/legacy/es/guide/overriding-express-api.md
similarity index 100%
rename from es/guide/overriding-express-api.md
rename to legacy/es/guide/overriding-express-api.md
diff --git a/es/guide/routing.md b/legacy/es/guide/routing.md
similarity index 100%
rename from es/guide/routing.md
rename to legacy/es/guide/routing.md
diff --git a/es/guide/using-middleware.md b/legacy/es/guide/using-middleware.md
similarity index 100%
rename from es/guide/using-middleware.md
rename to legacy/es/guide/using-middleware.md
diff --git a/es/guide/using-template-engines.md b/legacy/es/guide/using-template-engines.md
similarity index 100%
rename from es/guide/using-template-engines.md
rename to legacy/es/guide/using-template-engines.md
diff --git a/es/guide/writing-middleware.md b/legacy/es/guide/writing-middleware.md
similarity index 100%
rename from es/guide/writing-middleware.md
rename to legacy/es/guide/writing-middleware.md
diff --git a/es/index.md b/legacy/es/index.md
similarity index 100%
rename from es/index.md
rename to legacy/es/index.md
diff --git a/es/resources/community.md b/legacy/es/resources/community.md
similarity index 100%
rename from es/resources/community.md
rename to legacy/es/resources/community.md
diff --git a/es/resources/contributing.md b/legacy/es/resources/contributing.md
similarity index 100%
rename from es/resources/contributing.md
rename to legacy/es/resources/contributing.md
diff --git a/es/resources/glossary.md b/legacy/es/resources/glossary.md
similarity index 100%
rename from es/resources/glossary.md
rename to legacy/es/resources/glossary.md
diff --git a/es/resources/middleware.md b/legacy/es/resources/middleware.md
similarity index 100%
rename from es/resources/middleware.md
rename to legacy/es/resources/middleware.md
diff --git a/es/resources/middleware/body-parser.md b/legacy/es/resources/middleware/body-parser.md
similarity index 100%
rename from es/resources/middleware/body-parser.md
rename to legacy/es/resources/middleware/body-parser.md
diff --git a/es/resources/middleware/compression.md b/legacy/es/resources/middleware/compression.md
similarity index 100%
rename from es/resources/middleware/compression.md
rename to legacy/es/resources/middleware/compression.md
diff --git a/es/resources/middleware/connect-rid.md b/legacy/es/resources/middleware/connect-rid.md
similarity index 100%
rename from es/resources/middleware/connect-rid.md
rename to legacy/es/resources/middleware/connect-rid.md
diff --git a/es/resources/middleware/cookie-parser.md b/legacy/es/resources/middleware/cookie-parser.md
similarity index 100%
rename from es/resources/middleware/cookie-parser.md
rename to legacy/es/resources/middleware/cookie-parser.md
diff --git a/es/resources/middleware/cookie-session.md b/legacy/es/resources/middleware/cookie-session.md
similarity index 100%
rename from es/resources/middleware/cookie-session.md
rename to legacy/es/resources/middleware/cookie-session.md
diff --git a/es/resources/middleware/cors.md b/legacy/es/resources/middleware/cors.md
similarity index 100%
rename from es/resources/middleware/cors.md
rename to legacy/es/resources/middleware/cors.md
diff --git a/es/resources/middleware/errorhandler.md b/legacy/es/resources/middleware/errorhandler.md
similarity index 100%
rename from es/resources/middleware/errorhandler.md
rename to legacy/es/resources/middleware/errorhandler.md
diff --git a/es/resources/middleware/method-override.md b/legacy/es/resources/middleware/method-override.md
similarity index 100%
rename from es/resources/middleware/method-override.md
rename to legacy/es/resources/middleware/method-override.md
diff --git a/es/resources/middleware/morgan.md b/legacy/es/resources/middleware/morgan.md
similarity index 100%
rename from es/resources/middleware/morgan.md
rename to legacy/es/resources/middleware/morgan.md
diff --git a/es/resources/middleware/multer.md b/legacy/es/resources/middleware/multer.md
similarity index 100%
rename from es/resources/middleware/multer.md
rename to legacy/es/resources/middleware/multer.md
diff --git a/es/resources/middleware/response-time.md b/legacy/es/resources/middleware/response-time.md
similarity index 100%
rename from es/resources/middleware/response-time.md
rename to legacy/es/resources/middleware/response-time.md
diff --git a/es/resources/middleware/serve-favicon.md b/legacy/es/resources/middleware/serve-favicon.md
similarity index 100%
rename from es/resources/middleware/serve-favicon.md
rename to legacy/es/resources/middleware/serve-favicon.md
diff --git a/es/resources/middleware/serve-index.md b/legacy/es/resources/middleware/serve-index.md
similarity index 100%
rename from es/resources/middleware/serve-index.md
rename to legacy/es/resources/middleware/serve-index.md
diff --git a/es/resources/middleware/serve-static.md b/legacy/es/resources/middleware/serve-static.md
similarity index 100%
rename from es/resources/middleware/serve-static.md
rename to legacy/es/resources/middleware/serve-static.md
diff --git a/es/resources/middleware/session.md b/legacy/es/resources/middleware/session.md
similarity index 100%
rename from es/resources/middleware/session.md
rename to legacy/es/resources/middleware/session.md
diff --git a/es/resources/middleware/timeout.md b/legacy/es/resources/middleware/timeout.md
similarity index 100%
rename from es/resources/middleware/timeout.md
rename to legacy/es/resources/middleware/timeout.md
diff --git a/es/resources/middleware/vhost.md b/legacy/es/resources/middleware/vhost.md
similarity index 100%
rename from es/resources/middleware/vhost.md
rename to legacy/es/resources/middleware/vhost.md
diff --git a/es/resources/utils.md b/legacy/es/resources/utils.md
similarity index 100%
rename from es/resources/utils.md
rename to legacy/es/resources/utils.md
diff --git a/es/starter/basic-routing.md b/legacy/es/starter/basic-routing.md
similarity index 100%
rename from es/starter/basic-routing.md
rename to legacy/es/starter/basic-routing.md
diff --git a/es/starter/examples.md b/legacy/es/starter/examples.md
similarity index 100%
rename from es/starter/examples.md
rename to legacy/es/starter/examples.md
diff --git a/es/starter/faq.md b/legacy/es/starter/faq.md
similarity index 100%
rename from es/starter/faq.md
rename to legacy/es/starter/faq.md
diff --git a/es/starter/generator.md b/legacy/es/starter/generator.md
similarity index 100%
rename from es/starter/generator.md
rename to legacy/es/starter/generator.md
diff --git a/es/starter/hello-world.md b/legacy/es/starter/hello-world.md
similarity index 100%
rename from es/starter/hello-world.md
rename to legacy/es/starter/hello-world.md
diff --git a/es/starter/installing.md b/legacy/es/starter/installing.md
similarity index 100%
rename from es/starter/installing.md
rename to legacy/es/starter/installing.md
diff --git a/es/starter/static-files.md b/legacy/es/starter/static-files.md
similarity index 100%
rename from es/starter/static-files.md
rename to legacy/es/starter/static-files.md
diff --git a/es/support/index.md b/legacy/es/support/index.md
similarity index 100%
rename from es/support/index.md
rename to legacy/es/support/index.md
diff --git a/feed.xml b/legacy/feed.xml
similarity index 100%
rename from feed.xml
rename to legacy/feed.xml
diff --git a/fonts/ko/pretendard.css b/legacy/fonts/ko/pretendard.css
similarity index 100%
rename from fonts/ko/pretendard.css
rename to legacy/fonts/ko/pretendard.css
diff --git a/fonts/ko/woff/Pretendard-Black.woff b/legacy/fonts/ko/woff/Pretendard-Black.woff
similarity index 100%
rename from fonts/ko/woff/Pretendard-Black.woff
rename to legacy/fonts/ko/woff/Pretendard-Black.woff
diff --git a/fonts/ko/woff/Pretendard-Bold.woff b/legacy/fonts/ko/woff/Pretendard-Bold.woff
similarity index 100%
rename from fonts/ko/woff/Pretendard-Bold.woff
rename to legacy/fonts/ko/woff/Pretendard-Bold.woff
diff --git a/fonts/ko/woff/Pretendard-ExtraBold.woff b/legacy/fonts/ko/woff/Pretendard-ExtraBold.woff
similarity index 100%
rename from fonts/ko/woff/Pretendard-ExtraBold.woff
rename to legacy/fonts/ko/woff/Pretendard-ExtraBold.woff
diff --git a/fonts/ko/woff/Pretendard-ExtraLight.woff b/legacy/fonts/ko/woff/Pretendard-ExtraLight.woff
similarity index 100%
rename from fonts/ko/woff/Pretendard-ExtraLight.woff
rename to legacy/fonts/ko/woff/Pretendard-ExtraLight.woff
diff --git a/fonts/ko/woff/Pretendard-Light.woff b/legacy/fonts/ko/woff/Pretendard-Light.woff
similarity index 100%
rename from fonts/ko/woff/Pretendard-Light.woff
rename to legacy/fonts/ko/woff/Pretendard-Light.woff
diff --git a/fonts/ko/woff/Pretendard-Medium.woff b/legacy/fonts/ko/woff/Pretendard-Medium.woff
similarity index 100%
rename from fonts/ko/woff/Pretendard-Medium.woff
rename to legacy/fonts/ko/woff/Pretendard-Medium.woff
diff --git a/fonts/ko/woff/Pretendard-Regular.woff b/legacy/fonts/ko/woff/Pretendard-Regular.woff
similarity index 100%
rename from fonts/ko/woff/Pretendard-Regular.woff
rename to legacy/fonts/ko/woff/Pretendard-Regular.woff
diff --git a/fonts/ko/woff/Pretendard-SemiBold.woff b/legacy/fonts/ko/woff/Pretendard-SemiBold.woff
similarity index 100%
rename from fonts/ko/woff/Pretendard-SemiBold.woff
rename to legacy/fonts/ko/woff/Pretendard-SemiBold.woff
diff --git a/fonts/ko/woff/Pretendard-Thin.woff b/legacy/fonts/ko/woff/Pretendard-Thin.woff
similarity index 100%
rename from fonts/ko/woff/Pretendard-Thin.woff
rename to legacy/fonts/ko/woff/Pretendard-Thin.woff
diff --git a/fonts/ko/woff2/Pretendard-Black.woff2 b/legacy/fonts/ko/woff2/Pretendard-Black.woff2
similarity index 100%
rename from fonts/ko/woff2/Pretendard-Black.woff2
rename to legacy/fonts/ko/woff2/Pretendard-Black.woff2
diff --git a/fonts/ko/woff2/Pretendard-Bold.woff2 b/legacy/fonts/ko/woff2/Pretendard-Bold.woff2
similarity index 100%
rename from fonts/ko/woff2/Pretendard-Bold.woff2
rename to legacy/fonts/ko/woff2/Pretendard-Bold.woff2
diff --git a/fonts/ko/woff2/Pretendard-ExtraBold.woff2 b/legacy/fonts/ko/woff2/Pretendard-ExtraBold.woff2
similarity index 100%
rename from fonts/ko/woff2/Pretendard-ExtraBold.woff2
rename to legacy/fonts/ko/woff2/Pretendard-ExtraBold.woff2
diff --git a/fonts/ko/woff2/Pretendard-ExtraLight.woff2 b/legacy/fonts/ko/woff2/Pretendard-ExtraLight.woff2
similarity index 100%
rename from fonts/ko/woff2/Pretendard-ExtraLight.woff2
rename to legacy/fonts/ko/woff2/Pretendard-ExtraLight.woff2
diff --git a/fonts/ko/woff2/Pretendard-Light.woff2 b/legacy/fonts/ko/woff2/Pretendard-Light.woff2
similarity index 100%
rename from fonts/ko/woff2/Pretendard-Light.woff2
rename to legacy/fonts/ko/woff2/Pretendard-Light.woff2
diff --git a/fonts/ko/woff2/Pretendard-Medium.woff2 b/legacy/fonts/ko/woff2/Pretendard-Medium.woff2
similarity index 100%
rename from fonts/ko/woff2/Pretendard-Medium.woff2
rename to legacy/fonts/ko/woff2/Pretendard-Medium.woff2
diff --git a/fonts/ko/woff2/Pretendard-Regular.woff2 b/legacy/fonts/ko/woff2/Pretendard-Regular.woff2
similarity index 100%
rename from fonts/ko/woff2/Pretendard-Regular.woff2
rename to legacy/fonts/ko/woff2/Pretendard-Regular.woff2
diff --git a/fonts/ko/woff2/Pretendard-SemiBold.woff2 b/legacy/fonts/ko/woff2/Pretendard-SemiBold.woff2
similarity index 100%
rename from fonts/ko/woff2/Pretendard-SemiBold.woff2
rename to legacy/fonts/ko/woff2/Pretendard-SemiBold.woff2
diff --git a/fonts/ko/woff2/Pretendard-Thin.woff2 b/legacy/fonts/ko/woff2/Pretendard-Thin.woff2
similarity index 100%
rename from fonts/ko/woff2/Pretendard-Thin.woff2
rename to legacy/fonts/ko/woff2/Pretendard-Thin.woff2
diff --git a/fonts/open-sans/fonts.css b/legacy/fonts/open-sans/fonts.css
similarity index 100%
rename from fonts/open-sans/fonts.css
rename to legacy/fonts/open-sans/fonts.css
diff --git a/fonts/open-sans/woff/OpenSans-Italic.woff b/legacy/fonts/open-sans/woff/OpenSans-Italic.woff
similarity index 100%
rename from fonts/open-sans/woff/OpenSans-Italic.woff
rename to legacy/fonts/open-sans/woff/OpenSans-Italic.woff
diff --git a/fonts/open-sans/woff/OpenSans.woff b/legacy/fonts/open-sans/woff/OpenSans.woff
similarity index 100%
rename from fonts/open-sans/woff/OpenSans.woff
rename to legacy/fonts/open-sans/woff/OpenSans.woff
diff --git a/fonts/open-sans/woff2/open-sans-latin-wght-italic.woff2 b/legacy/fonts/open-sans/woff2/open-sans-latin-wght-italic.woff2
similarity index 100%
rename from fonts/open-sans/woff2/open-sans-latin-wght-italic.woff2
rename to legacy/fonts/open-sans/woff2/open-sans-latin-wght-italic.woff2
diff --git a/fonts/open-sans/woff2/open-sans-latin-wght-normal.woff2 b/legacy/fonts/open-sans/woff2/open-sans-latin-wght-normal.woff2
similarity index 100%
rename from fonts/open-sans/woff2/open-sans-latin-wght-normal.woff2
rename to legacy/fonts/open-sans/woff2/open-sans-latin-wght-normal.woff2
diff --git a/fr/3x/api.md b/legacy/fr/3x/api.md
similarity index 100%
rename from fr/3x/api.md
rename to legacy/fr/3x/api.md
diff --git a/fr/4x/api.md b/legacy/fr/4x/api.md
similarity index 100%
rename from fr/4x/api.md
rename to legacy/fr/4x/api.md
diff --git a/fr/5x/api.md b/legacy/fr/5x/api.md
similarity index 100%
rename from fr/5x/api.md
rename to legacy/fr/5x/api.md
diff --git a/fr/advanced/best-practice-performance.md b/legacy/fr/advanced/best-practice-performance.md
similarity index 100%
rename from fr/advanced/best-practice-performance.md
rename to legacy/fr/advanced/best-practice-performance.md
diff --git a/fr/advanced/best-practice-security.md b/legacy/fr/advanced/best-practice-security.md
similarity index 100%
rename from fr/advanced/best-practice-security.md
rename to legacy/fr/advanced/best-practice-security.md
diff --git a/fr/advanced/developing-template-engines.md b/legacy/fr/advanced/developing-template-engines.md
similarity index 100%
rename from fr/advanced/developing-template-engines.md
rename to legacy/fr/advanced/developing-template-engines.md
diff --git a/fr/advanced/healthcheck-graceful-shutdown.md b/legacy/fr/advanced/healthcheck-graceful-shutdown.md
similarity index 100%
rename from fr/advanced/healthcheck-graceful-shutdown.md
rename to legacy/fr/advanced/healthcheck-graceful-shutdown.md
diff --git a/fr/advanced/security-updates.md b/legacy/fr/advanced/security-updates.md
similarity index 100%
rename from fr/advanced/security-updates.md
rename to legacy/fr/advanced/security-updates.md
diff --git a/fr/api.md b/legacy/fr/api.md
similarity index 100%
rename from fr/api.md
rename to legacy/fr/api.md
diff --git a/fr/changelog/index.md b/legacy/fr/changelog/index.md
similarity index 100%
rename from fr/changelog/index.md
rename to legacy/fr/changelog/index.md
diff --git a/fr/guide/behind-proxies.md b/legacy/fr/guide/behind-proxies.md
similarity index 100%
rename from fr/guide/behind-proxies.md
rename to legacy/fr/guide/behind-proxies.md
diff --git a/fr/guide/database-integration.md b/legacy/fr/guide/database-integration.md
similarity index 100%
rename from fr/guide/database-integration.md
rename to legacy/fr/guide/database-integration.md
diff --git a/fr/guide/debugging.md b/legacy/fr/guide/debugging.md
similarity index 100%
rename from fr/guide/debugging.md
rename to legacy/fr/guide/debugging.md
diff --git a/fr/guide/error-handling.md b/legacy/fr/guide/error-handling.md
similarity index 100%
rename from fr/guide/error-handling.md
rename to legacy/fr/guide/error-handling.md
diff --git a/fr/guide/migrating-4.md b/legacy/fr/guide/migrating-4.md
similarity index 100%
rename from fr/guide/migrating-4.md
rename to legacy/fr/guide/migrating-4.md
diff --git a/fr/guide/migrating-5.md b/legacy/fr/guide/migrating-5.md
similarity index 86%
rename from fr/guide/migrating-5.md
rename to legacy/fr/guide/migrating-5.md
index 67db811e24..a035f09ea8 100644
--- a/fr/guide/migrating-5.md
+++ b/legacy/fr/guide/migrating-5.md
@@ -117,7 +117,7 @@ clé réservé dans JavaScript. Cependant, à partir d'ECMAScript 6,
{% capture codemod-deprecated-signatures %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod v4-deprecated-signatures
```
@@ -127,14 +127,14 @@ npx @expressjs/codemod v4-deprecated-signatures
```js
// v4
-app.del('/user/:id', (req, res) => {
- res.send(`DELETE /user/${req.params.id}`)
-})
+app.del("/user/:id", (req, res) => {
+ res.send(`DELETE /user/${req.params.id}`);
+});
// v5
-app.delete('/user/:id', (req, res) => {
- res.send(`DELETE /user/${req.params.id}`)
-})
+app.delete("/user/:id", (req, res) => {
+ res.send(`DELETE /user/${req.params.id}`);
+});
```
app.param(fn)
@@ -161,7 +161,7 @@ d'obsolescence. Express 5 ne les prend plus du tout en charge :
{% capture codemod-pluralized-methods %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod pluralized-methods
```
@@ -171,22 +171,22 @@ npx @expressjs/codemod pluralized-methods
```js
// v4
-app.all('/', (req, res) => {
- req.acceptsCharset('utf-8')
- req.acceptsEncoding('br')
- req.acceptsLanguage('en')
+app.all("/", (req, res) => {
+ req.acceptsCharset("utf-8");
+ req.acceptsEncoding("br");
+ req.acceptsLanguage("en");
// ...
-})
+});
// v5
-app.all('/', (req, res) => {
- req.acceptsCharsets('utf-8')
- req.acceptsEncodings('br')
- req.acceptsLanguages('en')
+app.all("/", (req, res) => {
+ req.acceptsCharsets("utf-8");
+ req.acceptsEncodings("br");
+ req.acceptsLanguages("en");
// ...
-})
+});
```
Signe deux-points (:) de tête dans le nom de la
@@ -212,7 +212,7 @@ l'objet `req.params`, `req.body` ou `req.query`.
{% capture codemod-req-param %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod req-param
```
@@ -222,22 +222,22 @@ npx @expressjs/codemod req-param
```js
// v4
-app.post('/user', (req, res) => {
- const id = req.param('id')
- const body = req.param('body')
- const query = req.param('query')
+app.post("/user", (req, res) => {
+ const id = req.param("id");
+ const body = req.param("body");
+ const query = req.param("query");
// ...
-})
+});
// v5
-app.post('/user', (req, res) => {
- const id = req.params.id
- const body = req.body
- const query = req.query
+app.post("/user", (req, res) => {
+ const id = req.params.id;
+ const body = req.body;
+ const query = req.query;
// ...
-})
+});
```
res.json(obj, status)
@@ -252,14 +252,14 @@ statut et enchaînez-le à la méthode
```js
// v4
-app.post('/user', (req, res) => {
- res.json({ name: 'Ruben' }, 201)
-})
+app.post("/user", (req, res) => {
+ res.json({ name: "Ruben" }, 201);
+});
// v5
-app.post('/user', (req, res) => {
- res.status(201).json({ name: 'Ruben' })
-})
+app.post("/user", (req, res) => {
+ res.status(201).json({ name: "Ruben" });
+});
```
res.jsonp(obj, status)
@@ -273,14 +273,14 @@ comme suit : `res.status(status).jsonp(obj)`.
```js
// v4
-app.post('/user', (req, res) => {
- res.jsonp({ name: 'Ruben' }, 201)
-})
+app.post("/user", (req, res) => {
+ res.jsonp({ name: "Ruben" }, 201);
+});
// v5
-app.post('/user', (req, res) => {
- res.status(201).jsonp({ name: 'Ruben' })
-})
+app.post("/user", (req, res) => {
+ res.status(201).jsonp({ name: "Ruben" });
+});
```
res.redirect(url, status)
@@ -294,14 +294,14 @@ comme suit : `res.status(status).send(obj)`.
```js
// v4
-app.get('/user', (req, res) => {
- res.redirect('/users', 301)
-})
+app.get("/user", (req, res) => {
+ res.redirect("/users", 301);
+});
// v5
-app.get('/user', (req, res) => {
- res.redirect(301, '/users')
-})
+app.get("/user", (req, res) => {
+ res.redirect(301, "/users");
+});
```
res.redirect('back') and res.location('back')
@@ -311,7 +311,7 @@ Express 5 no longer supports the magic string `back` in the `res.redirect()` and
{% capture codemod-magic-redirect %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod magic-redirect
```
@@ -321,14 +321,14 @@ npx @expressjs/codemod magic-redirect
```js
// v4
-app.get('/user', (req, res) => {
- res.redirect('back')
-})
+app.get("/user", (req, res) => {
+ res.redirect("back");
+});
// v5
-app.get('/user', (req, res) => {
- res.redirect(req.get('Referrer') || '/')
-})
+app.get("/user", (req, res) => {
+ res.redirect(req.get("Referrer") || "/");
+});
```
res.send(body, status)
@@ -339,14 +339,14 @@ Express 5 no longer supports the signature `res.send(obj, status)`. Instead, set
```js
// v4
-app.get('/user', (req, res) => {
- res.send({ name: 'Ruben' }, 200)
-})
+app.get("/user", (req, res) => {
+ res.send({ name: "Ruben" }, 200);
+});
// v5
-app.get('/user', (req, res) => {
- res.status(200).send({ name: 'Ruben' })
-})
+app.get("/user", (req, res) => {
+ res.status(200).send({ name: "Ruben" });
+});
```
res.send(status)
@@ -364,14 +364,14 @@ comme une tentative d'utilisation de l'ancienne signature non prise en charge.
```js
// v4
-app.get('/user', (req, res) => {
- res.send(200)
-})
+app.get("/user", (req, res) => {
+ res.send(200);
+});
// v5
-app.get('/user', (req, res) => {
- res.sendStatus(200)
-})
+app.get("/user", (req, res) => {
+ res.sendStatus(200);
+});
```
res.sendfile()
@@ -393,14 +393,14 @@ version CamelCase `res.sendFile()` dans Express 5.
```js
// v4
-app.get('/user', (req, res) => {
- res.sendfile('/path/to/file')
-})
+app.get("/user", (req, res) => {
+ res.sendfile("/path/to/file");
+});
// v5
-app.get('/user', (req, res) => {
- res.sendFile('/path/to/file')
-})
+app.get("/user", (req, res) => {
+ res.sendFile("/path/to/file");
+});
```
router.param(fn)
@@ -424,11 +424,11 @@ Use the [`mime-types` package](https://github.com/jshttp/mime-types) to work wit
```js
// v4
-express.static.mime.lookup('json')
+express.static.mime.lookup("json");
// v5
-const mime = require('mime-types')
-mime.lookup('json')
+const mime = require("mime-types");
+mime.lookup("json");
```
express:router debug logs
@@ -460,14 +460,14 @@ Path route matching syntax is when a string is supplied as the first parameter t
```js
// v4
-app.get('/*', async (req, res) => {
- res.send('ok')
-})
+app.get("/*", async (req, res) => {
+ res.send("ok");
+});
// v5
-app.get('/*splat', async (req, res) => {
- res.send('ok')
-})
+app.get("/*splat", async (req, res) => {
+ res.send("ok");
+});
```
{% capture note_wildcard %}
@@ -475,9 +475,9 @@ app.get('/*splat', async (req, res) => {
```js
// v5
-app.get('/{*splat}', async (req, res) => {
- res.send('ok')
-})
+app.get("/{*splat}", async (req, res) => {
+ res.send("ok");
+});
```
{% endcapture %}
@@ -487,30 +487,30 @@ app.get('/{*splat}', async (req, res) => {
```js
// v4
-app.get('/:file.:ext?', async (req, res) => {
- res.send('ok')
-})
+app.get("/:file.:ext?", async (req, res) => {
+ res.send("ok");
+});
// v5
-app.get('/:file{.:ext}', async (req, res) => {
- res.send('ok')
-})
+app.get("/:file{.:ext}", async (req, res) => {
+ res.send("ok");
+});
```
- Regexp characters are not supported. Par exemple :
```js
-app.get('/[discussion|page]/:slug', async (req, res) => {
- res.status(200).send('ok')
-})
+app.get("/[discussion|page]/:slug", async (req, res) => {
+ res.status(200).send("ok");
+});
```
should be changed to:
```js
-app.get(['/discussion/:slug', '/page/:slug'], async (req, res) => {
- res.status(200).send('ok')
-})
+app.get(["/discussion/:slug", "/page/:slug"], async (req, res) => {
+ res.status(200).send("ok");
+});
```
- Some characters have been reserved to avoid confusion during upgrade (`()[]?+!`), use `\` to escape them.
@@ -534,7 +534,7 @@ Example of breaking code:
```js
// v4
-app.use(express.static('public'))
+app.use(express.static("public"));
```
After migrating to Express 5, a request to `/.well-known/assetlinks.json` will result in a **404 Not Found**.
@@ -543,8 +543,11 @@ To fix this, serve specific dot-directories explicitly using the `dotfiles: "all
```js
// v5
-app.use('/.well-known', express.static('public/.well-known', { dotfiles: 'allow' }))
-app.use(express.static('public'))
+app.use(
+ "/.well-known",
+ express.static("public/.well-known", { dotfiles: "allow" }),
+);
+app.use(express.static("public"));
```
This approach allows you to safely serve only the intended dot-directories while keeping the default secure behavior for other dotfiles, which remain inaccessible.
@@ -555,12 +558,12 @@ In Express 5, the `app.listen` method will invoke the user-provided callback fun
Par exemple :
```js
-const server = app.listen(8080, '0.0.0.0', (error) => {
+const server = app.listen(8080, "0.0.0.0", (error) => {
if (error) {
- throw error // e.g. EADDRINUSE
+ throw error; // e.g. EADDRINUSE
}
- console.log(`Listening on ${JSON.stringify(server.address())}`)
-})
+ console.log(`Listening on ${JSON.stringify(server.address())}`);
+});
```
app.router
@@ -586,11 +589,11 @@ The `req.params` object now has a **null prototype** when using string paths. Ho
Wildcards (e.g., `/*splat`) capture path segments as an array instead of a single string.
```js
-app.get('/*splat', (req, res) => {
+app.get("/*splat", (req, res) => {
// GET /foo/bar
- console.dir(req.params)
+ console.dir(req.params);
// => [Object: null prototype] { splat: [ 'foo', 'bar' ] }
-})
+});
```
**Unmatched parameters are omitted:**
@@ -599,25 +602,25 @@ In Express 4, unmatched wildcards were empty strings (`''`) and optional `:` par
```js
// v4: unmatched wildcard is empty string
-app.get('/*', (req, res) => {
+app.get("/*", (req, res) => {
// GET /
- console.dir(req.params)
+ console.dir(req.params);
// => { '0': '' }
-})
+});
// v4: unmatched optional param is undefined
-app.get('/:file.:ext?', (req, res) => {
+app.get("/:file.:ext?", (req, res) => {
// GET /image
- console.dir(req.params)
+ console.dir(req.params);
// => { file: 'image', ext: undefined }
-})
+});
// v5: unmatched optional param is omitted
-app.get('/:file{.:ext}', (req, res) => {
+app.get("/:file{.:ext}", (req, res) => {
// GET /image
- console.dir(req.params)
+ console.dir(req.params);
// => [Object: null prototype] { file: 'image' }
-})
+});
```
req.query
diff --git a/fr/guide/overriding-express-api.md b/legacy/fr/guide/overriding-express-api.md
similarity index 100%
rename from fr/guide/overriding-express-api.md
rename to legacy/fr/guide/overriding-express-api.md
diff --git a/fr/guide/routing.md b/legacy/fr/guide/routing.md
similarity index 100%
rename from fr/guide/routing.md
rename to legacy/fr/guide/routing.md
diff --git a/fr/guide/using-middleware.md b/legacy/fr/guide/using-middleware.md
similarity index 100%
rename from fr/guide/using-middleware.md
rename to legacy/fr/guide/using-middleware.md
diff --git a/fr/guide/using-template-engines.md b/legacy/fr/guide/using-template-engines.md
similarity index 100%
rename from fr/guide/using-template-engines.md
rename to legacy/fr/guide/using-template-engines.md
diff --git a/fr/guide/writing-middleware.md b/legacy/fr/guide/writing-middleware.md
similarity index 100%
rename from fr/guide/writing-middleware.md
rename to legacy/fr/guide/writing-middleware.md
diff --git a/fr/index.md b/legacy/fr/index.md
similarity index 100%
rename from fr/index.md
rename to legacy/fr/index.md
diff --git a/fr/resources/community.md b/legacy/fr/resources/community.md
similarity index 100%
rename from fr/resources/community.md
rename to legacy/fr/resources/community.md
diff --git a/fr/resources/contributing.md b/legacy/fr/resources/contributing.md
similarity index 100%
rename from fr/resources/contributing.md
rename to legacy/fr/resources/contributing.md
diff --git a/fr/resources/glossary.md b/legacy/fr/resources/glossary.md
similarity index 100%
rename from fr/resources/glossary.md
rename to legacy/fr/resources/glossary.md
diff --git a/fr/resources/middleware.md b/legacy/fr/resources/middleware.md
similarity index 100%
rename from fr/resources/middleware.md
rename to legacy/fr/resources/middleware.md
diff --git a/fr/resources/middleware/body-parser.md b/legacy/fr/resources/middleware/body-parser.md
similarity index 100%
rename from fr/resources/middleware/body-parser.md
rename to legacy/fr/resources/middleware/body-parser.md
diff --git a/fr/resources/middleware/compression.md b/legacy/fr/resources/middleware/compression.md
similarity index 100%
rename from fr/resources/middleware/compression.md
rename to legacy/fr/resources/middleware/compression.md
diff --git a/fr/resources/middleware/connect-rid.md b/legacy/fr/resources/middleware/connect-rid.md
similarity index 100%
rename from fr/resources/middleware/connect-rid.md
rename to legacy/fr/resources/middleware/connect-rid.md
diff --git a/fr/resources/middleware/cookie-parser.md b/legacy/fr/resources/middleware/cookie-parser.md
similarity index 100%
rename from fr/resources/middleware/cookie-parser.md
rename to legacy/fr/resources/middleware/cookie-parser.md
diff --git a/fr/resources/middleware/cookie-session.md b/legacy/fr/resources/middleware/cookie-session.md
similarity index 100%
rename from fr/resources/middleware/cookie-session.md
rename to legacy/fr/resources/middleware/cookie-session.md
diff --git a/fr/resources/middleware/cors.md b/legacy/fr/resources/middleware/cors.md
similarity index 100%
rename from fr/resources/middleware/cors.md
rename to legacy/fr/resources/middleware/cors.md
diff --git a/fr/resources/middleware/errorhandler.md b/legacy/fr/resources/middleware/errorhandler.md
similarity index 100%
rename from fr/resources/middleware/errorhandler.md
rename to legacy/fr/resources/middleware/errorhandler.md
diff --git a/fr/resources/middleware/method-override.md b/legacy/fr/resources/middleware/method-override.md
similarity index 100%
rename from fr/resources/middleware/method-override.md
rename to legacy/fr/resources/middleware/method-override.md
diff --git a/fr/resources/middleware/morgan.md b/legacy/fr/resources/middleware/morgan.md
similarity index 100%
rename from fr/resources/middleware/morgan.md
rename to legacy/fr/resources/middleware/morgan.md
diff --git a/fr/resources/middleware/multer.md b/legacy/fr/resources/middleware/multer.md
similarity index 100%
rename from fr/resources/middleware/multer.md
rename to legacy/fr/resources/middleware/multer.md
diff --git a/fr/resources/middleware/response-time.md b/legacy/fr/resources/middleware/response-time.md
similarity index 100%
rename from fr/resources/middleware/response-time.md
rename to legacy/fr/resources/middleware/response-time.md
diff --git a/fr/resources/middleware/serve-favicon.md b/legacy/fr/resources/middleware/serve-favicon.md
similarity index 100%
rename from fr/resources/middleware/serve-favicon.md
rename to legacy/fr/resources/middleware/serve-favicon.md
diff --git a/fr/resources/middleware/serve-index.md b/legacy/fr/resources/middleware/serve-index.md
similarity index 100%
rename from fr/resources/middleware/serve-index.md
rename to legacy/fr/resources/middleware/serve-index.md
diff --git a/fr/resources/middleware/serve-static.md b/legacy/fr/resources/middleware/serve-static.md
similarity index 100%
rename from fr/resources/middleware/serve-static.md
rename to legacy/fr/resources/middleware/serve-static.md
diff --git a/fr/resources/middleware/session.md b/legacy/fr/resources/middleware/session.md
similarity index 100%
rename from fr/resources/middleware/session.md
rename to legacy/fr/resources/middleware/session.md
diff --git a/fr/resources/middleware/timeout.md b/legacy/fr/resources/middleware/timeout.md
similarity index 100%
rename from fr/resources/middleware/timeout.md
rename to legacy/fr/resources/middleware/timeout.md
diff --git a/fr/resources/middleware/vhost.md b/legacy/fr/resources/middleware/vhost.md
similarity index 100%
rename from fr/resources/middleware/vhost.md
rename to legacy/fr/resources/middleware/vhost.md
diff --git a/fr/resources/utils.md b/legacy/fr/resources/utils.md
similarity index 100%
rename from fr/resources/utils.md
rename to legacy/fr/resources/utils.md
diff --git a/fr/starter/basic-routing.md b/legacy/fr/starter/basic-routing.md
similarity index 100%
rename from fr/starter/basic-routing.md
rename to legacy/fr/starter/basic-routing.md
diff --git a/fr/starter/examples.md b/legacy/fr/starter/examples.md
similarity index 100%
rename from fr/starter/examples.md
rename to legacy/fr/starter/examples.md
diff --git a/fr/starter/faq.md b/legacy/fr/starter/faq.md
similarity index 100%
rename from fr/starter/faq.md
rename to legacy/fr/starter/faq.md
diff --git a/fr/starter/generator.md b/legacy/fr/starter/generator.md
similarity index 100%
rename from fr/starter/generator.md
rename to legacy/fr/starter/generator.md
diff --git a/fr/starter/hello-world.md b/legacy/fr/starter/hello-world.md
similarity index 100%
rename from fr/starter/hello-world.md
rename to legacy/fr/starter/hello-world.md
diff --git a/fr/starter/installing.md b/legacy/fr/starter/installing.md
similarity index 100%
rename from fr/starter/installing.md
rename to legacy/fr/starter/installing.md
diff --git a/fr/starter/static-files.md b/legacy/fr/starter/static-files.md
similarity index 100%
rename from fr/starter/static-files.md
rename to legacy/fr/starter/static-files.md
diff --git a/fr/support/index.md b/legacy/fr/support/index.md
similarity index 100%
rename from fr/support/index.md
rename to legacy/fr/support/index.md
diff --git a/images/blogger.jpg b/legacy/images/blogger.jpg
similarity index 100%
rename from images/blogger.jpg
rename to legacy/images/blogger.jpg
diff --git a/images/brand/logo-dark.svg b/legacy/images/brand/logo-dark.svg
similarity index 100%
rename from images/brand/logo-dark.svg
rename to legacy/images/brand/logo-dark.svg
diff --git a/images/brand/logo-light.svg b/legacy/images/brand/logo-light.svg
similarity index 100%
rename from images/brand/logo-light.svg
rename to legacy/images/brand/logo-light.svg
diff --git a/images/brand/logotype-dark.svg b/legacy/images/brand/logotype-dark.svg
similarity index 100%
rename from images/brand/logotype-dark.svg
rename to legacy/images/brand/logotype-dark.svg
diff --git a/images/brand/logotype-light.svg b/legacy/images/brand/logotype-light.svg
similarity index 100%
rename from images/brand/logotype-light.svg
rename to legacy/images/brand/logotype-light.svg
diff --git a/images/clustering.png b/legacy/images/clustering.png
similarity index 100%
rename from images/clustering.png
rename to legacy/images/clustering.png
diff --git a/images/copy-btn.svg b/legacy/images/copy-btn.svg
similarity index 100%
rename from images/copy-btn.svg
rename to legacy/images/copy-btn.svg
diff --git a/images/express-mw.png b/legacy/images/express-mw.png
similarity index 100%
rename from images/express-mw.png
rename to legacy/images/express-mw.png
diff --git a/images/favicon.ico b/legacy/images/favicon.ico
similarity index 100%
rename from images/favicon.ico
rename to legacy/images/favicon.ico
diff --git a/images/favicon.png b/legacy/images/favicon.png
similarity index 100%
rename from images/favicon.png
rename to legacy/images/favicon.png
diff --git a/images/og.png b/legacy/images/og.png
similarity index 100%
rename from images/og.png
rename to legacy/images/og.png
diff --git a/index.md b/legacy/index.md
similarity index 100%
rename from index.md
rename to legacy/index.md
diff --git a/it/3x/api.md b/legacy/it/3x/api.md
similarity index 100%
rename from it/3x/api.md
rename to legacy/it/3x/api.md
diff --git a/it/4x/api.md b/legacy/it/4x/api.md
similarity index 100%
rename from it/4x/api.md
rename to legacy/it/4x/api.md
diff --git a/it/5x/api.md b/legacy/it/5x/api.md
similarity index 100%
rename from it/5x/api.md
rename to legacy/it/5x/api.md
diff --git a/it/advanced/best-practice-performance.md b/legacy/it/advanced/best-practice-performance.md
similarity index 100%
rename from it/advanced/best-practice-performance.md
rename to legacy/it/advanced/best-practice-performance.md
diff --git a/it/advanced/best-practice-security.md b/legacy/it/advanced/best-practice-security.md
similarity index 100%
rename from it/advanced/best-practice-security.md
rename to legacy/it/advanced/best-practice-security.md
diff --git a/it/advanced/developing-template-engines.md b/legacy/it/advanced/developing-template-engines.md
similarity index 100%
rename from it/advanced/developing-template-engines.md
rename to legacy/it/advanced/developing-template-engines.md
diff --git a/it/advanced/healthcheck-graceful-shutdown.md b/legacy/it/advanced/healthcheck-graceful-shutdown.md
similarity index 100%
rename from it/advanced/healthcheck-graceful-shutdown.md
rename to legacy/it/advanced/healthcheck-graceful-shutdown.md
diff --git a/it/advanced/security-updates.md b/legacy/it/advanced/security-updates.md
similarity index 100%
rename from it/advanced/security-updates.md
rename to legacy/it/advanced/security-updates.md
diff --git a/it/api.md b/legacy/it/api.md
similarity index 100%
rename from it/api.md
rename to legacy/it/api.md
diff --git a/it/changelog/index.md b/legacy/it/changelog/index.md
similarity index 100%
rename from it/changelog/index.md
rename to legacy/it/changelog/index.md
diff --git a/it/guide/behind-proxies.md b/legacy/it/guide/behind-proxies.md
similarity index 100%
rename from it/guide/behind-proxies.md
rename to legacy/it/guide/behind-proxies.md
diff --git a/it/guide/database-integration.md b/legacy/it/guide/database-integration.md
similarity index 100%
rename from it/guide/database-integration.md
rename to legacy/it/guide/database-integration.md
diff --git a/it/guide/debugging.md b/legacy/it/guide/debugging.md
similarity index 100%
rename from it/guide/debugging.md
rename to legacy/it/guide/debugging.md
diff --git a/it/guide/error-handling.md b/legacy/it/guide/error-handling.md
similarity index 100%
rename from it/guide/error-handling.md
rename to legacy/it/guide/error-handling.md
diff --git a/it/guide/migrating-4.md b/legacy/it/guide/migrating-4.md
similarity index 100%
rename from it/guide/migrating-4.md
rename to legacy/it/guide/migrating-4.md
diff --git a/it/guide/migrating-5.md b/legacy/it/guide/migrating-5.md
similarity index 86%
rename from it/guide/migrating-5.md
rename to legacy/it/guide/migrating-5.md
index 40d09e379f..91eef72d1f 100644
--- a/it/guide/migrating-5.md
+++ b/legacy/it/guide/migrating-5.md
@@ -99,7 +99,7 @@ Inizialmente era stato utilizzato il comando `del` al posto di `delete`, perché
{% capture codemod-deprecated-signatures %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod v4-deprecated-signatures
```
@@ -109,14 +109,14 @@ npx @expressjs/codemod v4-deprecated-signatures
```js
// v4
-app.del('/user/:id', (req, res) => {
- res.send(`DELETE /user/${req.params.id}`)
-})
+app.del("/user/:id", (req, res) => {
+ res.send(`DELETE /user/${req.params.id}`);
+});
// v5
-app.delete('/user/:id', (req, res) => {
- res.send(`DELETE /user/${req.params.id}`)
-})
+app.delete("/user/:id", (req, res) => {
+ res.send(`DELETE /user/${req.params.id}`);
+});
```
app.param(fn)
@@ -136,7 +136,7 @@ I seguenti nomi di metodi sono stati messi al plurale. In Express 4, l'utilizzo
{% capture codemod-pluralized-methods %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod pluralized-methods
```
@@ -146,22 +146,22 @@ npx @expressjs/codemod pluralized-methods
```js
// v4
-app.all('/', (req, res) => {
- req.acceptsCharset('utf-8')
- req.acceptsEncoding('br')
- req.acceptsLanguage('en')
+app.all("/", (req, res) => {
+ req.acceptsCharset("utf-8");
+ req.acceptsEncoding("br");
+ req.acceptsLanguage("en");
// ...
-})
+});
// v5
-app.all('/', (req, res) => {
- req.acceptsCharsets('utf-8')
- req.acceptsEncodings('br')
- req.acceptsLanguages('en')
+app.all("/", (req, res) => {
+ req.acceptsCharsets("utf-8");
+ req.acceptsEncodings("br");
+ req.acceptsLanguages("en");
// ...
-})
+});
```
Due punti (:) nel nome per app.param(name, fn)
@@ -177,7 +177,7 @@ Questo metodo poco chiaro e molto pericoloso che si utilizzava per richiamare i
{% capture codemod-req-param %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod req-param
```
@@ -187,22 +187,22 @@ npx @expressjs/codemod req-param
```js
// v4
-app.post('/user', (req, res) => {
- const id = req.param('id')
- const body = req.param('body')
- const query = req.param('query')
+app.post("/user", (req, res) => {
+ const id = req.param("id");
+ const body = req.param("body");
+ const query = req.param("query");
// ...
-})
+});
// v5
-app.post('/user', (req, res) => {
- const id = req.params.id
- const body = req.body
- const query = req.query
+app.post("/user", (req, res) => {
+ const id = req.params.id;
+ const body = req.body;
+ const query = req.query;
// ...
-})
+});
```
res.json(obj, status)
@@ -213,14 +213,14 @@ Express 5 non supporta più la firma `res.json(obj, status)`. Al contrario, impo
```js
// v4
-app.post('/user', (req, res) => {
- res.json({ name: 'Ruben' }, 201)
-})
+app.post("/user", (req, res) => {
+ res.json({ name: "Ruben" }, 201);
+});
// v5
-app.post('/user', (req, res) => {
- res.status(201).json({ name: 'Ruben' })
-})
+app.post("/user", (req, res) => {
+ res.status(201).json({ name: "Ruben" });
+});
```
res.jsonp(obj, status)
@@ -231,14 +231,14 @@ Express 5 non supporta più la firma `res.jsonp(obj, status)`. Al contrario, imp
```js
// v4
-app.post('/user', (req, res) => {
- res.jsonp({ name: 'Ruben' }, 201)
-})
+app.post("/user", (req, res) => {
+ res.jsonp({ name: "Ruben" }, 201);
+});
// v5
-app.post('/user', (req, res) => {
- res.status(201).jsonp({ name: 'Ruben' })
-})
+app.post("/user", (req, res) => {
+ res.status(201).jsonp({ name: "Ruben" });
+});
```
res.redirect(url, status)
@@ -249,14 +249,14 @@ Express 5 non supporta più la firma `res.send(obj, status)`. Al contrario, impo
```js
// v4
-app.get('/user', (req, res) => {
- res.redirect('/users', 301)
-})
+app.get("/user", (req, res) => {
+ res.redirect("/users", 301);
+});
// v5
-app.get('/user', (req, res) => {
- res.redirect(301, '/users')
-})
+app.get("/user", (req, res) => {
+ res.redirect(301, "/users");
+});
```
res.redirect('back') and res.location('back')
@@ -266,7 +266,7 @@ Express 5 no longer supports the magic string `back` in the `res.redirect()` and
{% capture codemod-magic-redirect %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod magic-redirect
```
@@ -276,14 +276,14 @@ npx @expressjs/codemod magic-redirect
```js
// v4
-app.get('/user', (req, res) => {
- res.redirect('back')
-})
+app.get("/user", (req, res) => {
+ res.redirect("back");
+});
// v5
-app.get('/user', (req, res) => {
- res.redirect(req.get('Referrer') || '/')
-})
+app.get("/user", (req, res) => {
+ res.redirect(req.get("Referrer") || "/");
+});
```
res.send(body, status)
@@ -294,14 +294,14 @@ Express 5 no longer supports the signature `res.send(obj, status)`. Instead, set
```js
// v4
-app.get('/user', (req, res) => {
- res.send({ name: 'Ruben' }, 200)
-})
+app.get("/user", (req, res) => {
+ res.send({ name: "Ruben" }, 200);
+});
// v5
-app.get('/user', (req, res) => {
- res.status(200).send({ name: 'Ruben' })
-})
+app.get("/user", (req, res) => {
+ res.status(200).send({ name: "Ruben" });
+});
```
res.send(status)
@@ -313,14 +313,14 @@ Se è necessario inviare un numero utilizzando la funzione `res.send()`, citare
```js
// v4
-app.get('/user', (req, res) => {
- res.send(200)
-})
+app.get("/user", (req, res) => {
+ res.send(200);
+});
// v5
-app.get('/user', (req, res) => {
- res.sendStatus(200)
-})
+app.get("/user", (req, res) => {
+ res.sendStatus(200);
+});
```
res.sendfile()
@@ -340,14 +340,14 @@ La funzione `res.sendfile()` è stata sostituita da una versione in cui ogni fra
```js
// v4
-app.get('/user', (req, res) => {
- res.sendfile('/path/to/file')
-})
+app.get("/user", (req, res) => {
+ res.sendfile("/path/to/file");
+});
// v5
-app.get('/user', (req, res) => {
- res.sendFile('/path/to/file')
-})
+app.get("/user", (req, res) => {
+ res.sendFile("/path/to/file");
+});
```
router.param(fn)
@@ -370,11 +370,11 @@ Use the [`mime-types` package](https://github.com/jshttp/mime-types) to work wit
```js
// v4
-express.static.mime.lookup('json')
+express.static.mime.lookup("json");
// v5
-const mime = require('mime-types')
-mime.lookup('json')
+const mime = require("mime-types");
+mime.lookup("json");
```
express:router debug logs
@@ -406,14 +406,14 @@ Path route matching syntax is when a string is supplied as the first parameter t
```js
// v4
-app.get('/*', async (req, res) => {
- res.send('ok')
-})
+app.get("/*", async (req, res) => {
+ res.send("ok");
+});
// v5
-app.get('/*splat', async (req, res) => {
- res.send('ok')
-})
+app.get("/*splat", async (req, res) => {
+ res.send("ok");
+});
```
{% capture note_wildcard %}
@@ -421,9 +421,9 @@ app.get('/*splat', async (req, res) => {
```js
// v5
-app.get('/{*splat}', async (req, res) => {
- res.send('ok')
-})
+app.get("/{*splat}", async (req, res) => {
+ res.send("ok");
+});
```
{% endcapture %}
@@ -433,30 +433,30 @@ app.get('/{*splat}', async (req, res) => {
```js
// v4
-app.get('/:file.:ext?', async (req, res) => {
- res.send('ok')
-})
+app.get("/:file.:ext?", async (req, res) => {
+ res.send("ok");
+});
// v5
-app.get('/:file{.:ext}', async (req, res) => {
- res.send('ok')
-})
+app.get("/:file{.:ext}", async (req, res) => {
+ res.send("ok");
+});
```
- Regexp characters are not supported. Ad esempio:
```js
-app.get('/[discussion|page]/:slug', async (req, res) => {
- res.status(200).send('ok')
-})
+app.get("/[discussion|page]/:slug", async (req, res) => {
+ res.status(200).send("ok");
+});
```
should be changed to:
```js
-app.get(['/discussion/:slug', '/page/:slug'], async (req, res) => {
- res.status(200).send('ok')
-})
+app.get(["/discussion/:slug", "/page/:slug"], async (req, res) => {
+ res.status(200).send("ok");
+});
```
- Some characters have been reserved to avoid confusion during upgrade (`()[]?+!`), use `\` to escape them.
@@ -480,7 +480,7 @@ Example of breaking code:
```js
// v4
-app.use(express.static('public'))
+app.use(express.static("public"));
```
After migrating to Express 5, a request to `/.well-known/assetlinks.json` will result in a **404 Not Found**.
@@ -489,8 +489,11 @@ To fix this, serve specific dot-directories explicitly using the `dotfiles: "all
```js
// v5
-app.use('/.well-known', express.static('public/.well-known', { dotfiles: 'allow' }))
-app.use(express.static('public'))
+app.use(
+ "/.well-known",
+ express.static("public/.well-known", { dotfiles: "allow" }),
+);
+app.use(express.static("public"));
```
This approach allows you to safely serve only the intended dot-directories while keeping the default secure behavior for other dotfiles, which remain inaccessible.
@@ -501,12 +504,12 @@ In Express 5, the `app.listen` method will invoke the user-provided callback fun
Ad esempio:
```js
-const server = app.listen(8080, '0.0.0.0', (error) => {
+const server = app.listen(8080, "0.0.0.0", (error) => {
if (error) {
- throw error // e.g. EADDRINUSE
+ throw error; // e.g. EADDRINUSE
}
- console.log(`Listening on ${JSON.stringify(server.address())}`)
-})
+ console.log(`Listening on ${JSON.stringify(server.address())}`);
+});
```
app.router
@@ -530,11 +533,11 @@ The `req.params` object now has a **null prototype** when using string paths. Ho
Wildcards (e.g., `/*splat`) capture path segments as an array instead of a single string.
```js
-app.get('/*splat', (req, res) => {
+app.get("/*splat", (req, res) => {
// GET /foo/bar
- console.dir(req.params)
+ console.dir(req.params);
// => [Object: null prototype] { splat: [ 'foo', 'bar' ] }
-})
+});
```
**Unmatched parameters are omitted:**
@@ -543,25 +546,25 @@ In Express 4, unmatched wildcards were empty strings (`''`) and optional `:` par
```js
// v4: unmatched wildcard is empty string
-app.get('/*', (req, res) => {
+app.get("/*", (req, res) => {
// GET /
- console.dir(req.params)
+ console.dir(req.params);
// => { '0': '' }
-})
+});
// v4: unmatched optional param is undefined
-app.get('/:file.:ext?', (req, res) => {
+app.get("/:file.:ext?", (req, res) => {
// GET /image
- console.dir(req.params)
+ console.dir(req.params);
// => { file: 'image', ext: undefined }
-})
+});
// v5: unmatched optional param is omitted
-app.get('/:file{.:ext}', (req, res) => {
+app.get("/:file{.:ext}", (req, res) => {
// GET /image
- console.dir(req.params)
+ console.dir(req.params);
// => [Object: null prototype] { file: 'image' }
-})
+});
```
req.query
diff --git a/it/guide/overriding-express-api.md b/legacy/it/guide/overriding-express-api.md
similarity index 100%
rename from it/guide/overriding-express-api.md
rename to legacy/it/guide/overriding-express-api.md
diff --git a/it/guide/routing.md b/legacy/it/guide/routing.md
similarity index 100%
rename from it/guide/routing.md
rename to legacy/it/guide/routing.md
diff --git a/it/guide/using-middleware.md b/legacy/it/guide/using-middleware.md
similarity index 100%
rename from it/guide/using-middleware.md
rename to legacy/it/guide/using-middleware.md
diff --git a/it/guide/using-template-engines.md b/legacy/it/guide/using-template-engines.md
similarity index 100%
rename from it/guide/using-template-engines.md
rename to legacy/it/guide/using-template-engines.md
diff --git a/it/guide/writing-middleware.md b/legacy/it/guide/writing-middleware.md
similarity index 100%
rename from it/guide/writing-middleware.md
rename to legacy/it/guide/writing-middleware.md
diff --git a/it/index.md b/legacy/it/index.md
similarity index 100%
rename from it/index.md
rename to legacy/it/index.md
diff --git a/it/resources/community.md b/legacy/it/resources/community.md
similarity index 100%
rename from it/resources/community.md
rename to legacy/it/resources/community.md
diff --git a/it/resources/contributing.md b/legacy/it/resources/contributing.md
similarity index 100%
rename from it/resources/contributing.md
rename to legacy/it/resources/contributing.md
diff --git a/it/resources/glossary.md b/legacy/it/resources/glossary.md
similarity index 100%
rename from it/resources/glossary.md
rename to legacy/it/resources/glossary.md
diff --git a/it/resources/middleware.md b/legacy/it/resources/middleware.md
similarity index 100%
rename from it/resources/middleware.md
rename to legacy/it/resources/middleware.md
diff --git a/it/resources/middleware/body-parser.md b/legacy/it/resources/middleware/body-parser.md
similarity index 100%
rename from it/resources/middleware/body-parser.md
rename to legacy/it/resources/middleware/body-parser.md
diff --git a/it/resources/middleware/compression.md b/legacy/it/resources/middleware/compression.md
similarity index 100%
rename from it/resources/middleware/compression.md
rename to legacy/it/resources/middleware/compression.md
diff --git a/it/resources/middleware/connect-rid.md b/legacy/it/resources/middleware/connect-rid.md
similarity index 100%
rename from it/resources/middleware/connect-rid.md
rename to legacy/it/resources/middleware/connect-rid.md
diff --git a/it/resources/middleware/cookie-parser.md b/legacy/it/resources/middleware/cookie-parser.md
similarity index 100%
rename from it/resources/middleware/cookie-parser.md
rename to legacy/it/resources/middleware/cookie-parser.md
diff --git a/it/resources/middleware/cookie-session.md b/legacy/it/resources/middleware/cookie-session.md
similarity index 100%
rename from it/resources/middleware/cookie-session.md
rename to legacy/it/resources/middleware/cookie-session.md
diff --git a/it/resources/middleware/cors.md b/legacy/it/resources/middleware/cors.md
similarity index 100%
rename from it/resources/middleware/cors.md
rename to legacy/it/resources/middleware/cors.md
diff --git a/it/resources/middleware/errorhandler.md b/legacy/it/resources/middleware/errorhandler.md
similarity index 100%
rename from it/resources/middleware/errorhandler.md
rename to legacy/it/resources/middleware/errorhandler.md
diff --git a/it/resources/middleware/method-override.md b/legacy/it/resources/middleware/method-override.md
similarity index 100%
rename from it/resources/middleware/method-override.md
rename to legacy/it/resources/middleware/method-override.md
diff --git a/it/resources/middleware/morgan.md b/legacy/it/resources/middleware/morgan.md
similarity index 100%
rename from it/resources/middleware/morgan.md
rename to legacy/it/resources/middleware/morgan.md
diff --git a/it/resources/middleware/multer.md b/legacy/it/resources/middleware/multer.md
similarity index 100%
rename from it/resources/middleware/multer.md
rename to legacy/it/resources/middleware/multer.md
diff --git a/it/resources/middleware/response-time.md b/legacy/it/resources/middleware/response-time.md
similarity index 100%
rename from it/resources/middleware/response-time.md
rename to legacy/it/resources/middleware/response-time.md
diff --git a/it/resources/middleware/serve-favicon.md b/legacy/it/resources/middleware/serve-favicon.md
similarity index 100%
rename from it/resources/middleware/serve-favicon.md
rename to legacy/it/resources/middleware/serve-favicon.md
diff --git a/it/resources/middleware/serve-index.md b/legacy/it/resources/middleware/serve-index.md
similarity index 100%
rename from it/resources/middleware/serve-index.md
rename to legacy/it/resources/middleware/serve-index.md
diff --git a/it/resources/middleware/serve-static.md b/legacy/it/resources/middleware/serve-static.md
similarity index 100%
rename from it/resources/middleware/serve-static.md
rename to legacy/it/resources/middleware/serve-static.md
diff --git a/it/resources/middleware/session.md b/legacy/it/resources/middleware/session.md
similarity index 100%
rename from it/resources/middleware/session.md
rename to legacy/it/resources/middleware/session.md
diff --git a/it/resources/middleware/timeout.md b/legacy/it/resources/middleware/timeout.md
similarity index 100%
rename from it/resources/middleware/timeout.md
rename to legacy/it/resources/middleware/timeout.md
diff --git a/it/resources/middleware/vhost.md b/legacy/it/resources/middleware/vhost.md
similarity index 100%
rename from it/resources/middleware/vhost.md
rename to legacy/it/resources/middleware/vhost.md
diff --git a/it/resources/utils.md b/legacy/it/resources/utils.md
similarity index 100%
rename from it/resources/utils.md
rename to legacy/it/resources/utils.md
diff --git a/it/starter/basic-routing.md b/legacy/it/starter/basic-routing.md
similarity index 100%
rename from it/starter/basic-routing.md
rename to legacy/it/starter/basic-routing.md
diff --git a/it/starter/examples.md b/legacy/it/starter/examples.md
similarity index 100%
rename from it/starter/examples.md
rename to legacy/it/starter/examples.md
diff --git a/it/starter/faq.md b/legacy/it/starter/faq.md
similarity index 100%
rename from it/starter/faq.md
rename to legacy/it/starter/faq.md
diff --git a/it/starter/generator.md b/legacy/it/starter/generator.md
similarity index 100%
rename from it/starter/generator.md
rename to legacy/it/starter/generator.md
diff --git a/it/starter/hello-world.md b/legacy/it/starter/hello-world.md
similarity index 100%
rename from it/starter/hello-world.md
rename to legacy/it/starter/hello-world.md
diff --git a/it/starter/installing.md b/legacy/it/starter/installing.md
similarity index 100%
rename from it/starter/installing.md
rename to legacy/it/starter/installing.md
diff --git a/it/starter/static-files.md b/legacy/it/starter/static-files.md
similarity index 100%
rename from it/starter/static-files.md
rename to legacy/it/starter/static-files.md
diff --git a/it/support/index.md b/legacy/it/support/index.md
similarity index 100%
rename from it/support/index.md
rename to legacy/it/support/index.md
diff --git a/ja/3x/api.md b/legacy/ja/3x/api.md
similarity index 100%
rename from ja/3x/api.md
rename to legacy/ja/3x/api.md
diff --git a/ja/4x/api.md b/legacy/ja/4x/api.md
similarity index 100%
rename from ja/4x/api.md
rename to legacy/ja/4x/api.md
diff --git a/ja/5x/api.md b/legacy/ja/5x/api.md
similarity index 100%
rename from ja/5x/api.md
rename to legacy/ja/5x/api.md
diff --git a/ja/advanced/best-practice-performance.md b/legacy/ja/advanced/best-practice-performance.md
similarity index 100%
rename from ja/advanced/best-practice-performance.md
rename to legacy/ja/advanced/best-practice-performance.md
diff --git a/ja/advanced/best-practice-security.md b/legacy/ja/advanced/best-practice-security.md
similarity index 100%
rename from ja/advanced/best-practice-security.md
rename to legacy/ja/advanced/best-practice-security.md
diff --git a/ja/advanced/developing-template-engines.md b/legacy/ja/advanced/developing-template-engines.md
similarity index 100%
rename from ja/advanced/developing-template-engines.md
rename to legacy/ja/advanced/developing-template-engines.md
diff --git a/ja/advanced/healthcheck-graceful-shutdown.md b/legacy/ja/advanced/healthcheck-graceful-shutdown.md
similarity index 100%
rename from ja/advanced/healthcheck-graceful-shutdown.md
rename to legacy/ja/advanced/healthcheck-graceful-shutdown.md
diff --git a/ja/advanced/security-updates.md b/legacy/ja/advanced/security-updates.md
similarity index 100%
rename from ja/advanced/security-updates.md
rename to legacy/ja/advanced/security-updates.md
diff --git a/ja/api.md b/legacy/ja/api.md
similarity index 100%
rename from ja/api.md
rename to legacy/ja/api.md
diff --git a/ja/changelog/index.md b/legacy/ja/changelog/index.md
similarity index 100%
rename from ja/changelog/index.md
rename to legacy/ja/changelog/index.md
diff --git a/ja/guide/behind-proxies.md b/legacy/ja/guide/behind-proxies.md
similarity index 100%
rename from ja/guide/behind-proxies.md
rename to legacy/ja/guide/behind-proxies.md
diff --git a/ja/guide/database-integration.md b/legacy/ja/guide/database-integration.md
similarity index 100%
rename from ja/guide/database-integration.md
rename to legacy/ja/guide/database-integration.md
diff --git a/ja/guide/debugging.md b/legacy/ja/guide/debugging.md
similarity index 100%
rename from ja/guide/debugging.md
rename to legacy/ja/guide/debugging.md
diff --git a/ja/guide/error-handling.md b/legacy/ja/guide/error-handling.md
similarity index 100%
rename from ja/guide/error-handling.md
rename to legacy/ja/guide/error-handling.md
diff --git a/ja/guide/migrating-4.md b/legacy/ja/guide/migrating-4.md
similarity index 100%
rename from ja/guide/migrating-4.md
rename to legacy/ja/guide/migrating-4.md
diff --git a/ja/guide/migrating-5.md b/legacy/ja/guide/migrating-5.md
similarity index 87%
rename from ja/guide/migrating-5.md
rename to legacy/ja/guide/migrating-5.md
index 21b7e81bcf..d60ff7df77 100644
--- a/ja/guide/migrating-5.md
+++ b/legacy/ja/guide/migrating-5.md
@@ -99,7 +99,7 @@ Express 5 は、`app.del()` 関数をサポートしなくなりました。こ
{% capture codemod-deprecated-signatures %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod v4-deprecated-signatures
```
@@ -109,14 +109,14 @@ npx @expressjs/codemod v4-deprecated-signatures
```js
// v4
-app.del('/user/:id', (req, res) => {
- res.send(`DELETE /user/${req.params.id}`)
-})
+app.del("/user/:id", (req, res) => {
+ res.send(`DELETE /user/${req.params.id}`);
+});
// v5
-app.delete('/user/:id', (req, res) => {
- res.send(`DELETE /user/${req.params.id}`)
-})
+app.delete("/user/:id", (req, res) => {
+ res.send(`DELETE /user/${req.params.id}`);
+});
```
app.param(fn)
@@ -136,7 +136,7 @@ The following method names have been pluralized. In Express 4, using the old met
{% capture codemod-pluralized-methods %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod pluralized-methods
```
@@ -146,22 +146,22 @@ npx @expressjs/codemod pluralized-methods
```js
// v4
-app.all('/', (req, res) => {
- req.acceptsCharset('utf-8')
- req.acceptsEncoding('br')
- req.acceptsLanguage('en')
+app.all("/", (req, res) => {
+ req.acceptsCharset("utf-8");
+ req.acceptsEncoding("br");
+ req.acceptsLanguage("en");
// ...
-})
+});
// v5
-app.all('/', (req, res) => {
- req.acceptsCharsets('utf-8')
- req.acceptsEncodings('br')
- req.acceptsLanguages('en')
+app.all("/", (req, res) => {
+ req.acceptsCharsets("utf-8");
+ req.acceptsEncodings("br");
+ req.acceptsLanguages("en");
// ...
-})
+});
```
app.param(name, fn) の name の先頭コロン (:)
@@ -177,7 +177,7 @@ This potentially confusing and dangerous method of retrieving form data has been
{% capture codemod-req-param %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod req-param
```
@@ -187,22 +187,22 @@ npx @expressjs/codemod req-param
```js
// v4
-app.post('/user', (req, res) => {
- const id = req.param('id')
- const body = req.param('body')
- const query = req.param('query')
+app.post("/user", (req, res) => {
+ const id = req.param("id");
+ const body = req.param("body");
+ const query = req.param("query");
// ...
-})
+});
// v5
-app.post('/user', (req, res) => {
- const id = req.params.id
- const body = req.body
- const query = req.query
+app.post("/user", (req, res) => {
+ const id = req.params.id;
+ const body = req.body;
+ const query = req.query;
// ...
-})
+});
```
res.json(obj, status)
@@ -213,14 +213,14 @@ Express 5 は、シグニチャー `res.json(obj, status)` をサポートしな
```js
// v4
-app.post('/user', (req, res) => {
- res.json({ name: 'Ruben' }, 201)
-})
+app.post("/user", (req, res) => {
+ res.json({ name: "Ruben" }, 201);
+});
// v5
-app.post('/user', (req, res) => {
- res.status(201).json({ name: 'Ruben' })
-})
+app.post("/user", (req, res) => {
+ res.status(201).json({ name: "Ruben" });
+});
```
res.jsonp(obj, status)
@@ -231,14 +231,14 @@ Express 5 は、シグニチャー `res.jsonp(obj, status)` をサポートし
```js
// v4
-app.post('/user', (req, res) => {
- res.jsonp({ name: 'Ruben' }, 201)
-})
+app.post("/user", (req, res) => {
+ res.jsonp({ name: "Ruben" }, 201);
+});
// v5
-app.post('/user', (req, res) => {
- res.status(201).jsonp({ name: 'Ruben' })
-})
+app.post("/user", (req, res) => {
+ res.status(201).jsonp({ name: "Ruben" });
+});
```
res.redirect(url, status)
@@ -249,14 +249,14 @@ Express 5 no longer supports the signature `res.redirect(url, status)`. Instead,
```js
// v4
-app.get('/user', (req, res) => {
- res.redirect('/users', 301)
-})
+app.get("/user", (req, res) => {
+ res.redirect("/users", 301);
+});
// v5
-app.get('/user', (req, res) => {
- res.redirect(301, '/users')
-})
+app.get("/user", (req, res) => {
+ res.redirect(301, "/users");
+});
```
res.redirect('back') and res.location('back')
@@ -266,7 +266,7 @@ Express 5 no longer supports the magic string `back` in the `res.redirect()` and
{% capture codemod-magic-redirect %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod magic-redirect
```
@@ -276,14 +276,14 @@ npx @expressjs/codemod magic-redirect
```js
// v4
-app.get('/user', (req, res) => {
- res.redirect('back')
-})
+app.get("/user", (req, res) => {
+ res.redirect("back");
+});
// v5
-app.get('/user', (req, res) => {
- res.redirect(req.get('Referrer') || '/')
-})
+app.get("/user", (req, res) => {
+ res.redirect(req.get("Referrer") || "/");
+});
```
res.send(body, status)
@@ -294,14 +294,14 @@ Express 5 は、シグニチャー `res.send(obj, status)` をサポートしな
```js
// v4
-app.get('/user', (req, res) => {
- res.send({ name: 'Ruben' }, 200)
-})
+app.get("/user", (req, res) => {
+ res.send({ name: "Ruben" }, 200);
+});
// v5
-app.get('/user', (req, res) => {
- res.status(200).send({ name: 'Ruben' })
-})
+app.get("/user", (req, res) => {
+ res.status(200).send({ name: "Ruben" });
+});
```
res.send(status)
@@ -313,14 +313,14 @@ If you need to send a number by using the `res.send()` function, quote the numbe
```js
// v4
-app.get('/user', (req, res) => {
- res.send(200)
-})
+app.get("/user", (req, res) => {
+ res.send(200);
+});
// v5
-app.get('/user', (req, res) => {
- res.sendStatus(200)
-})
+app.get("/user", (req, res) => {
+ res.sendStatus(200);
+});
```
res.sendfile()
@@ -340,14 +340,14 @@ app.get('/user', (req, res) => {
```js
// v4
-app.get('/user', (req, res) => {
- res.sendfile('/path/to/file')
-})
+app.get("/user", (req, res) => {
+ res.sendfile("/path/to/file");
+});
// v5
-app.get('/user', (req, res) => {
- res.sendFile('/path/to/file')
-})
+app.get("/user", (req, res) => {
+ res.sendFile("/path/to/file");
+});
```
router.param(fn)
@@ -370,11 +370,11 @@ Use the [`mime-types` package](https://github.com/jshttp/mime-types) to work wit
```js
// v4
-express.static.mime.lookup('json')
+express.static.mime.lookup("json");
// v5
-const mime = require('mime-types')
-mime.lookup('json')
+const mime = require("mime-types");
+mime.lookup("json");
```
express:router debug logs
@@ -406,14 +406,14 @@ Path route matching syntax is when a string is supplied as the first parameter t
```js
// v4
-app.get('/*', async (req, res) => {
- res.send('ok')
-})
+app.get("/*", async (req, res) => {
+ res.send("ok");
+});
// v5
-app.get('/*splat', async (req, res) => {
- res.send('ok')
-})
+app.get("/*splat", async (req, res) => {
+ res.send("ok");
+});
```
{% capture note_wildcard %}
@@ -421,9 +421,9 @@ app.get('/*splat', async (req, res) => {
```js
// v5
-app.get('/{*splat}', async (req, res) => {
- res.send('ok')
-})
+app.get("/{*splat}", async (req, res) => {
+ res.send("ok");
+});
```
{% endcapture %}
@@ -433,30 +433,30 @@ app.get('/{*splat}', async (req, res) => {
```js
// v4
-app.get('/:file.:ext?', async (req, res) => {
- res.send('ok')
-})
+app.get("/:file.:ext?", async (req, res) => {
+ res.send("ok");
+});
// v5
-app.get('/:file{.:ext}', async (req, res) => {
- res.send('ok')
-})
+app.get("/:file{.:ext}", async (req, res) => {
+ res.send("ok");
+});
```
- Regexp characters are not supported. For example:
```js
-app.get('/[discussion|page]/:slug', async (req, res) => {
- res.status(200).send('ok')
-})
+app.get("/[discussion|page]/:slug", async (req, res) => {
+ res.status(200).send("ok");
+});
```
should be changed to:
```js
-app.get(['/discussion/:slug', '/page/:slug'], async (req, res) => {
- res.status(200).send('ok')
-})
+app.get(["/discussion/:slug", "/page/:slug"], async (req, res) => {
+ res.status(200).send("ok");
+});
```
- Some characters have been reserved to avoid confusion during upgrade (`()[]?+!`), use `\` to escape them.
@@ -480,7 +480,7 @@ Example of breaking code:
```js
// v4
-app.use(express.static('public'))
+app.use(express.static("public"));
```
After migrating to Express 5, a request to `/.well-known/assetlinks.json` will result in a **404 Not Found**.
@@ -489,8 +489,11 @@ To fix this, serve specific dot-directories explicitly using the `dotfiles: "all
```js
// v5
-app.use('/.well-known', express.static('public/.well-known', { dotfiles: 'allow' }))
-app.use(express.static('public'))
+app.use(
+ "/.well-known",
+ express.static("public/.well-known", { dotfiles: "allow" }),
+);
+app.use(express.static("public"));
```
This approach allows you to safely serve only the intended dot-directories while keeping the default secure behavior for other dotfiles, which remain inaccessible.
@@ -501,12 +504,12 @@ In Express 5, the `app.listen` method will invoke the user-provided callback fun
For example:
```js
-const server = app.listen(8080, '0.0.0.0', (error) => {
+const server = app.listen(8080, "0.0.0.0", (error) => {
if (error) {
- throw error // e.g. EADDRINUSE
+ throw error; // e.g. EADDRINUSE
}
- console.log(`Listening on ${JSON.stringify(server.address())}`)
-})
+ console.log(`Listening on ${JSON.stringify(server.address())}`);
+});
```
app.router
@@ -530,11 +533,11 @@ The `req.params` object now has a **null prototype** when using string paths. Ho
Wildcards (e.g., `/*splat`) capture path segments as an array instead of a single string.
```js
-app.get('/*splat', (req, res) => {
+app.get("/*splat", (req, res) => {
// GET /foo/bar
- console.dir(req.params)
+ console.dir(req.params);
// => [Object: null prototype] { splat: [ 'foo', 'bar' ] }
-})
+});
```
**Unmatched parameters are omitted:**
@@ -543,25 +546,25 @@ In Express 4, unmatched wildcards were empty strings (`''`) and optional `:` par
```js
// v4: unmatched wildcard is empty string
-app.get('/*', (req, res) => {
+app.get("/*", (req, res) => {
// GET /
- console.dir(req.params)
+ console.dir(req.params);
// => { '0': '' }
-})
+});
// v4: unmatched optional param is undefined
-app.get('/:file.:ext?', (req, res) => {
+app.get("/:file.:ext?", (req, res) => {
// GET /image
- console.dir(req.params)
+ console.dir(req.params);
// => { file: 'image', ext: undefined }
-})
+});
// v5: unmatched optional param is omitted
-app.get('/:file{.:ext}', (req, res) => {
+app.get("/:file{.:ext}", (req, res) => {
// GET /image
- console.dir(req.params)
+ console.dir(req.params);
// => [Object: null prototype] { file: 'image' }
-})
+});
```
req.query
diff --git a/ja/guide/overriding-express-api.md b/legacy/ja/guide/overriding-express-api.md
similarity index 100%
rename from ja/guide/overriding-express-api.md
rename to legacy/ja/guide/overriding-express-api.md
diff --git a/ja/guide/routing.md b/legacy/ja/guide/routing.md
similarity index 100%
rename from ja/guide/routing.md
rename to legacy/ja/guide/routing.md
diff --git a/ja/guide/using-middleware.md b/legacy/ja/guide/using-middleware.md
similarity index 100%
rename from ja/guide/using-middleware.md
rename to legacy/ja/guide/using-middleware.md
diff --git a/ja/guide/using-template-engines.md b/legacy/ja/guide/using-template-engines.md
similarity index 100%
rename from ja/guide/using-template-engines.md
rename to legacy/ja/guide/using-template-engines.md
diff --git a/ja/guide/writing-middleware.md b/legacy/ja/guide/writing-middleware.md
similarity index 100%
rename from ja/guide/writing-middleware.md
rename to legacy/ja/guide/writing-middleware.md
diff --git a/ja/index.md b/legacy/ja/index.md
similarity index 100%
rename from ja/index.md
rename to legacy/ja/index.md
diff --git a/ja/resources/community.md b/legacy/ja/resources/community.md
similarity index 100%
rename from ja/resources/community.md
rename to legacy/ja/resources/community.md
diff --git a/ja/resources/contributing.md b/legacy/ja/resources/contributing.md
similarity index 100%
rename from ja/resources/contributing.md
rename to legacy/ja/resources/contributing.md
diff --git a/ja/resources/glossary.md b/legacy/ja/resources/glossary.md
similarity index 100%
rename from ja/resources/glossary.md
rename to legacy/ja/resources/glossary.md
diff --git a/ja/resources/middleware.md b/legacy/ja/resources/middleware.md
similarity index 100%
rename from ja/resources/middleware.md
rename to legacy/ja/resources/middleware.md
diff --git a/ja/resources/middleware/body-parser.md b/legacy/ja/resources/middleware/body-parser.md
similarity index 100%
rename from ja/resources/middleware/body-parser.md
rename to legacy/ja/resources/middleware/body-parser.md
diff --git a/ja/resources/middleware/compression.md b/legacy/ja/resources/middleware/compression.md
similarity index 100%
rename from ja/resources/middleware/compression.md
rename to legacy/ja/resources/middleware/compression.md
diff --git a/ja/resources/middleware/connect-rid.md b/legacy/ja/resources/middleware/connect-rid.md
similarity index 100%
rename from ja/resources/middleware/connect-rid.md
rename to legacy/ja/resources/middleware/connect-rid.md
diff --git a/ja/resources/middleware/cookie-parser.md b/legacy/ja/resources/middleware/cookie-parser.md
similarity index 100%
rename from ja/resources/middleware/cookie-parser.md
rename to legacy/ja/resources/middleware/cookie-parser.md
diff --git a/ja/resources/middleware/cookie-session.md b/legacy/ja/resources/middleware/cookie-session.md
similarity index 100%
rename from ja/resources/middleware/cookie-session.md
rename to legacy/ja/resources/middleware/cookie-session.md
diff --git a/ja/resources/middleware/cors.md b/legacy/ja/resources/middleware/cors.md
similarity index 100%
rename from ja/resources/middleware/cors.md
rename to legacy/ja/resources/middleware/cors.md
diff --git a/ja/resources/middleware/errorhandler.md b/legacy/ja/resources/middleware/errorhandler.md
similarity index 100%
rename from ja/resources/middleware/errorhandler.md
rename to legacy/ja/resources/middleware/errorhandler.md
diff --git a/ja/resources/middleware/method-override.md b/legacy/ja/resources/middleware/method-override.md
similarity index 100%
rename from ja/resources/middleware/method-override.md
rename to legacy/ja/resources/middleware/method-override.md
diff --git a/ja/resources/middleware/morgan.md b/legacy/ja/resources/middleware/morgan.md
similarity index 100%
rename from ja/resources/middleware/morgan.md
rename to legacy/ja/resources/middleware/morgan.md
diff --git a/ja/resources/middleware/multer.md b/legacy/ja/resources/middleware/multer.md
similarity index 100%
rename from ja/resources/middleware/multer.md
rename to legacy/ja/resources/middleware/multer.md
diff --git a/ja/resources/middleware/response-time.md b/legacy/ja/resources/middleware/response-time.md
similarity index 100%
rename from ja/resources/middleware/response-time.md
rename to legacy/ja/resources/middleware/response-time.md
diff --git a/ja/resources/middleware/serve-favicon.md b/legacy/ja/resources/middleware/serve-favicon.md
similarity index 100%
rename from ja/resources/middleware/serve-favicon.md
rename to legacy/ja/resources/middleware/serve-favicon.md
diff --git a/ja/resources/middleware/serve-index.md b/legacy/ja/resources/middleware/serve-index.md
similarity index 100%
rename from ja/resources/middleware/serve-index.md
rename to legacy/ja/resources/middleware/serve-index.md
diff --git a/ja/resources/middleware/serve-static.md b/legacy/ja/resources/middleware/serve-static.md
similarity index 100%
rename from ja/resources/middleware/serve-static.md
rename to legacy/ja/resources/middleware/serve-static.md
diff --git a/ja/resources/middleware/session.md b/legacy/ja/resources/middleware/session.md
similarity index 100%
rename from ja/resources/middleware/session.md
rename to legacy/ja/resources/middleware/session.md
diff --git a/ja/resources/middleware/timeout.md b/legacy/ja/resources/middleware/timeout.md
similarity index 100%
rename from ja/resources/middleware/timeout.md
rename to legacy/ja/resources/middleware/timeout.md
diff --git a/ja/resources/middleware/vhost.md b/legacy/ja/resources/middleware/vhost.md
similarity index 100%
rename from ja/resources/middleware/vhost.md
rename to legacy/ja/resources/middleware/vhost.md
diff --git a/ja/resources/utils.md b/legacy/ja/resources/utils.md
similarity index 100%
rename from ja/resources/utils.md
rename to legacy/ja/resources/utils.md
diff --git a/ja/starter/basic-routing.md b/legacy/ja/starter/basic-routing.md
similarity index 100%
rename from ja/starter/basic-routing.md
rename to legacy/ja/starter/basic-routing.md
diff --git a/ja/starter/examples.md b/legacy/ja/starter/examples.md
similarity index 100%
rename from ja/starter/examples.md
rename to legacy/ja/starter/examples.md
diff --git a/ja/starter/faq.md b/legacy/ja/starter/faq.md
similarity index 100%
rename from ja/starter/faq.md
rename to legacy/ja/starter/faq.md
diff --git a/ja/starter/generator.md b/legacy/ja/starter/generator.md
similarity index 100%
rename from ja/starter/generator.md
rename to legacy/ja/starter/generator.md
diff --git a/ja/starter/hello-world.md b/legacy/ja/starter/hello-world.md
similarity index 100%
rename from ja/starter/hello-world.md
rename to legacy/ja/starter/hello-world.md
diff --git a/ja/starter/installing.md b/legacy/ja/starter/installing.md
similarity index 100%
rename from ja/starter/installing.md
rename to legacy/ja/starter/installing.md
diff --git a/ja/starter/static-files.md b/legacy/ja/starter/static-files.md
similarity index 100%
rename from ja/starter/static-files.md
rename to legacy/ja/starter/static-files.md
diff --git a/ja/support/index.md b/legacy/ja/support/index.md
similarity index 100%
rename from ja/support/index.md
rename to legacy/ja/support/index.md
diff --git a/js/app.js b/legacy/js/app.js
similarity index 100%
rename from js/app.js
rename to legacy/js/app.js
diff --git a/js/copycode.js b/legacy/js/copycode.js
similarity index 100%
rename from js/copycode.js
rename to legacy/js/copycode.js
diff --git a/js/menu.js b/legacy/js/menu.js
similarity index 100%
rename from js/menu.js
rename to legacy/js/menu.js
diff --git a/js/theme.js b/legacy/js/theme.js
similarity index 100%
rename from js/theme.js
rename to legacy/js/theme.js
diff --git a/ko/3x/api.md b/legacy/ko/3x/api.md
similarity index 100%
rename from ko/3x/api.md
rename to legacy/ko/3x/api.md
diff --git a/ko/4x/api.md b/legacy/ko/4x/api.md
similarity index 100%
rename from ko/4x/api.md
rename to legacy/ko/4x/api.md
diff --git a/ko/5x/api.md b/legacy/ko/5x/api.md
similarity index 100%
rename from ko/5x/api.md
rename to legacy/ko/5x/api.md
diff --git a/ko/advanced/best-practice-performance.md b/legacy/ko/advanced/best-practice-performance.md
similarity index 100%
rename from ko/advanced/best-practice-performance.md
rename to legacy/ko/advanced/best-practice-performance.md
diff --git a/ko/advanced/best-practice-security.md b/legacy/ko/advanced/best-practice-security.md
similarity index 100%
rename from ko/advanced/best-practice-security.md
rename to legacy/ko/advanced/best-practice-security.md
diff --git a/ko/advanced/developing-template-engines.md b/legacy/ko/advanced/developing-template-engines.md
similarity index 100%
rename from ko/advanced/developing-template-engines.md
rename to legacy/ko/advanced/developing-template-engines.md
diff --git a/ko/advanced/healthcheck-graceful-shutdown.md b/legacy/ko/advanced/healthcheck-graceful-shutdown.md
similarity index 100%
rename from ko/advanced/healthcheck-graceful-shutdown.md
rename to legacy/ko/advanced/healthcheck-graceful-shutdown.md
diff --git a/ko/advanced/security-updates.md b/legacy/ko/advanced/security-updates.md
similarity index 100%
rename from ko/advanced/security-updates.md
rename to legacy/ko/advanced/security-updates.md
diff --git a/ko/api.md b/legacy/ko/api.md
similarity index 100%
rename from ko/api.md
rename to legacy/ko/api.md
diff --git a/ko/changelog/4x.md b/legacy/ko/changelog/4x.md
similarity index 100%
rename from ko/changelog/4x.md
rename to legacy/ko/changelog/4x.md
diff --git a/ko/changelog/index.md b/legacy/ko/changelog/index.md
similarity index 100%
rename from ko/changelog/index.md
rename to legacy/ko/changelog/index.md
diff --git a/ko/guide/behind-proxies.md b/legacy/ko/guide/behind-proxies.md
similarity index 100%
rename from ko/guide/behind-proxies.md
rename to legacy/ko/guide/behind-proxies.md
diff --git a/ko/guide/database-integration.md b/legacy/ko/guide/database-integration.md
similarity index 100%
rename from ko/guide/database-integration.md
rename to legacy/ko/guide/database-integration.md
diff --git a/ko/guide/debugging.md b/legacy/ko/guide/debugging.md
similarity index 100%
rename from ko/guide/debugging.md
rename to legacy/ko/guide/debugging.md
diff --git a/ko/guide/error-handling.md b/legacy/ko/guide/error-handling.md
similarity index 100%
rename from ko/guide/error-handling.md
rename to legacy/ko/guide/error-handling.md
diff --git a/ko/guide/migrating-4.md b/legacy/ko/guide/migrating-4.md
similarity index 100%
rename from ko/guide/migrating-4.md
rename to legacy/ko/guide/migrating-4.md
diff --git a/ko/guide/migrating-5.md b/legacy/ko/guide/migrating-5.md
similarity index 87%
rename from ko/guide/migrating-5.md
rename to legacy/ko/guide/migrating-5.md
index fedcfe82ee..2d94712214 100644
--- a/ko/guide/migrating-5.md
+++ b/legacy/ko/guide/migrating-5.md
@@ -99,7 +99,7 @@ Express 5는 `app.del()` 함수를 더 이상 지원하지 않습니다. 이 함
{% capture codemod-deprecated-signatures %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod v4-deprecated-signatures
```
@@ -109,14 +109,14 @@ npx @expressjs/codemod v4-deprecated-signatures
```js
// v4
-app.del('/user/:id', (req, res) => {
- res.send(`DELETE /user/${req.params.id}`)
-})
+app.del("/user/:id", (req, res) => {
+ res.send(`DELETE /user/${req.params.id}`);
+});
// v5
-app.delete('/user/:id', (req, res) => {
- res.send(`DELETE /user/${req.params.id}`)
-})
+app.delete("/user/:id", (req, res) => {
+ res.send(`DELETE /user/${req.params.id}`);
+});
```
app.param(fn)
@@ -136,7 +136,7 @@ app.delete('/user/:id', (req, res) => {
{% capture codemod-pluralized-methods %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod pluralized-methods
```
@@ -146,22 +146,22 @@ npx @expressjs/codemod pluralized-methods
```js
// v4
-app.all('/', (req, res) => {
- req.acceptsCharset('utf-8')
- req.acceptsEncoding('br')
- req.acceptsLanguage('en')
+app.all("/", (req, res) => {
+ req.acceptsCharset("utf-8");
+ req.acceptsEncoding("br");
+ req.acceptsLanguage("en");
// ...
-})
+});
// v5
-app.all('/', (req, res) => {
- req.acceptsCharsets('utf-8')
- req.acceptsEncodings('br')
- req.acceptsLanguages('en')
+app.all("/", (req, res) => {
+ req.acceptsCharsets("utf-8");
+ req.acceptsEncodings("br");
+ req.acceptsLanguages("en");
// ...
-})
+});
```
app.param(name, fn)에 대한 이름(name)의 첫머리 콜론(:)
@@ -177,7 +177,7 @@ app.all('/', (req, res) => {
{% capture codemod-req-param %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod req-param
```
@@ -187,22 +187,22 @@ npx @expressjs/codemod req-param
```js
// v4
-app.post('/user', (req, res) => {
- const id = req.param('id')
- const body = req.param('body')
- const query = req.param('query')
+app.post("/user", (req, res) => {
+ const id = req.param("id");
+ const body = req.param("body");
+ const query = req.param("query");
// ...
-})
+});
// v5
-app.post('/user', (req, res) => {
- const id = req.params.id
- const body = req.body
- const query = req.query
+app.post("/user", (req, res) => {
+ const id = req.params.id;
+ const body = req.body;
+ const query = req.query;
// ...
-})
+});
```
res.json(obj, status)
@@ -213,14 +213,14 @@ Express 5는 `res.json(obj, status)` 시그니처를 더 이상 지원하지 않
```js
// v4
-app.post('/user', (req, res) => {
- res.json({ name: 'Ruben' }, 201)
-})
+app.post("/user", (req, res) => {
+ res.json({ name: "Ruben" }, 201);
+});
// v5
-app.post('/user', (req, res) => {
- res.status(201).json({ name: 'Ruben' })
-})
+app.post("/user", (req, res) => {
+ res.status(201).json({ name: "Ruben" });
+});
```
res.jsonp(obj, status)
@@ -231,14 +231,14 @@ Express 5는 `res.jsonp(obj, status)` 시그니처를 더 이상 지원하지
```js
// v4
-app.post('/user', (req, res) => {
- res.jsonp({ name: 'Ruben' }, 201)
-})
+app.post("/user", (req, res) => {
+ res.jsonp({ name: "Ruben" }, 201);
+});
// v5
-app.post('/user', (req, res) => {
- res.status(201).jsonp({ name: 'Ruben' })
-})
+app.post("/user", (req, res) => {
+ res.status(201).jsonp({ name: "Ruben" });
+});
```
res.redirect(url, status)
@@ -249,14 +249,14 @@ Express 5는 `res.send(obj, status)` 시그니처를 더 이상 지원하지 않
```js
// v4
-app.get('/user', (req, res) => {
- res.redirect('/users', 301)
-})
+app.get("/user", (req, res) => {
+ res.redirect("/users", 301);
+});
// v5
-app.get('/user', (req, res) => {
- res.redirect(301, '/users')
-})
+app.get("/user", (req, res) => {
+ res.redirect(301, "/users");
+});
```
res.redirect('back') and res.location('back')
@@ -266,7 +266,7 @@ Express 5 no longer supports the magic string `back` in the `res.redirect()` and
{% capture codemod-magic-redirect %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod magic-redirect
```
@@ -276,14 +276,14 @@ npx @expressjs/codemod magic-redirect
```js
// v4
-app.get('/user', (req, res) => {
- res.redirect('back')
-})
+app.get("/user", (req, res) => {
+ res.redirect("back");
+});
// v5
-app.get('/user', (req, res) => {
- res.redirect(req.get('Referrer') || '/')
-})
+app.get("/user", (req, res) => {
+ res.redirect(req.get("Referrer") || "/");
+});
```
res.send(body, status)
@@ -294,14 +294,14 @@ Express 5 no longer supports the signature `res.send(obj, status)`. Instead, set
```js
// v4
-app.get('/user', (req, res) => {
- res.send({ name: 'Ruben' }, 200)
-})
+app.get("/user", (req, res) => {
+ res.send({ name: "Ruben" }, 200);
+});
// v5
-app.get('/user', (req, res) => {
- res.status(200).send({ name: 'Ruben' })
-})
+app.get("/user", (req, res) => {
+ res.status(200).send({ name: "Ruben" });
+});
```
res.send(status)
@@ -313,14 +313,14 @@ Express 5는 \*`status`\*가 숫자인 res.send(status )
```js
// v4
-app.get('/user', (req, res) => {
- res.send(200)
-})
+app.get("/user", (req, res) => {
+ res.send(200);
+});
// v5
-app.get('/user', (req, res) => {
- res.sendStatus(200)
-})
+app.get("/user", (req, res) => {
+ res.sendStatus(200);
+});
```
res.sendfile()
@@ -340,14 +340,14 @@ Express 5에서 `res.sendfile()` 함수는 낙타 대문자(camel-cased) 버전
```js
// v4
-app.get('/user', (req, res) => {
- res.sendfile('/path/to/file')
-})
+app.get("/user", (req, res) => {
+ res.sendfile("/path/to/file");
+});
// v5
-app.get('/user', (req, res) => {
- res.sendFile('/path/to/file')
-})
+app.get("/user", (req, res) => {
+ res.sendFile("/path/to/file");
+});
```
router.param(fn)
@@ -370,11 +370,11 @@ Use the [`mime-types` package](https://github.com/jshttp/mime-types) to work wit
```js
// v4
-express.static.mime.lookup('json')
+express.static.mime.lookup("json");
// v5
-const mime = require('mime-types')
-mime.lookup('json')
+const mime = require("mime-types");
+mime.lookup("json");
```
express:router debug logs
@@ -406,14 +406,14 @@ Path route matching syntax is when a string is supplied as the first parameter t
```js
// v4
-app.get('/*', async (req, res) => {
- res.send('ok')
-})
+app.get("/*", async (req, res) => {
+ res.send("ok");
+});
// v5
-app.get('/*splat', async (req, res) => {
- res.send('ok')
-})
+app.get("/*splat", async (req, res) => {
+ res.send("ok");
+});
```
{% capture note_wildcard %}
@@ -421,9 +421,9 @@ app.get('/*splat', async (req, res) => {
```js
// v5
-app.get('/{*splat}', async (req, res) => {
- res.send('ok')
-})
+app.get("/{*splat}", async (req, res) => {
+ res.send("ok");
+});
```
{% endcapture %}
@@ -433,30 +433,30 @@ app.get('/{*splat}', async (req, res) => {
```js
// v4
-app.get('/:file.:ext?', async (req, res) => {
- res.send('ok')
-})
+app.get("/:file.:ext?", async (req, res) => {
+ res.send("ok");
+});
// v5
-app.get('/:file{.:ext}', async (req, res) => {
- res.send('ok')
-})
+app.get("/:file{.:ext}", async (req, res) => {
+ res.send("ok");
+});
```
- Regexp characters are not supported. 예를 들면 다음과 같습니다.
```js
-app.get('/[discussion|page]/:slug', async (req, res) => {
- res.status(200).send('ok')
-})
+app.get("/[discussion|page]/:slug", async (req, res) => {
+ res.status(200).send("ok");
+});
```
should be changed to:
```js
-app.get(['/discussion/:slug', '/page/:slug'], async (req, res) => {
- res.status(200).send('ok')
-})
+app.get(["/discussion/:slug", "/page/:slug"], async (req, res) => {
+ res.status(200).send("ok");
+});
```
- Some characters have been reserved to avoid confusion during upgrade (`()[]?+!`), use `\` to escape them.
@@ -480,7 +480,7 @@ Example of breaking code:
```js
// v4
-app.use(express.static('public'))
+app.use(express.static("public"));
```
After migrating to Express 5, a request to `/.well-known/assetlinks.json` will result in a **404 Not Found**.
@@ -489,8 +489,11 @@ To fix this, serve specific dot-directories explicitly using the `dotfiles: "all
```js
// v5
-app.use('/.well-known', express.static('public/.well-known', { dotfiles: 'allow' }))
-app.use(express.static('public'))
+app.use(
+ "/.well-known",
+ express.static("public/.well-known", { dotfiles: "allow" }),
+);
+app.use(express.static("public"));
```
This approach allows you to safely serve only the intended dot-directories while keeping the default secure behavior for other dotfiles, which remain inaccessible.
@@ -501,12 +504,12 @@ In Express 5, the `app.listen` method will invoke the user-provided callback fun
예를 들면 다음과 같습니다.
```js
-const server = app.listen(8080, '0.0.0.0', (error) => {
+const server = app.listen(8080, "0.0.0.0", (error) => {
if (error) {
- throw error // e.g. EADDRINUSE
+ throw error; // e.g. EADDRINUSE
}
- console.log(`Listening on ${JSON.stringify(server.address())}`)
-})
+ console.log(`Listening on ${JSON.stringify(server.address())}`);
+});
```
app.router
@@ -530,11 +533,11 @@ The `req.params` object now has a **null prototype** when using string paths. Ho
Wildcards (e.g., `/*splat`) capture path segments as an array instead of a single string.
```js
-app.get('/*splat', (req, res) => {
+app.get("/*splat", (req, res) => {
// GET /foo/bar
- console.dir(req.params)
+ console.dir(req.params);
// => [Object: null prototype] { splat: [ 'foo', 'bar' ] }
-})
+});
```
**Unmatched parameters are omitted:**
@@ -543,25 +546,25 @@ In Express 4, unmatched wildcards were empty strings (`''`) and optional `:` par
```js
// v4: unmatched wildcard is empty string
-app.get('/*', (req, res) => {
+app.get("/*", (req, res) => {
// GET /
- console.dir(req.params)
+ console.dir(req.params);
// => { '0': '' }
-})
+});
// v4: unmatched optional param is undefined
-app.get('/:file.:ext?', (req, res) => {
+app.get("/:file.:ext?", (req, res) => {
// GET /image
- console.dir(req.params)
+ console.dir(req.params);
// => { file: 'image', ext: undefined }
-})
+});
// v5: unmatched optional param is omitted
-app.get('/:file{.:ext}', (req, res) => {
+app.get("/:file{.:ext}", (req, res) => {
// GET /image
- console.dir(req.params)
+ console.dir(req.params);
// => [Object: null prototype] { file: 'image' }
-})
+});
```
req.query
diff --git a/ko/guide/overriding-express-api.md b/legacy/ko/guide/overriding-express-api.md
similarity index 100%
rename from ko/guide/overriding-express-api.md
rename to legacy/ko/guide/overriding-express-api.md
diff --git a/ko/guide/routing.md b/legacy/ko/guide/routing.md
similarity index 100%
rename from ko/guide/routing.md
rename to legacy/ko/guide/routing.md
diff --git a/ko/guide/using-middleware.md b/legacy/ko/guide/using-middleware.md
similarity index 100%
rename from ko/guide/using-middleware.md
rename to legacy/ko/guide/using-middleware.md
diff --git a/ko/guide/using-template-engines.md b/legacy/ko/guide/using-template-engines.md
similarity index 100%
rename from ko/guide/using-template-engines.md
rename to legacy/ko/guide/using-template-engines.md
diff --git a/ko/guide/writing-middleware.md b/legacy/ko/guide/writing-middleware.md
similarity index 100%
rename from ko/guide/writing-middleware.md
rename to legacy/ko/guide/writing-middleware.md
diff --git a/ko/index.md b/legacy/ko/index.md
similarity index 100%
rename from ko/index.md
rename to legacy/ko/index.md
diff --git a/ko/resources/community.md b/legacy/ko/resources/community.md
similarity index 100%
rename from ko/resources/community.md
rename to legacy/ko/resources/community.md
diff --git a/ko/resources/contributing.md b/legacy/ko/resources/contributing.md
similarity index 100%
rename from ko/resources/contributing.md
rename to legacy/ko/resources/contributing.md
diff --git a/ko/resources/glossary.md b/legacy/ko/resources/glossary.md
similarity index 100%
rename from ko/resources/glossary.md
rename to legacy/ko/resources/glossary.md
diff --git a/ko/resources/middleware.md b/legacy/ko/resources/middleware.md
similarity index 100%
rename from ko/resources/middleware.md
rename to legacy/ko/resources/middleware.md
diff --git a/ko/resources/middleware/body-parser.md b/legacy/ko/resources/middleware/body-parser.md
similarity index 100%
rename from ko/resources/middleware/body-parser.md
rename to legacy/ko/resources/middleware/body-parser.md
diff --git a/ko/resources/middleware/compression.md b/legacy/ko/resources/middleware/compression.md
similarity index 100%
rename from ko/resources/middleware/compression.md
rename to legacy/ko/resources/middleware/compression.md
diff --git a/ko/resources/middleware/connect-rid.md b/legacy/ko/resources/middleware/connect-rid.md
similarity index 100%
rename from ko/resources/middleware/connect-rid.md
rename to legacy/ko/resources/middleware/connect-rid.md
diff --git a/ko/resources/middleware/cookie-parser.md b/legacy/ko/resources/middleware/cookie-parser.md
similarity index 100%
rename from ko/resources/middleware/cookie-parser.md
rename to legacy/ko/resources/middleware/cookie-parser.md
diff --git a/ko/resources/middleware/cookie-session.md b/legacy/ko/resources/middleware/cookie-session.md
similarity index 100%
rename from ko/resources/middleware/cookie-session.md
rename to legacy/ko/resources/middleware/cookie-session.md
diff --git a/ko/resources/middleware/cors.md b/legacy/ko/resources/middleware/cors.md
similarity index 100%
rename from ko/resources/middleware/cors.md
rename to legacy/ko/resources/middleware/cors.md
diff --git a/ko/resources/middleware/errorhandler.md b/legacy/ko/resources/middleware/errorhandler.md
similarity index 100%
rename from ko/resources/middleware/errorhandler.md
rename to legacy/ko/resources/middleware/errorhandler.md
diff --git a/ko/resources/middleware/method-override.md b/legacy/ko/resources/middleware/method-override.md
similarity index 100%
rename from ko/resources/middleware/method-override.md
rename to legacy/ko/resources/middleware/method-override.md
diff --git a/ko/resources/middleware/morgan.md b/legacy/ko/resources/middleware/morgan.md
similarity index 100%
rename from ko/resources/middleware/morgan.md
rename to legacy/ko/resources/middleware/morgan.md
diff --git a/ko/resources/middleware/multer.md b/legacy/ko/resources/middleware/multer.md
similarity index 100%
rename from ko/resources/middleware/multer.md
rename to legacy/ko/resources/middleware/multer.md
diff --git a/ko/resources/middleware/response-time.md b/legacy/ko/resources/middleware/response-time.md
similarity index 100%
rename from ko/resources/middleware/response-time.md
rename to legacy/ko/resources/middleware/response-time.md
diff --git a/ko/resources/middleware/serve-favicon.md b/legacy/ko/resources/middleware/serve-favicon.md
similarity index 100%
rename from ko/resources/middleware/serve-favicon.md
rename to legacy/ko/resources/middleware/serve-favicon.md
diff --git a/ko/resources/middleware/serve-index.md b/legacy/ko/resources/middleware/serve-index.md
similarity index 100%
rename from ko/resources/middleware/serve-index.md
rename to legacy/ko/resources/middleware/serve-index.md
diff --git a/ko/resources/middleware/serve-static.md b/legacy/ko/resources/middleware/serve-static.md
similarity index 100%
rename from ko/resources/middleware/serve-static.md
rename to legacy/ko/resources/middleware/serve-static.md
diff --git a/ko/resources/middleware/session.md b/legacy/ko/resources/middleware/session.md
similarity index 100%
rename from ko/resources/middleware/session.md
rename to legacy/ko/resources/middleware/session.md
diff --git a/ko/resources/middleware/timeout.md b/legacy/ko/resources/middleware/timeout.md
similarity index 100%
rename from ko/resources/middleware/timeout.md
rename to legacy/ko/resources/middleware/timeout.md
diff --git a/ko/resources/middleware/vhost.md b/legacy/ko/resources/middleware/vhost.md
similarity index 100%
rename from ko/resources/middleware/vhost.md
rename to legacy/ko/resources/middleware/vhost.md
diff --git a/ko/resources/utils.md b/legacy/ko/resources/utils.md
similarity index 100%
rename from ko/resources/utils.md
rename to legacy/ko/resources/utils.md
diff --git a/ko/starter/basic-routing.md b/legacy/ko/starter/basic-routing.md
similarity index 100%
rename from ko/starter/basic-routing.md
rename to legacy/ko/starter/basic-routing.md
diff --git a/ko/starter/examples.md b/legacy/ko/starter/examples.md
similarity index 100%
rename from ko/starter/examples.md
rename to legacy/ko/starter/examples.md
diff --git a/ko/starter/faq.md b/legacy/ko/starter/faq.md
similarity index 100%
rename from ko/starter/faq.md
rename to legacy/ko/starter/faq.md
diff --git a/ko/starter/generator.md b/legacy/ko/starter/generator.md
similarity index 100%
rename from ko/starter/generator.md
rename to legacy/ko/starter/generator.md
diff --git a/ko/starter/hello-world.md b/legacy/ko/starter/hello-world.md
similarity index 100%
rename from ko/starter/hello-world.md
rename to legacy/ko/starter/hello-world.md
diff --git a/ko/starter/installing.md b/legacy/ko/starter/installing.md
similarity index 100%
rename from ko/starter/installing.md
rename to legacy/ko/starter/installing.md
diff --git a/ko/starter/static-files.md b/legacy/ko/starter/static-files.md
similarity index 100%
rename from ko/starter/static-files.md
rename to legacy/ko/starter/static-files.md
diff --git a/ko/support/index.md b/legacy/ko/support/index.md
similarity index 100%
rename from ko/support/index.md
rename to legacy/ko/support/index.md
diff --git a/package-lock.json b/legacy/package-lock.json
similarity index 100%
rename from package-lock.json
rename to legacy/package-lock.json
diff --git a/package.json b/legacy/package.json
similarity index 100%
rename from package.json
rename to legacy/package.json
diff --git a/pt-br/3x/api.md b/legacy/pt-br/3x/api.md
similarity index 100%
rename from pt-br/3x/api.md
rename to legacy/pt-br/3x/api.md
diff --git a/pt-br/4x/api.md b/legacy/pt-br/4x/api.md
similarity index 100%
rename from pt-br/4x/api.md
rename to legacy/pt-br/4x/api.md
diff --git a/pt-br/5x/api.md b/legacy/pt-br/5x/api.md
similarity index 100%
rename from pt-br/5x/api.md
rename to legacy/pt-br/5x/api.md
diff --git a/pt-br/advanced/best-practice-performance.md b/legacy/pt-br/advanced/best-practice-performance.md
similarity index 100%
rename from pt-br/advanced/best-practice-performance.md
rename to legacy/pt-br/advanced/best-practice-performance.md
diff --git a/pt-br/advanced/best-practice-security.md b/legacy/pt-br/advanced/best-practice-security.md
similarity index 100%
rename from pt-br/advanced/best-practice-security.md
rename to legacy/pt-br/advanced/best-practice-security.md
diff --git a/pt-br/advanced/developing-template-engines.md b/legacy/pt-br/advanced/developing-template-engines.md
similarity index 100%
rename from pt-br/advanced/developing-template-engines.md
rename to legacy/pt-br/advanced/developing-template-engines.md
diff --git a/pt-br/advanced/healthcheck-graceful-shutdown.md b/legacy/pt-br/advanced/healthcheck-graceful-shutdown.md
similarity index 100%
rename from pt-br/advanced/healthcheck-graceful-shutdown.md
rename to legacy/pt-br/advanced/healthcheck-graceful-shutdown.md
diff --git a/pt-br/advanced/security-updates.md b/legacy/pt-br/advanced/security-updates.md
similarity index 100%
rename from pt-br/advanced/security-updates.md
rename to legacy/pt-br/advanced/security-updates.md
diff --git a/pt-br/api.md b/legacy/pt-br/api.md
similarity index 100%
rename from pt-br/api.md
rename to legacy/pt-br/api.md
diff --git a/pt-br/changelog/index.md b/legacy/pt-br/changelog/index.md
similarity index 100%
rename from pt-br/changelog/index.md
rename to legacy/pt-br/changelog/index.md
diff --git a/pt-br/guide/behind-proxies.md b/legacy/pt-br/guide/behind-proxies.md
similarity index 100%
rename from pt-br/guide/behind-proxies.md
rename to legacy/pt-br/guide/behind-proxies.md
diff --git a/pt-br/guide/database-integration.md b/legacy/pt-br/guide/database-integration.md
similarity index 100%
rename from pt-br/guide/database-integration.md
rename to legacy/pt-br/guide/database-integration.md
diff --git a/pt-br/guide/debugging.md b/legacy/pt-br/guide/debugging.md
similarity index 100%
rename from pt-br/guide/debugging.md
rename to legacy/pt-br/guide/debugging.md
diff --git a/pt-br/guide/error-handling.md b/legacy/pt-br/guide/error-handling.md
similarity index 100%
rename from pt-br/guide/error-handling.md
rename to legacy/pt-br/guide/error-handling.md
diff --git a/pt-br/guide/migrating-4.md b/legacy/pt-br/guide/migrating-4.md
similarity index 100%
rename from pt-br/guide/migrating-4.md
rename to legacy/pt-br/guide/migrating-4.md
diff --git a/pt-br/guide/migrating-5.md b/legacy/pt-br/guide/migrating-5.md
similarity index 85%
rename from pt-br/guide/migrating-5.md
rename to legacy/pt-br/guide/migrating-5.md
index 3279493188..e4a65d899d 100644
--- a/pt-br/guide/migrating-5.md
+++ b/legacy/pt-br/guide/migrating-5.md
@@ -115,7 +115,7 @@ legalmente ser usadas como nomes de propriedades.
{% capture codemod-deprecated-signatures %}
Você pode substituir as assinaturas obsoletas pelo seguinte comando:
-```plain-text
+```plaintext
npx @expressjs/codemod v4-deprecated-signatures
```
@@ -125,14 +125,14 @@ npx @expressjs/codemod v4-deprecated-signatures
```js
// v4
-app.del('/user/:id', (req, res) => {
- res.send(`DELETE /user/${req.params.id}`)
-})
+app.del("/user/:id", (req, res) => {
+ res.send(`DELETE /user/${req.params.id}`);
+});
// v5
-app.delete('/user/:id', (req, res) => {
- res.send(`DELETE /user/${req.params.id}`)
-})
+app.delete("/user/:id", (req, res) => {
+ res.send(`DELETE /user/${req.params.id}`);
+});
```
app.param(fn)
@@ -145,7 +145,7 @@ foi descontinuada desde a v4.11.0, e o Express 5 não a suporta mais de nenhuma
Os seguintes nomes de métodos podem ser pluralizados. No
Express 4, o uso dos métodos antigos resultava em um aviso de
-descontinuação. O Express 5 não os suporta mais de forma nenhuma: Express 5 no longer supports them at all:
+descontinuação. O Express 5 não os suporta mais de forma nenhuma: Express 5 no longer supports them at all:
`req.acceptsLanguage()` é substituído por `req.acceptsLanguages()`.
@@ -156,7 +156,7 @@ descontinuação. O Express 5 não os suporta mais de forma nenhuma: Express 5
{% capture codemod-pluralized-methods %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod pluralized-methods
```
@@ -166,22 +166,22 @@ npx @expressjs/codemod pluralized-methods
```js
// v4
-app.all('/', (req, res) => {
- req.acceptsCharset('utf-8')
- req.acceptsEncoding('br')
- req.acceptsLanguage('en')
+app.all("/", (req, res) => {
+ req.acceptsCharset("utf-8");
+ req.acceptsEncoding("br");
+ req.acceptsLanguage("en");
// ...
-})
+});
// v5
-app.all('/', (req, res) => {
- req.acceptsCharsets('utf-8')
- req.acceptsEncodings('br')
- req.acceptsLanguages('en')
+app.all("/", (req, res) => {
+ req.acceptsCharsets("utf-8");
+ req.acceptsEncodings("br");
+ req.acceptsLanguages("en");
// ...
-})
+});
```
Dois pontos no começo (:) do nome do app.param(name, fn)
@@ -205,7 +205,7 @@ Este é um método potencialmente confuso e perigoso de recuperação de dados d
{% capture codemod-req-param %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod req-param
```
@@ -215,22 +215,22 @@ npx @expressjs/codemod req-param
```js
// v4
-app.post('/user', (req, res) => {
- const id = req.param('id')
- const body = req.param('body')
- const query = req.param('query')
+app.post("/user", (req, res) => {
+ const id = req.param("id");
+ const body = req.param("body");
+ const query = req.param("query");
// ...
-})
+});
// v5
-app.post('/user', (req, res) => {
- const id = req.params.id
- const body = req.body
- const query = req.query
+app.post("/user", (req, res) => {
+ const id = req.params.id;
+ const body = req.body;
+ const query = req.query;
// ...
-})
+});
```
res.json(obj, status)
@@ -243,14 +243,14 @@ invés disso, configure o status e então encadeie-o ao método `res.json()` ass
```js
// v4
-app.post('/user', (req, res) => {
- res.json({ name: 'Ruben' }, 201)
-})
+app.post("/user", (req, res) => {
+ res.json({ name: "Ruben" }, 201);
+});
// v5
-app.post('/user', (req, res) => {
- res.status(201).json({ name: 'Ruben' })
-})
+app.post("/user", (req, res) => {
+ res.status(201).json({ name: "Ruben" });
+});
```
res.jsonp(obj, status)
@@ -262,14 +262,14 @@ O Express 5 não suporta mais a assinatura `res.jsonp(obj, status)`. Ao invés d
```js
// v4
-app.post('/user', (req, res) => {
- res.jsonp({ name: 'Ruben' }, 201)
-})
+app.post("/user", (req, res) => {
+ res.jsonp({ name: "Ruben" }, 201);
+});
// v5
-app.post('/user', (req, res) => {
- res.status(201).jsonp({ name: 'Ruben' })
-})
+app.post("/user", (req, res) => {
+ res.status(201).jsonp({ name: "Ruben" });
+});
```
res.redirect(url, status)
@@ -281,14 +281,14 @@ O Express 5 não suporta mais a assinatura `res.send(obj, status)`. Ao invés di
```js
// v4
-app.get('/user', (req, res) => {
- res.redirect('/users', 301)
-})
+app.get("/user", (req, res) => {
+ res.redirect("/users", 301);
+});
// v5
-app.get('/user', (req, res) => {
- res.redirect(301, '/users')
-})
+app.get("/user", (req, res) => {
+ res.redirect(301, "/users");
+});
```
res.redirect('back') and res.location('back')
@@ -298,7 +298,7 @@ Express 5 no longer supports the magic string `back` in the `res.redirect()` and
{% capture codemod-magic-redirect %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod magic-redirect
```
@@ -308,14 +308,14 @@ npx @expressjs/codemod magic-redirect
```js
// v4
-app.get('/user', (req, res) => {
- res.redirect('back')
-})
+app.get("/user", (req, res) => {
+ res.redirect("back");
+});
// v5
-app.get('/user', (req, res) => {
- res.redirect(req.get('Referrer') || '/')
-})
+app.get("/user", (req, res) => {
+ res.redirect(req.get("Referrer") || "/");
+});
```
res.send(body, status)
@@ -326,14 +326,14 @@ Express 5 no longer supports the signature `res.send(obj, status)`. Instead, set
```js
// v4
-app.get('/user', (req, res) => {
- res.send({ name: 'Ruben' }, 200)
-})
+app.get("/user", (req, res) => {
+ res.send({ name: "Ruben" }, 200);
+});
// v5
-app.get('/user', (req, res) => {
- res.status(200).send({ name: 'Ruben' })
-})
+app.get("/user", (req, res) => {
+ res.status(200).send({ name: "Ruben" });
+});
```
res.send(status)
@@ -341,7 +341,7 @@ app.get('/user', (req, res) => {
O Express 5 não suporta mais a assinatura res.send(status ), onde _`status`_
é um número. Ao invés disso, use a função
`res.sendStatus(statusCode)`, que configura o código
-do status do cabeçalho de resposta HTTP e envia a versão de texto do
+do status do cabeçalho de resposta HTTP e envia a versão de texto do
código: "Não Encontrado", "Erro Interno de Servidor", e assim por
diante.
Se precisar enviar um número usando a função
@@ -354,14 +354,14 @@ suportada.
```js
// v4
-app.get('/user', (req, res) => {
- res.send(200)
-})
+app.get("/user", (req, res) => {
+ res.send(200);
+});
// v5
-app.get('/user', (req, res) => {
- res.sendStatus(200)
-})
+app.get("/user", (req, res) => {
+ res.sendStatus(200);
+});
```
res.sendfile()
@@ -383,14 +383,14 @@ Express 5.
```js
// v4
-app.get('/user', (req, res) => {
- res.sendfile('/path/to/file')
-})
+app.get("/user", (req, res) => {
+ res.sendfile("/path/to/file");
+});
// v5
-app.get('/user', (req, res) => {
- res.sendFile('/path/to/file')
-})
+app.get("/user", (req, res) => {
+ res.sendFile("/path/to/file");
+});
```
router.param(fn)
@@ -414,11 +414,11 @@ Use the [`mime-types` package](https://github.com/jshttp/mime-types) to work wit
```js
// v4
-express.static.mime.lookup('json')
+express.static.mime.lookup("json");
// v5
-const mime = require('mime-types')
-mime.lookup('json')
+const mime = require("mime-types");
+mime.lookup("json");
```
express:router debug logs
@@ -450,14 +450,14 @@ Path route matching syntax is when a string is supplied as the first parameter t
```js
// v4
-app.get('/*', async (req, res) => {
- res.send('ok')
-})
+app.get("/*", async (req, res) => {
+ res.send("ok");
+});
// v5
-app.get('/*splat', async (req, res) => {
- res.send('ok')
-})
+app.get("/*splat", async (req, res) => {
+ res.send("ok");
+});
```
{% capture note_wildcard %}
@@ -465,9 +465,9 @@ app.get('/*splat', async (req, res) => {
```js
// v5
-app.get('/{*splat}', async (req, res) => {
- res.send('ok')
-})
+app.get("/{*splat}", async (req, res) => {
+ res.send("ok");
+});
```
{% endcapture %}
@@ -477,30 +477,30 @@ app.get('/{*splat}', async (req, res) => {
```js
// v4
-app.get('/:file.:ext?', async (req, res) => {
- res.send('ok')
-})
+app.get("/:file.:ext?", async (req, res) => {
+ res.send("ok");
+});
// v5
-app.get('/:file{.:ext}', async (req, res) => {
- res.send('ok')
-})
+app.get("/:file{.:ext}", async (req, res) => {
+ res.send("ok");
+});
```
- Regexp characters are not supported. Por exemplo:
```js
-app.get('/[discussion|page]/:slug', async (req, res) => {
- res.status(200).send('ok')
-})
+app.get("/[discussion|page]/:slug", async (req, res) => {
+ res.status(200).send("ok");
+});
```
should be changed to:
```js
-app.get(['/discussion/:slug', '/page/:slug'], async (req, res) => {
- res.status(200).send('ok')
-})
+app.get(["/discussion/:slug", "/page/:slug"], async (req, res) => {
+ res.status(200).send("ok");
+});
```
- Some characters have been reserved to avoid confusion during upgrade (`()[]?+!`), use `\` to escape them.
@@ -524,7 +524,7 @@ Example of breaking code:
```js
// v4
-app.use(express.static('public'))
+app.use(express.static("public"));
```
After migrating to Express 5, a request to `/.well-known/assetlinks.json` will result in a **404 Not Found**.
@@ -533,8 +533,11 @@ To fix this, serve specific dot-directories explicitly using the `dotfiles: "all
```js
// v5
-app.use('/.well-known', express.static('public/.well-known', { dotfiles: 'allow' }))
-app.use(express.static('public'))
+app.use(
+ "/.well-known",
+ express.static("public/.well-known", { dotfiles: "allow" }),
+);
+app.use(express.static("public"));
```
This approach allows you to safely serve only the intended dot-directories while keeping the default secure behavior for other dotfiles, which remain inaccessible.
@@ -545,12 +548,12 @@ In Express 5, the `app.listen` method will invoke the user-provided callback fun
Por exemplo:
```js
-const server = app.listen(8080, '0.0.0.0', (error) => {
+const server = app.listen(8080, "0.0.0.0", (error) => {
if (error) {
- throw error // e.g. EADDRINUSE
+ throw error; // e.g. EADDRINUSE
}
- console.log(`Listening on ${JSON.stringify(server.address())}`)
-})
+ console.log(`Listening on ${JSON.stringify(server.address())}`);
+});
```
app.router
@@ -579,11 +582,11 @@ The `req.params` object now has a **null prototype** when using string paths. Ho
Wildcards (e.g., `/*splat`) capture path segments as an array instead of a single string.
```js
-app.get('/*splat', (req, res) => {
+app.get("/*splat", (req, res) => {
// GET /foo/bar
- console.dir(req.params)
+ console.dir(req.params);
// => [Object: null prototype] { splat: [ 'foo', 'bar' ] }
-})
+});
```
**Unmatched parameters are omitted:**
@@ -592,25 +595,25 @@ In Express 4, unmatched wildcards were empty strings (`''`) and optional `:` par
```js
// v4: unmatched wildcard is empty string
-app.get('/*', (req, res) => {
+app.get("/*", (req, res) => {
// GET /
- console.dir(req.params)
+ console.dir(req.params);
// => { '0': '' }
-})
+});
// v4: unmatched optional param is undefined
-app.get('/:file.:ext?', (req, res) => {
+app.get("/:file.:ext?", (req, res) => {
// GET /image
- console.dir(req.params)
+ console.dir(req.params);
// => { file: 'image', ext: undefined }
-})
+});
// v5: unmatched optional param is omitted
-app.get('/:file{.:ext}', (req, res) => {
+app.get("/:file{.:ext}", (req, res) => {
// GET /image
- console.dir(req.params)
+ console.dir(req.params);
// => [Object: null prototype] { file: 'image' }
-})
+});
```
req.query
@@ -633,7 +636,7 @@ The `res.vary` throws an error when the `field` argument is missing. In Express
res.render()
-Este método agora impinge comportamento assíncrono para todos
+Este método agora impinge comportamento assíncrono para todos
os mecanismos de visualização, evitando erros causados pelos
mecanismos de visualização que tinham uma implementação síncrona e
que violavam a interface recomendada.
diff --git a/pt-br/guide/overriding-express-api.md b/legacy/pt-br/guide/overriding-express-api.md
similarity index 100%
rename from pt-br/guide/overriding-express-api.md
rename to legacy/pt-br/guide/overriding-express-api.md
diff --git a/pt-br/guide/routing.md b/legacy/pt-br/guide/routing.md
similarity index 100%
rename from pt-br/guide/routing.md
rename to legacy/pt-br/guide/routing.md
diff --git a/pt-br/guide/using-middleware.md b/legacy/pt-br/guide/using-middleware.md
similarity index 100%
rename from pt-br/guide/using-middleware.md
rename to legacy/pt-br/guide/using-middleware.md
diff --git a/pt-br/guide/using-template-engines.md b/legacy/pt-br/guide/using-template-engines.md
similarity index 100%
rename from pt-br/guide/using-template-engines.md
rename to legacy/pt-br/guide/using-template-engines.md
diff --git a/pt-br/guide/writing-middleware.md b/legacy/pt-br/guide/writing-middleware.md
similarity index 100%
rename from pt-br/guide/writing-middleware.md
rename to legacy/pt-br/guide/writing-middleware.md
diff --git a/pt-br/index.md b/legacy/pt-br/index.md
similarity index 100%
rename from pt-br/index.md
rename to legacy/pt-br/index.md
diff --git a/pt-br/resources/community.md b/legacy/pt-br/resources/community.md
similarity index 100%
rename from pt-br/resources/community.md
rename to legacy/pt-br/resources/community.md
diff --git a/pt-br/resources/contributing.md b/legacy/pt-br/resources/contributing.md
similarity index 100%
rename from pt-br/resources/contributing.md
rename to legacy/pt-br/resources/contributing.md
diff --git a/pt-br/resources/glossary.md b/legacy/pt-br/resources/glossary.md
similarity index 100%
rename from pt-br/resources/glossary.md
rename to legacy/pt-br/resources/glossary.md
diff --git a/pt-br/resources/middleware.md b/legacy/pt-br/resources/middleware.md
similarity index 100%
rename from pt-br/resources/middleware.md
rename to legacy/pt-br/resources/middleware.md
diff --git a/pt-br/resources/middleware/body-parser.md b/legacy/pt-br/resources/middleware/body-parser.md
similarity index 100%
rename from pt-br/resources/middleware/body-parser.md
rename to legacy/pt-br/resources/middleware/body-parser.md
diff --git a/pt-br/resources/middleware/compression.md b/legacy/pt-br/resources/middleware/compression.md
similarity index 100%
rename from pt-br/resources/middleware/compression.md
rename to legacy/pt-br/resources/middleware/compression.md
diff --git a/pt-br/resources/middleware/connect-rid.md b/legacy/pt-br/resources/middleware/connect-rid.md
similarity index 100%
rename from pt-br/resources/middleware/connect-rid.md
rename to legacy/pt-br/resources/middleware/connect-rid.md
diff --git a/pt-br/resources/middleware/cookie-parser.md b/legacy/pt-br/resources/middleware/cookie-parser.md
similarity index 100%
rename from pt-br/resources/middleware/cookie-parser.md
rename to legacy/pt-br/resources/middleware/cookie-parser.md
diff --git a/pt-br/resources/middleware/cookie-session.md b/legacy/pt-br/resources/middleware/cookie-session.md
similarity index 100%
rename from pt-br/resources/middleware/cookie-session.md
rename to legacy/pt-br/resources/middleware/cookie-session.md
diff --git a/pt-br/resources/middleware/cors.md b/legacy/pt-br/resources/middleware/cors.md
similarity index 100%
rename from pt-br/resources/middleware/cors.md
rename to legacy/pt-br/resources/middleware/cors.md
diff --git a/pt-br/resources/middleware/errorhandler.md b/legacy/pt-br/resources/middleware/errorhandler.md
similarity index 100%
rename from pt-br/resources/middleware/errorhandler.md
rename to legacy/pt-br/resources/middleware/errorhandler.md
diff --git a/pt-br/resources/middleware/method-override.md b/legacy/pt-br/resources/middleware/method-override.md
similarity index 100%
rename from pt-br/resources/middleware/method-override.md
rename to legacy/pt-br/resources/middleware/method-override.md
diff --git a/pt-br/resources/middleware/morgan.md b/legacy/pt-br/resources/middleware/morgan.md
similarity index 100%
rename from pt-br/resources/middleware/morgan.md
rename to legacy/pt-br/resources/middleware/morgan.md
diff --git a/pt-br/resources/middleware/multer.md b/legacy/pt-br/resources/middleware/multer.md
similarity index 100%
rename from pt-br/resources/middleware/multer.md
rename to legacy/pt-br/resources/middleware/multer.md
diff --git a/pt-br/resources/middleware/response-time.md b/legacy/pt-br/resources/middleware/response-time.md
similarity index 100%
rename from pt-br/resources/middleware/response-time.md
rename to legacy/pt-br/resources/middleware/response-time.md
diff --git a/pt-br/resources/middleware/serve-favicon.md b/legacy/pt-br/resources/middleware/serve-favicon.md
similarity index 100%
rename from pt-br/resources/middleware/serve-favicon.md
rename to legacy/pt-br/resources/middleware/serve-favicon.md
diff --git a/pt-br/resources/middleware/serve-index.md b/legacy/pt-br/resources/middleware/serve-index.md
similarity index 100%
rename from pt-br/resources/middleware/serve-index.md
rename to legacy/pt-br/resources/middleware/serve-index.md
diff --git a/pt-br/resources/middleware/serve-static.md b/legacy/pt-br/resources/middleware/serve-static.md
similarity index 100%
rename from pt-br/resources/middleware/serve-static.md
rename to legacy/pt-br/resources/middleware/serve-static.md
diff --git a/pt-br/resources/middleware/session.md b/legacy/pt-br/resources/middleware/session.md
similarity index 100%
rename from pt-br/resources/middleware/session.md
rename to legacy/pt-br/resources/middleware/session.md
diff --git a/pt-br/resources/middleware/timeout.md b/legacy/pt-br/resources/middleware/timeout.md
similarity index 100%
rename from pt-br/resources/middleware/timeout.md
rename to legacy/pt-br/resources/middleware/timeout.md
diff --git a/pt-br/resources/middleware/vhost.md b/legacy/pt-br/resources/middleware/vhost.md
similarity index 100%
rename from pt-br/resources/middleware/vhost.md
rename to legacy/pt-br/resources/middleware/vhost.md
diff --git a/pt-br/resources/utils.md b/legacy/pt-br/resources/utils.md
similarity index 100%
rename from pt-br/resources/utils.md
rename to legacy/pt-br/resources/utils.md
diff --git a/pt-br/starter/basic-routing.md b/legacy/pt-br/starter/basic-routing.md
similarity index 100%
rename from pt-br/starter/basic-routing.md
rename to legacy/pt-br/starter/basic-routing.md
diff --git a/pt-br/starter/examples.md b/legacy/pt-br/starter/examples.md
similarity index 100%
rename from pt-br/starter/examples.md
rename to legacy/pt-br/starter/examples.md
diff --git a/pt-br/starter/faq.md b/legacy/pt-br/starter/faq.md
similarity index 100%
rename from pt-br/starter/faq.md
rename to legacy/pt-br/starter/faq.md
diff --git a/pt-br/starter/generator.md b/legacy/pt-br/starter/generator.md
similarity index 100%
rename from pt-br/starter/generator.md
rename to legacy/pt-br/starter/generator.md
diff --git a/pt-br/starter/hello-world.md b/legacy/pt-br/starter/hello-world.md
similarity index 100%
rename from pt-br/starter/hello-world.md
rename to legacy/pt-br/starter/hello-world.md
diff --git a/pt-br/starter/installing.md b/legacy/pt-br/starter/installing.md
similarity index 100%
rename from pt-br/starter/installing.md
rename to legacy/pt-br/starter/installing.md
diff --git a/pt-br/starter/static-files.md b/legacy/pt-br/starter/static-files.md
similarity index 100%
rename from pt-br/starter/static-files.md
rename to legacy/pt-br/starter/static-files.md
diff --git a/pt-br/support/index.md b/legacy/pt-br/support/index.md
similarity index 100%
rename from pt-br/support/index.md
rename to legacy/pt-br/support/index.md
diff --git a/sitemap.xml b/legacy/sitemap.xml
similarity index 100%
rename from sitemap.xml
rename to legacy/sitemap.xml
diff --git a/vulnerabilities.xml b/legacy/vulnerabilities.xml
similarity index 100%
rename from vulnerabilities.xml
rename to legacy/vulnerabilities.xml
diff --git a/zh-cn/3x/api.md b/legacy/zh-cn/3x/api.md
similarity index 100%
rename from zh-cn/3x/api.md
rename to legacy/zh-cn/3x/api.md
diff --git a/zh-cn/4x/api.md b/legacy/zh-cn/4x/api.md
similarity index 100%
rename from zh-cn/4x/api.md
rename to legacy/zh-cn/4x/api.md
diff --git a/zh-cn/5x/api.md b/legacy/zh-cn/5x/api.md
similarity index 100%
rename from zh-cn/5x/api.md
rename to legacy/zh-cn/5x/api.md
diff --git a/zh-cn/advanced/best-practice-performance.md b/legacy/zh-cn/advanced/best-practice-performance.md
similarity index 100%
rename from zh-cn/advanced/best-practice-performance.md
rename to legacy/zh-cn/advanced/best-practice-performance.md
diff --git a/zh-cn/advanced/best-practice-security.md b/legacy/zh-cn/advanced/best-practice-security.md
similarity index 100%
rename from zh-cn/advanced/best-practice-security.md
rename to legacy/zh-cn/advanced/best-practice-security.md
diff --git a/zh-cn/advanced/developing-template-engines.md b/legacy/zh-cn/advanced/developing-template-engines.md
similarity index 100%
rename from zh-cn/advanced/developing-template-engines.md
rename to legacy/zh-cn/advanced/developing-template-engines.md
diff --git a/zh-cn/advanced/healthcheck-graceful-shutdown.md b/legacy/zh-cn/advanced/healthcheck-graceful-shutdown.md
similarity index 100%
rename from zh-cn/advanced/healthcheck-graceful-shutdown.md
rename to legacy/zh-cn/advanced/healthcheck-graceful-shutdown.md
diff --git a/zh-cn/advanced/security-updates.md b/legacy/zh-cn/advanced/security-updates.md
similarity index 100%
rename from zh-cn/advanced/security-updates.md
rename to legacy/zh-cn/advanced/security-updates.md
diff --git a/zh-cn/api.md b/legacy/zh-cn/api.md
similarity index 100%
rename from zh-cn/api.md
rename to legacy/zh-cn/api.md
diff --git a/zh-cn/changelog/index.md b/legacy/zh-cn/changelog/index.md
similarity index 100%
rename from zh-cn/changelog/index.md
rename to legacy/zh-cn/changelog/index.md
diff --git a/zh-cn/guide/behind-proxies.md b/legacy/zh-cn/guide/behind-proxies.md
similarity index 100%
rename from zh-cn/guide/behind-proxies.md
rename to legacy/zh-cn/guide/behind-proxies.md
diff --git a/zh-cn/guide/database-integration.md b/legacy/zh-cn/guide/database-integration.md
similarity index 100%
rename from zh-cn/guide/database-integration.md
rename to legacy/zh-cn/guide/database-integration.md
diff --git a/zh-cn/guide/debugging.md b/legacy/zh-cn/guide/debugging.md
similarity index 100%
rename from zh-cn/guide/debugging.md
rename to legacy/zh-cn/guide/debugging.md
diff --git a/zh-cn/guide/error-handling.md b/legacy/zh-cn/guide/error-handling.md
similarity index 100%
rename from zh-cn/guide/error-handling.md
rename to legacy/zh-cn/guide/error-handling.md
diff --git a/zh-cn/guide/migrating-4.md b/legacy/zh-cn/guide/migrating-4.md
similarity index 100%
rename from zh-cn/guide/migrating-4.md
rename to legacy/zh-cn/guide/migrating-4.md
diff --git a/zh-cn/guide/migrating-5.md b/legacy/zh-cn/guide/migrating-5.md
similarity index 87%
rename from zh-cn/guide/migrating-5.md
rename to legacy/zh-cn/guide/migrating-5.md
index 02d36227fe..161452eb57 100644
--- a/zh-cn/guide/migrating-5.md
+++ b/legacy/zh-cn/guide/migrating-5.md
@@ -99,7 +99,7 @@ Express 5 不再支持 `app.del()` 函数。如果使用此函数,将抛出错
{% capture codemod-deprecated-signatures %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod v4-deprecated-signatures
```
@@ -109,14 +109,14 @@ npx @expressjs/codemod v4-deprecated-signatures
```js
// v4
-app.del('/user/:id', (req, res) => {
- res.send(`DELETE /user/${req.params.id}`)
-})
+app.del("/user/:id", (req, res) => {
+ res.send(`DELETE /user/${req.params.id}`);
+});
// v5
-app.delete('/user/:id', (req, res) => {
- res.send(`DELETE /user/${req.params.id}`)
-})
+app.delete("/user/:id", (req, res) => {
+ res.send(`DELETE /user/${req.params.id}`);
+});
```
app.param(fn)
@@ -136,7 +136,7 @@ The following method names have been pluralized. In Express 4, using the old met
{% capture codemod-pluralized-methods %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod pluralized-methods
```
@@ -146,22 +146,22 @@ npx @expressjs/codemod pluralized-methods
```js
// v4
-app.all('/', (req, res) => {
- req.acceptsCharset('utf-8')
- req.acceptsEncoding('br')
- req.acceptsLanguage('en')
+app.all("/", (req, res) => {
+ req.acceptsCharset("utf-8");
+ req.acceptsEncoding("br");
+ req.acceptsLanguage("en");
// ...
-})
+});
// v5
-app.all('/', (req, res) => {
- req.acceptsCharsets('utf-8')
- req.acceptsEncodings('br')
- req.acceptsLanguages('en')
+app.all("/", (req, res) => {
+ req.acceptsCharsets("utf-8");
+ req.acceptsEncodings("br");
+ req.acceptsLanguages("en");
// ...
-})
+});
```
app.param(name, fn) 的名称中的前置冒号 (:)
@@ -177,7 +177,7 @@ This potentially confusing and dangerous method of retrieving form data has been
{% capture codemod-req-param %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod req-param
```
@@ -187,22 +187,22 @@ npx @expressjs/codemod req-param
```js
// v4
-app.post('/user', (req, res) => {
- const id = req.param('id')
- const body = req.param('body')
- const query = req.param('query')
+app.post("/user", (req, res) => {
+ const id = req.param("id");
+ const body = req.param("body");
+ const query = req.param("query");
// ...
-})
+});
// v5
-app.post('/user', (req, res) => {
- const id = req.params.id
- const body = req.body
- const query = req.query
+app.post("/user", (req, res) => {
+ const id = req.params.id;
+ const body = req.body;
+ const query = req.query;
// ...
-})
+});
```
res.json(obj, status)
@@ -213,14 +213,14 @@ Express 5 不再支持特征符 `res.json(obj, status)`。而是设置状态,
```js
// v4
-app.post('/user', (req, res) => {
- res.json({ name: 'Ruben' }, 201)
-})
+app.post("/user", (req, res) => {
+ res.json({ name: "Ruben" }, 201);
+});
// v5
-app.post('/user', (req, res) => {
- res.status(201).json({ name: 'Ruben' })
-})
+app.post("/user", (req, res) => {
+ res.status(201).json({ name: "Ruben" });
+});
```
res.jsonp(obj, status)
@@ -231,14 +231,14 @@ Express 5 不再支持特征符 `res.jsonp(obj, status)`。而是设置状态,
```js
// v4
-app.post('/user', (req, res) => {
- res.jsonp({ name: 'Ruben' }, 201)
-})
+app.post("/user", (req, res) => {
+ res.jsonp({ name: "Ruben" }, 201);
+});
// v5
-app.post('/user', (req, res) => {
- res.status(201).jsonp({ name: 'Ruben' })
-})
+app.post("/user", (req, res) => {
+ res.status(201).jsonp({ name: "Ruben" });
+});
```
res.redirect(url, status)
@@ -249,14 +249,14 @@ Express 5 no longer supports the signature `res.redirect(url, status)`. Instead,
```js
// v4
-app.get('/user', (req, res) => {
- res.redirect('/users', 301)
-})
+app.get("/user", (req, res) => {
+ res.redirect("/users", 301);
+});
// v5
-app.get('/user', (req, res) => {
- res.redirect(301, '/users')
-})
+app.get("/user", (req, res) => {
+ res.redirect(301, "/users");
+});
```
res.redirect('back') and res.location('back')
@@ -266,7 +266,7 @@ Express 5 no longer supports the magic string `back` in the `res.redirect()` and
{% capture codemod-magic-redirect %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod magic-redirect
```
@@ -276,14 +276,14 @@ npx @expressjs/codemod magic-redirect
```js
// v4
-app.get('/user', (req, res) => {
- res.redirect('back')
-})
+app.get("/user", (req, res) => {
+ res.redirect("back");
+});
// v5
-app.get('/user', (req, res) => {
- res.redirect(req.get('Referrer') || '/')
-})
+app.get("/user", (req, res) => {
+ res.redirect(req.get("Referrer") || "/");
+});
```
res.send(body, status)
@@ -294,14 +294,14 @@ Express 5 不再支持特征符 `res.send(obj, status)`。而是设置状态,
```js
// v4
-app.get('/user', (req, res) => {
- res.send({ name: 'Ruben' }, 200)
-})
+app.get("/user", (req, res) => {
+ res.send({ name: "Ruben" }, 200);
+});
// v5
-app.get('/user', (req, res) => {
- res.status(200).send({ name: 'Ruben' })
-})
+app.get("/user", (req, res) => {
+ res.status(200).send({ name: "Ruben" });
+});
```
res.send(status)
@@ -313,14 +313,14 @@ If you need to send a number by using the `res.send()` function, quote the numbe
```js
// v4
-app.get('/user', (req, res) => {
- res.send(200)
-})
+app.get("/user", (req, res) => {
+ res.send(200);
+});
// v5
-app.get('/user', (req, res) => {
- res.sendStatus(200)
-})
+app.get("/user", (req, res) => {
+ res.sendStatus(200);
+});
```
res.sendfile()
@@ -340,14 +340,14 @@ app.get('/user', (req, res) => {
```js
// v4
-app.get('/user', (req, res) => {
- res.sendfile('/path/to/file')
-})
+app.get("/user", (req, res) => {
+ res.sendfile("/path/to/file");
+});
// v5
-app.get('/user', (req, res) => {
- res.sendFile('/path/to/file')
-})
+app.get("/user", (req, res) => {
+ res.sendFile("/path/to/file");
+});
```
router.param(fn)
@@ -370,11 +370,11 @@ Use the [`mime-types` package](https://github.com/jshttp/mime-types) to work wit
```js
// v4
-express.static.mime.lookup('json')
+express.static.mime.lookup("json");
// v5
-const mime = require('mime-types')
-mime.lookup('json')
+const mime = require("mime-types");
+mime.lookup("json");
```
express:router debug logs
@@ -406,14 +406,14 @@ Path route matching syntax is when a string is supplied as the first parameter t
```js
// v4
-app.get('/*', async (req, res) => {
- res.send('ok')
-})
+app.get("/*", async (req, res) => {
+ res.send("ok");
+});
// v5
-app.get('/*splat', async (req, res) => {
- res.send('ok')
-})
+app.get("/*splat", async (req, res) => {
+ res.send("ok");
+});
```
{% capture note_wildcard %}
@@ -421,9 +421,9 @@ app.get('/*splat', async (req, res) => {
```js
// v5
-app.get('/{*splat}', async (req, res) => {
- res.send('ok')
-})
+app.get("/{*splat}", async (req, res) => {
+ res.send("ok");
+});
```
{% endcapture %}
@@ -433,30 +433,30 @@ app.get('/{*splat}', async (req, res) => {
```js
// v4
-app.get('/:file.:ext?', async (req, res) => {
- res.send('ok')
-})
+app.get("/:file.:ext?", async (req, res) => {
+ res.send("ok");
+});
// v5
-app.get('/:file{.:ext}', async (req, res) => {
- res.send('ok')
-})
+app.get("/:file{.:ext}", async (req, res) => {
+ res.send("ok");
+});
```
- Regexp characters are not supported. For example:
```js
-app.get('/[discussion|page]/:slug', async (req, res) => {
- res.status(200).send('ok')
-})
+app.get("/[discussion|page]/:slug", async (req, res) => {
+ res.status(200).send("ok");
+});
```
should be changed to:
```js
-app.get(['/discussion/:slug', '/page/:slug'], async (req, res) => {
- res.status(200).send('ok')
-})
+app.get(["/discussion/:slug", "/page/:slug"], async (req, res) => {
+ res.status(200).send("ok");
+});
```
- Some characters have been reserved to avoid confusion during upgrade (`()[]?+!`), use `\` to escape them.
@@ -480,7 +480,7 @@ Example of breaking code:
```js
// v4
-app.use(express.static('public'))
+app.use(express.static("public"));
```
After migrating to Express 5, a request to `/.well-known/assetlinks.json` will result in a **404 Not Found**.
@@ -489,8 +489,11 @@ To fix this, serve specific dot-directories explicitly using the `dotfiles: "all
```js
// v5
-app.use('/.well-known', express.static('public/.well-known', { dotfiles: 'allow' }))
-app.use(express.static('public'))
+app.use(
+ "/.well-known",
+ express.static("public/.well-known", { dotfiles: "allow" }),
+);
+app.use(express.static("public"));
```
This approach allows you to safely serve only the intended dot-directories while keeping the default secure behavior for other dotfiles, which remain inaccessible.
@@ -501,12 +504,12 @@ In Express 5, the `app.listen` method will invoke the user-provided callback fun
For example:
```js
-const server = app.listen(8080, '0.0.0.0', (error) => {
+const server = app.listen(8080, "0.0.0.0", (error) => {
if (error) {
- throw error // e.g. EADDRINUSE
+ throw error; // e.g. EADDRINUSE
}
- console.log(`Listening on ${JSON.stringify(server.address())}`)
-})
+ console.log(`Listening on ${JSON.stringify(server.address())}`);
+});
```
app.router
@@ -530,11 +533,11 @@ The `req.params` object now has a **null prototype** when using string paths. Ho
Wildcards (e.g., `/*splat`) capture path segments as an array instead of a single string.
```js
-app.get('/*splat', (req, res) => {
+app.get("/*splat", (req, res) => {
// GET /foo/bar
- console.dir(req.params)
+ console.dir(req.params);
// => [Object: null prototype] { splat: [ 'foo', 'bar' ] }
-})
+});
```
**Unmatched parameters are omitted:**
@@ -543,25 +546,25 @@ In Express 4, unmatched wildcards were empty strings (`''`) and optional `:` par
```js
// v4: unmatched wildcard is empty string
-app.get('/*', (req, res) => {
+app.get("/*", (req, res) => {
// GET /
- console.dir(req.params)
+ console.dir(req.params);
// => { '0': '' }
-})
+});
// v4: unmatched optional param is undefined
-app.get('/:file.:ext?', (req, res) => {
+app.get("/:file.:ext?", (req, res) => {
// GET /image
- console.dir(req.params)
+ console.dir(req.params);
// => { file: 'image', ext: undefined }
-})
+});
// v5: unmatched optional param is omitted
-app.get('/:file{.:ext}', (req, res) => {
+app.get("/:file{.:ext}", (req, res) => {
// GET /image
- console.dir(req.params)
+ console.dir(req.params);
// => [Object: null prototype] { file: 'image' }
-})
+});
```
req.query
diff --git a/zh-cn/guide/overriding-express-api.md b/legacy/zh-cn/guide/overriding-express-api.md
similarity index 100%
rename from zh-cn/guide/overriding-express-api.md
rename to legacy/zh-cn/guide/overriding-express-api.md
diff --git a/zh-cn/guide/routing.md b/legacy/zh-cn/guide/routing.md
similarity index 100%
rename from zh-cn/guide/routing.md
rename to legacy/zh-cn/guide/routing.md
diff --git a/zh-cn/guide/using-middleware.md b/legacy/zh-cn/guide/using-middleware.md
similarity index 100%
rename from zh-cn/guide/using-middleware.md
rename to legacy/zh-cn/guide/using-middleware.md
diff --git a/zh-cn/guide/using-template-engines.md b/legacy/zh-cn/guide/using-template-engines.md
similarity index 100%
rename from zh-cn/guide/using-template-engines.md
rename to legacy/zh-cn/guide/using-template-engines.md
diff --git a/zh-cn/guide/writing-middleware.md b/legacy/zh-cn/guide/writing-middleware.md
similarity index 100%
rename from zh-cn/guide/writing-middleware.md
rename to legacy/zh-cn/guide/writing-middleware.md
diff --git a/zh-cn/index.md b/legacy/zh-cn/index.md
similarity index 100%
rename from zh-cn/index.md
rename to legacy/zh-cn/index.md
diff --git a/zh-cn/resources/community.md b/legacy/zh-cn/resources/community.md
similarity index 100%
rename from zh-cn/resources/community.md
rename to legacy/zh-cn/resources/community.md
diff --git a/zh-cn/resources/contributing.md b/legacy/zh-cn/resources/contributing.md
similarity index 100%
rename from zh-cn/resources/contributing.md
rename to legacy/zh-cn/resources/contributing.md
diff --git a/zh-cn/resources/glossary.md b/legacy/zh-cn/resources/glossary.md
similarity index 100%
rename from zh-cn/resources/glossary.md
rename to legacy/zh-cn/resources/glossary.md
diff --git a/zh-cn/resources/middleware.md b/legacy/zh-cn/resources/middleware.md
similarity index 100%
rename from zh-cn/resources/middleware.md
rename to legacy/zh-cn/resources/middleware.md
diff --git a/zh-cn/resources/middleware/body-parser.md b/legacy/zh-cn/resources/middleware/body-parser.md
similarity index 100%
rename from zh-cn/resources/middleware/body-parser.md
rename to legacy/zh-cn/resources/middleware/body-parser.md
diff --git a/zh-cn/resources/middleware/compression.md b/legacy/zh-cn/resources/middleware/compression.md
similarity index 100%
rename from zh-cn/resources/middleware/compression.md
rename to legacy/zh-cn/resources/middleware/compression.md
diff --git a/zh-cn/resources/middleware/connect-rid.md b/legacy/zh-cn/resources/middleware/connect-rid.md
similarity index 100%
rename from zh-cn/resources/middleware/connect-rid.md
rename to legacy/zh-cn/resources/middleware/connect-rid.md
diff --git a/zh-cn/resources/middleware/cookie-parser.md b/legacy/zh-cn/resources/middleware/cookie-parser.md
similarity index 100%
rename from zh-cn/resources/middleware/cookie-parser.md
rename to legacy/zh-cn/resources/middleware/cookie-parser.md
diff --git a/zh-cn/resources/middleware/cookie-session.md b/legacy/zh-cn/resources/middleware/cookie-session.md
similarity index 100%
rename from zh-cn/resources/middleware/cookie-session.md
rename to legacy/zh-cn/resources/middleware/cookie-session.md
diff --git a/zh-cn/resources/middleware/cors.md b/legacy/zh-cn/resources/middleware/cors.md
similarity index 100%
rename from zh-cn/resources/middleware/cors.md
rename to legacy/zh-cn/resources/middleware/cors.md
diff --git a/zh-cn/resources/middleware/errorhandler.md b/legacy/zh-cn/resources/middleware/errorhandler.md
similarity index 100%
rename from zh-cn/resources/middleware/errorhandler.md
rename to legacy/zh-cn/resources/middleware/errorhandler.md
diff --git a/zh-cn/resources/middleware/method-override.md b/legacy/zh-cn/resources/middleware/method-override.md
similarity index 100%
rename from zh-cn/resources/middleware/method-override.md
rename to legacy/zh-cn/resources/middleware/method-override.md
diff --git a/zh-cn/resources/middleware/morgan.md b/legacy/zh-cn/resources/middleware/morgan.md
similarity index 100%
rename from zh-cn/resources/middleware/morgan.md
rename to legacy/zh-cn/resources/middleware/morgan.md
diff --git a/zh-cn/resources/middleware/multer.md b/legacy/zh-cn/resources/middleware/multer.md
similarity index 100%
rename from zh-cn/resources/middleware/multer.md
rename to legacy/zh-cn/resources/middleware/multer.md
diff --git a/zh-cn/resources/middleware/response-time.md b/legacy/zh-cn/resources/middleware/response-time.md
similarity index 100%
rename from zh-cn/resources/middleware/response-time.md
rename to legacy/zh-cn/resources/middleware/response-time.md
diff --git a/zh-cn/resources/middleware/serve-favicon.md b/legacy/zh-cn/resources/middleware/serve-favicon.md
similarity index 100%
rename from zh-cn/resources/middleware/serve-favicon.md
rename to legacy/zh-cn/resources/middleware/serve-favicon.md
diff --git a/zh-cn/resources/middleware/serve-index.md b/legacy/zh-cn/resources/middleware/serve-index.md
similarity index 100%
rename from zh-cn/resources/middleware/serve-index.md
rename to legacy/zh-cn/resources/middleware/serve-index.md
diff --git a/zh-cn/resources/middleware/serve-static.md b/legacy/zh-cn/resources/middleware/serve-static.md
similarity index 100%
rename from zh-cn/resources/middleware/serve-static.md
rename to legacy/zh-cn/resources/middleware/serve-static.md
diff --git a/zh-cn/resources/middleware/session.md b/legacy/zh-cn/resources/middleware/session.md
similarity index 100%
rename from zh-cn/resources/middleware/session.md
rename to legacy/zh-cn/resources/middleware/session.md
diff --git a/zh-cn/resources/middleware/timeout.md b/legacy/zh-cn/resources/middleware/timeout.md
similarity index 100%
rename from zh-cn/resources/middleware/timeout.md
rename to legacy/zh-cn/resources/middleware/timeout.md
diff --git a/zh-cn/resources/middleware/vhost.md b/legacy/zh-cn/resources/middleware/vhost.md
similarity index 100%
rename from zh-cn/resources/middleware/vhost.md
rename to legacy/zh-cn/resources/middleware/vhost.md
diff --git a/zh-cn/resources/utils.md b/legacy/zh-cn/resources/utils.md
similarity index 100%
rename from zh-cn/resources/utils.md
rename to legacy/zh-cn/resources/utils.md
diff --git a/zh-cn/starter/basic-routing.md b/legacy/zh-cn/starter/basic-routing.md
similarity index 100%
rename from zh-cn/starter/basic-routing.md
rename to legacy/zh-cn/starter/basic-routing.md
diff --git a/zh-cn/starter/examples.md b/legacy/zh-cn/starter/examples.md
similarity index 100%
rename from zh-cn/starter/examples.md
rename to legacy/zh-cn/starter/examples.md
diff --git a/zh-cn/starter/faq.md b/legacy/zh-cn/starter/faq.md
similarity index 100%
rename from zh-cn/starter/faq.md
rename to legacy/zh-cn/starter/faq.md
diff --git a/zh-cn/starter/generator.md b/legacy/zh-cn/starter/generator.md
similarity index 100%
rename from zh-cn/starter/generator.md
rename to legacy/zh-cn/starter/generator.md
diff --git a/zh-cn/starter/hello-world.md b/legacy/zh-cn/starter/hello-world.md
similarity index 100%
rename from zh-cn/starter/hello-world.md
rename to legacy/zh-cn/starter/hello-world.md
diff --git a/zh-cn/starter/installing.md b/legacy/zh-cn/starter/installing.md
similarity index 100%
rename from zh-cn/starter/installing.md
rename to legacy/zh-cn/starter/installing.md
diff --git a/zh-cn/starter/static-files.md b/legacy/zh-cn/starter/static-files.md
similarity index 100%
rename from zh-cn/starter/static-files.md
rename to legacy/zh-cn/starter/static-files.md
diff --git a/zh-cn/support/index.md b/legacy/zh-cn/support/index.md
similarity index 100%
rename from zh-cn/support/index.md
rename to legacy/zh-cn/support/index.md
diff --git a/zh-tw/3x/api.md b/legacy/zh-tw/3x/api.md
similarity index 100%
rename from zh-tw/3x/api.md
rename to legacy/zh-tw/3x/api.md
diff --git a/zh-tw/4x/api.md b/legacy/zh-tw/4x/api.md
similarity index 100%
rename from zh-tw/4x/api.md
rename to legacy/zh-tw/4x/api.md
diff --git a/zh-tw/5x/api.md b/legacy/zh-tw/5x/api.md
similarity index 100%
rename from zh-tw/5x/api.md
rename to legacy/zh-tw/5x/api.md
diff --git a/zh-tw/advanced/best-practice-performance.md b/legacy/zh-tw/advanced/best-practice-performance.md
similarity index 100%
rename from zh-tw/advanced/best-practice-performance.md
rename to legacy/zh-tw/advanced/best-practice-performance.md
diff --git a/zh-tw/advanced/best-practice-security.md b/legacy/zh-tw/advanced/best-practice-security.md
similarity index 100%
rename from zh-tw/advanced/best-practice-security.md
rename to legacy/zh-tw/advanced/best-practice-security.md
diff --git a/zh-tw/advanced/developing-template-engines.md b/legacy/zh-tw/advanced/developing-template-engines.md
similarity index 100%
rename from zh-tw/advanced/developing-template-engines.md
rename to legacy/zh-tw/advanced/developing-template-engines.md
diff --git a/zh-tw/advanced/healthcheck-graceful-shutdown.md b/legacy/zh-tw/advanced/healthcheck-graceful-shutdown.md
similarity index 100%
rename from zh-tw/advanced/healthcheck-graceful-shutdown.md
rename to legacy/zh-tw/advanced/healthcheck-graceful-shutdown.md
diff --git a/zh-tw/advanced/security-updates.md b/legacy/zh-tw/advanced/security-updates.md
similarity index 100%
rename from zh-tw/advanced/security-updates.md
rename to legacy/zh-tw/advanced/security-updates.md
diff --git a/zh-tw/api.md b/legacy/zh-tw/api.md
similarity index 100%
rename from zh-tw/api.md
rename to legacy/zh-tw/api.md
diff --git a/zh-tw/changelog/index.md b/legacy/zh-tw/changelog/index.md
similarity index 100%
rename from zh-tw/changelog/index.md
rename to legacy/zh-tw/changelog/index.md
diff --git a/zh-tw/guide/behind-proxies.md b/legacy/zh-tw/guide/behind-proxies.md
similarity index 100%
rename from zh-tw/guide/behind-proxies.md
rename to legacy/zh-tw/guide/behind-proxies.md
diff --git a/zh-tw/guide/database-integration.md b/legacy/zh-tw/guide/database-integration.md
similarity index 100%
rename from zh-tw/guide/database-integration.md
rename to legacy/zh-tw/guide/database-integration.md
diff --git a/zh-tw/guide/debugging.md b/legacy/zh-tw/guide/debugging.md
similarity index 100%
rename from zh-tw/guide/debugging.md
rename to legacy/zh-tw/guide/debugging.md
diff --git a/zh-tw/guide/error-handling.md b/legacy/zh-tw/guide/error-handling.md
similarity index 100%
rename from zh-tw/guide/error-handling.md
rename to legacy/zh-tw/guide/error-handling.md
diff --git a/zh-tw/guide/migrating-4.md b/legacy/zh-tw/guide/migrating-4.md
similarity index 100%
rename from zh-tw/guide/migrating-4.md
rename to legacy/zh-tw/guide/migrating-4.md
diff --git a/zh-tw/guide/migrating-5.md b/legacy/zh-tw/guide/migrating-5.md
similarity index 87%
rename from zh-tw/guide/migrating-5.md
rename to legacy/zh-tw/guide/migrating-5.md
index a85c65abb3..ab4f440e7b 100644
--- a/zh-tw/guide/migrating-5.md
+++ b/legacy/zh-tw/guide/migrating-5.md
@@ -99,7 +99,7 @@ Express 5 no longer supports the `app.del()` function. If you use this function,
{% capture codemod-deprecated-signatures %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod v4-deprecated-signatures
```
@@ -109,14 +109,14 @@ npx @expressjs/codemod v4-deprecated-signatures
```js
// v4
-app.del('/user/:id', (req, res) => {
- res.send(`DELETE /user/${req.params.id}`)
-})
+app.del("/user/:id", (req, res) => {
+ res.send(`DELETE /user/${req.params.id}`);
+});
// v5
-app.delete('/user/:id', (req, res) => {
- res.send(`DELETE /user/${req.params.id}`)
-})
+app.delete("/user/:id", (req, res) => {
+ res.send(`DELETE /user/${req.params.id}`);
+});
```
app.param(fn)
@@ -136,7 +136,7 @@ The following method names have been pluralized. In Express 4, using the old met
{% capture codemod-pluralized-methods %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod pluralized-methods
```
@@ -146,22 +146,22 @@ npx @expressjs/codemod pluralized-methods
```js
// v4
-app.all('/', (req, res) => {
- req.acceptsCharset('utf-8')
- req.acceptsEncoding('br')
- req.acceptsLanguage('en')
+app.all("/", (req, res) => {
+ req.acceptsCharset("utf-8");
+ req.acceptsEncoding("br");
+ req.acceptsLanguage("en");
// ...
-})
+});
// v5
-app.all('/', (req, res) => {
- req.acceptsCharsets('utf-8')
- req.acceptsEncodings('br')
- req.acceptsLanguages('en')
+app.all("/", (req, res) => {
+ req.acceptsCharsets("utf-8");
+ req.acceptsEncodings("br");
+ req.acceptsLanguages("en");
// ...
-})
+});
```
app.param(name, fn) 名稱中的前導冒號 (:)
@@ -177,7 +177,7 @@ This potentially confusing and dangerous method of retrieving form data has been
{% capture codemod-req-param %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod req-param
```
@@ -187,22 +187,22 @@ npx @expressjs/codemod req-param
```js
// v4
-app.post('/user', (req, res) => {
- const id = req.param('id')
- const body = req.param('body')
- const query = req.param('query')
+app.post("/user", (req, res) => {
+ const id = req.param("id");
+ const body = req.param("body");
+ const query = req.param("query");
// ...
-})
+});
// v5
-app.post('/user', (req, res) => {
- const id = req.params.id
- const body = req.body
- const query = req.query
+app.post("/user", (req, res) => {
+ const id = req.params.id;
+ const body = req.body;
+ const query = req.query;
// ...
-})
+});
```
res.json(obj, status)
@@ -213,14 +213,14 @@ Express 5 不再支援 `res.json(obj, status)` 簽章。請改以設定狀態,
```js
// v4
-app.post('/user', (req, res) => {
- res.json({ name: 'Ruben' }, 201)
-})
+app.post("/user", (req, res) => {
+ res.json({ name: "Ruben" }, 201);
+});
// v5
-app.post('/user', (req, res) => {
- res.status(201).json({ name: 'Ruben' })
-})
+app.post("/user", (req, res) => {
+ res.status(201).json({ name: "Ruben" });
+});
```
res.jsonp(obj, status)
@@ -231,14 +231,14 @@ Express 5 不再支援 `res.jsonp(obj, status)` 簽章。請改以設定狀態
```js
// v4
-app.post('/user', (req, res) => {
- res.jsonp({ name: 'Ruben' }, 201)
-})
+app.post("/user", (req, res) => {
+ res.jsonp({ name: "Ruben" }, 201);
+});
// v5
-app.post('/user', (req, res) => {
- res.status(201).jsonp({ name: 'Ruben' })
-})
+app.post("/user", (req, res) => {
+ res.status(201).jsonp({ name: "Ruben" });
+});
```
res.redirect(url, status)
@@ -249,14 +249,14 @@ Express 5 no longer supports the signature `res.redirect(url, status)`. Instead,
```js
// v4
-app.get('/user', (req, res) => {
- res.redirect('/users', 301)
-})
+app.get("/user", (req, res) => {
+ res.redirect("/users", 301);
+});
// v5
-app.get('/user', (req, res) => {
- res.redirect(301, '/users')
-})
+app.get("/user", (req, res) => {
+ res.redirect(301, "/users");
+});
```
res.redirect('back') and res.location('back')
@@ -266,7 +266,7 @@ Express 5 no longer supports the magic string `back` in the `res.redirect()` and
{% capture codemod-magic-redirect %}
You can replace the deprecated signatures with the following command:
-```plain-text
+```plaintext
npx @expressjs/codemod magic-redirect
```
@@ -276,14 +276,14 @@ npx @expressjs/codemod magic-redirect
```js
// v4
-app.get('/user', (req, res) => {
- res.redirect('back')
-})
+app.get("/user", (req, res) => {
+ res.redirect("back");
+});
// v5
-app.get('/user', (req, res) => {
- res.redirect(req.get('Referrer') || '/')
-})
+app.get("/user", (req, res) => {
+ res.redirect(req.get("Referrer") || "/");
+});
```
res.send(body, status)
@@ -294,14 +294,14 @@ Express 5 不再支援 `res.send(obj, status)` 簽章。請改以設定狀態,
```js
// v4
-app.get('/user', (req, res) => {
- res.send({ name: 'Ruben' }, 200)
-})
+app.get("/user", (req, res) => {
+ res.send({ name: "Ruben" }, 200);
+});
// v5
-app.get('/user', (req, res) => {
- res.status(200).send({ name: 'Ruben' })
-})
+app.get("/user", (req, res) => {
+ res.status(200).send({ name: "Ruben" });
+});
```
res.send(status)
@@ -314,14 +314,14 @@ If you need to send a number by using the `res.send()` function, quote the numbe
```js
// v4
-app.get('/user', (req, res) => {
- res.send(200)
-})
+app.get("/user", (req, res) => {
+ res.send(200);
+});
// v5
-app.get('/user', (req, res) => {
- res.sendStatus(200)
-})
+app.get("/user", (req, res) => {
+ res.sendStatus(200);
+});
```
res.sendfile()
@@ -341,14 +341,14 @@ app.get('/user', (req, res) => {
```js
// v4
-app.get('/user', (req, res) => {
- res.sendfile('/path/to/file')
-})
+app.get("/user", (req, res) => {
+ res.sendfile("/path/to/file");
+});
// v5
-app.get('/user', (req, res) => {
- res.sendFile('/path/to/file')
-})
+app.get("/user", (req, res) => {
+ res.sendFile("/path/to/file");
+});
```
router.param(fn)
@@ -371,11 +371,11 @@ Use the [`mime-types` package](https://github.com/jshttp/mime-types) to work wit
```js
// v4
-express.static.mime.lookup('json')
+express.static.mime.lookup("json");
// v5
-const mime = require('mime-types')
-mime.lookup('json')
+const mime = require("mime-types");
+mime.lookup("json");
```
express:router debug logs
@@ -407,14 +407,14 @@ Path route matching syntax is when a string is supplied as the first parameter t
```js
// v4
-app.get('/*', async (req, res) => {
- res.send('ok')
-})
+app.get("/*", async (req, res) => {
+ res.send("ok");
+});
// v5
-app.get('/*splat', async (req, res) => {
- res.send('ok')
-})
+app.get("/*splat", async (req, res) => {
+ res.send("ok");
+});
```
{% capture note_wildcard %}
@@ -422,9 +422,9 @@ app.get('/*splat', async (req, res) => {
```js
// v5
-app.get('/{*splat}', async (req, res) => {
- res.send('ok')
-})
+app.get("/{*splat}", async (req, res) => {
+ res.send("ok");
+});
```
{% endcapture %}
@@ -434,30 +434,30 @@ app.get('/{*splat}', async (req, res) => {
```js
// v4
-app.get('/:file.:ext?', async (req, res) => {
- res.send('ok')
-})
+app.get("/:file.:ext?", async (req, res) => {
+ res.send("ok");
+});
// v5
-app.get('/:file{.:ext}', async (req, res) => {
- res.send('ok')
-})
+app.get("/:file{.:ext}", async (req, res) => {
+ res.send("ok");
+});
```
- Regexp characters are not supported. For example:
```js
-app.get('/[discussion|page]/:slug', async (req, res) => {
- res.status(200).send('ok')
-})
+app.get("/[discussion|page]/:slug", async (req, res) => {
+ res.status(200).send("ok");
+});
```
should be changed to:
```js
-app.get(['/discussion/:slug', '/page/:slug'], async (req, res) => {
- res.status(200).send('ok')
-})
+app.get(["/discussion/:slug", "/page/:slug"], async (req, res) => {
+ res.status(200).send("ok");
+});
```
- Some characters have been reserved to avoid confusion during upgrade (`()[]?+!`), use `\` to escape them.
@@ -481,7 +481,7 @@ Example of breaking code:
```js
// v4
-app.use(express.static('public'))
+app.use(express.static("public"));
```
After migrating to Express 5, a request to `/.well-known/assetlinks.json` will result in a **404 Not Found**.
@@ -490,8 +490,11 @@ To fix this, serve specific dot-directories explicitly using the `dotfiles: "all
```js
// v5
-app.use('/.well-known', express.static('public/.well-known', { dotfiles: 'allow' }))
-app.use(express.static('public'))
+app.use(
+ "/.well-known",
+ express.static("public/.well-known", { dotfiles: "allow" }),
+);
+app.use(express.static("public"));
```
This approach allows you to safely serve only the intended dot-directories while keeping the default secure behavior for other dotfiles, which remain inaccessible.
@@ -502,12 +505,12 @@ In Express 5, the `app.listen` method will invoke the user-provided callback fun
For example:
```js
-const server = app.listen(8080, '0.0.0.0', (error) => {
+const server = app.listen(8080, "0.0.0.0", (error) => {
if (error) {
- throw error // e.g. EADDRINUSE
+ throw error; // e.g. EADDRINUSE
}
- console.log(`Listening on ${JSON.stringify(server.address())}`)
-})
+ console.log(`Listening on ${JSON.stringify(server.address())}`);
+});
```
app.router
@@ -532,11 +535,11 @@ The `req.params` object now has a **null prototype** when using string paths. Ho
Wildcards (e.g., `/*splat`) capture path segments as an array instead of a single string.
```js
-app.get('/*splat', (req, res) => {
+app.get("/*splat", (req, res) => {
// GET /foo/bar
- console.dir(req.params)
+ console.dir(req.params);
// => [Object: null prototype] { splat: [ 'foo', 'bar' ] }
-})
+});
```
**Unmatched parameters are omitted:**
@@ -545,25 +548,25 @@ In Express 4, unmatched wildcards were empty strings (`''`) and optional `:` par
```js
// v4: unmatched wildcard is empty string
-app.get('/*', (req, res) => {
+app.get("/*", (req, res) => {
// GET /
- console.dir(req.params)
+ console.dir(req.params);
// => { '0': '' }
-})
+});
// v4: unmatched optional param is undefined
-app.get('/:file.:ext?', (req, res) => {
+app.get("/:file.:ext?", (req, res) => {
// GET /image
- console.dir(req.params)
+ console.dir(req.params);
// => { file: 'image', ext: undefined }
-})
+});
// v5: unmatched optional param is omitted
-app.get('/:file{.:ext}', (req, res) => {
+app.get("/:file{.:ext}", (req, res) => {
// GET /image
- console.dir(req.params)
+ console.dir(req.params);
// => [Object: null prototype] { file: 'image' }
-})
+});
```
req.query
diff --git a/zh-tw/guide/overriding-express-api.md b/legacy/zh-tw/guide/overriding-express-api.md
similarity index 100%
rename from zh-tw/guide/overriding-express-api.md
rename to legacy/zh-tw/guide/overriding-express-api.md
diff --git a/zh-tw/guide/routing.md b/legacy/zh-tw/guide/routing.md
similarity index 100%
rename from zh-tw/guide/routing.md
rename to legacy/zh-tw/guide/routing.md
diff --git a/zh-tw/guide/using-middleware.md b/legacy/zh-tw/guide/using-middleware.md
similarity index 100%
rename from zh-tw/guide/using-middleware.md
rename to legacy/zh-tw/guide/using-middleware.md
diff --git a/zh-tw/guide/using-template-engines.md b/legacy/zh-tw/guide/using-template-engines.md
similarity index 100%
rename from zh-tw/guide/using-template-engines.md
rename to legacy/zh-tw/guide/using-template-engines.md
diff --git a/zh-tw/guide/writing-middleware.md b/legacy/zh-tw/guide/writing-middleware.md
similarity index 100%
rename from zh-tw/guide/writing-middleware.md
rename to legacy/zh-tw/guide/writing-middleware.md
diff --git a/zh-tw/index.md b/legacy/zh-tw/index.md
similarity index 100%
rename from zh-tw/index.md
rename to legacy/zh-tw/index.md
diff --git a/zh-tw/resources/community.md b/legacy/zh-tw/resources/community.md
similarity index 100%
rename from zh-tw/resources/community.md
rename to legacy/zh-tw/resources/community.md
diff --git a/zh-tw/resources/contributing.md b/legacy/zh-tw/resources/contributing.md
similarity index 100%
rename from zh-tw/resources/contributing.md
rename to legacy/zh-tw/resources/contributing.md
diff --git a/zh-tw/resources/glossary.md b/legacy/zh-tw/resources/glossary.md
similarity index 100%
rename from zh-tw/resources/glossary.md
rename to legacy/zh-tw/resources/glossary.md
diff --git a/zh-tw/resources/middleware.md b/legacy/zh-tw/resources/middleware.md
similarity index 100%
rename from zh-tw/resources/middleware.md
rename to legacy/zh-tw/resources/middleware.md
diff --git a/zh-tw/resources/middleware/body-parser.md b/legacy/zh-tw/resources/middleware/body-parser.md
similarity index 100%
rename from zh-tw/resources/middleware/body-parser.md
rename to legacy/zh-tw/resources/middleware/body-parser.md
diff --git a/zh-tw/resources/middleware/compression.md b/legacy/zh-tw/resources/middleware/compression.md
similarity index 100%
rename from zh-tw/resources/middleware/compression.md
rename to legacy/zh-tw/resources/middleware/compression.md
diff --git a/zh-tw/resources/middleware/connect-rid.md b/legacy/zh-tw/resources/middleware/connect-rid.md
similarity index 100%
rename from zh-tw/resources/middleware/connect-rid.md
rename to legacy/zh-tw/resources/middleware/connect-rid.md
diff --git a/zh-tw/resources/middleware/cookie-parser.md b/legacy/zh-tw/resources/middleware/cookie-parser.md
similarity index 100%
rename from zh-tw/resources/middleware/cookie-parser.md
rename to legacy/zh-tw/resources/middleware/cookie-parser.md
diff --git a/zh-tw/resources/middleware/cookie-session.md b/legacy/zh-tw/resources/middleware/cookie-session.md
similarity index 100%
rename from zh-tw/resources/middleware/cookie-session.md
rename to legacy/zh-tw/resources/middleware/cookie-session.md
diff --git a/zh-tw/resources/middleware/cors.md b/legacy/zh-tw/resources/middleware/cors.md
similarity index 100%
rename from zh-tw/resources/middleware/cors.md
rename to legacy/zh-tw/resources/middleware/cors.md
diff --git a/zh-tw/resources/middleware/errorhandler.md b/legacy/zh-tw/resources/middleware/errorhandler.md
similarity index 100%
rename from zh-tw/resources/middleware/errorhandler.md
rename to legacy/zh-tw/resources/middleware/errorhandler.md
diff --git a/zh-tw/resources/middleware/method-override.md b/legacy/zh-tw/resources/middleware/method-override.md
similarity index 100%
rename from zh-tw/resources/middleware/method-override.md
rename to legacy/zh-tw/resources/middleware/method-override.md
diff --git a/zh-tw/resources/middleware/morgan.md b/legacy/zh-tw/resources/middleware/morgan.md
similarity index 100%
rename from zh-tw/resources/middleware/morgan.md
rename to legacy/zh-tw/resources/middleware/morgan.md
diff --git a/zh-tw/resources/middleware/multer.md b/legacy/zh-tw/resources/middleware/multer.md
similarity index 100%
rename from zh-tw/resources/middleware/multer.md
rename to legacy/zh-tw/resources/middleware/multer.md
diff --git a/zh-tw/resources/middleware/response-time.md b/legacy/zh-tw/resources/middleware/response-time.md
similarity index 100%
rename from zh-tw/resources/middleware/response-time.md
rename to legacy/zh-tw/resources/middleware/response-time.md
diff --git a/zh-tw/resources/middleware/serve-favicon.md b/legacy/zh-tw/resources/middleware/serve-favicon.md
similarity index 100%
rename from zh-tw/resources/middleware/serve-favicon.md
rename to legacy/zh-tw/resources/middleware/serve-favicon.md
diff --git a/zh-tw/resources/middleware/serve-index.md b/legacy/zh-tw/resources/middleware/serve-index.md
similarity index 100%
rename from zh-tw/resources/middleware/serve-index.md
rename to legacy/zh-tw/resources/middleware/serve-index.md
diff --git a/zh-tw/resources/middleware/serve-static.md b/legacy/zh-tw/resources/middleware/serve-static.md
similarity index 100%
rename from zh-tw/resources/middleware/serve-static.md
rename to legacy/zh-tw/resources/middleware/serve-static.md
diff --git a/zh-tw/resources/middleware/session.md b/legacy/zh-tw/resources/middleware/session.md
similarity index 100%
rename from zh-tw/resources/middleware/session.md
rename to legacy/zh-tw/resources/middleware/session.md
diff --git a/zh-tw/resources/middleware/timeout.md b/legacy/zh-tw/resources/middleware/timeout.md
similarity index 100%
rename from zh-tw/resources/middleware/timeout.md
rename to legacy/zh-tw/resources/middleware/timeout.md
diff --git a/zh-tw/resources/middleware/vhost.md b/legacy/zh-tw/resources/middleware/vhost.md
similarity index 100%
rename from zh-tw/resources/middleware/vhost.md
rename to legacy/zh-tw/resources/middleware/vhost.md
diff --git a/zh-tw/resources/utils.md b/legacy/zh-tw/resources/utils.md
similarity index 100%
rename from zh-tw/resources/utils.md
rename to legacy/zh-tw/resources/utils.md
diff --git a/zh-tw/starter/basic-routing.md b/legacy/zh-tw/starter/basic-routing.md
similarity index 100%
rename from zh-tw/starter/basic-routing.md
rename to legacy/zh-tw/starter/basic-routing.md
diff --git a/zh-tw/starter/examples.md b/legacy/zh-tw/starter/examples.md
similarity index 100%
rename from zh-tw/starter/examples.md
rename to legacy/zh-tw/starter/examples.md
diff --git a/zh-tw/starter/faq.md b/legacy/zh-tw/starter/faq.md
similarity index 100%
rename from zh-tw/starter/faq.md
rename to legacy/zh-tw/starter/faq.md
diff --git a/zh-tw/starter/generator.md b/legacy/zh-tw/starter/generator.md
similarity index 100%
rename from zh-tw/starter/generator.md
rename to legacy/zh-tw/starter/generator.md
diff --git a/zh-tw/starter/hello-world.md b/legacy/zh-tw/starter/hello-world.md
similarity index 100%
rename from zh-tw/starter/hello-world.md
rename to legacy/zh-tw/starter/hello-world.md
diff --git a/zh-tw/starter/installing.md b/legacy/zh-tw/starter/installing.md
similarity index 100%
rename from zh-tw/starter/installing.md
rename to legacy/zh-tw/starter/installing.md
diff --git a/zh-tw/starter/static-files.md b/legacy/zh-tw/starter/static-files.md
similarity index 100%
rename from zh-tw/starter/static-files.md
rename to legacy/zh-tw/starter/static-files.md
diff --git a/zh-tw/support/index.md b/legacy/zh-tw/support/index.md
similarity index 100%
rename from zh-tw/support/index.md
rename to legacy/zh-tw/support/index.md
diff --git a/netlify.toml b/netlify.toml
new file mode 100644
index 0000000000..ae93185a99
--- /dev/null
+++ b/netlify.toml
@@ -0,0 +1,4 @@
+[build]
+ base = "astro"
+ command = "npm run build"
+ publish = "dist"