Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/haikyuu/inertia-node-adapter
Inertia adapter for express, koa and frameworks on top. Includes a flash middleware as a bonus
https://github.com/haikyuu/inertia-node-adapter
Last synced: 3 months ago
JSON representation
Inertia adapter for express, koa and frameworks on top. Includes a flash middleware as a bonus
- Host: GitHub
- URL: https://github.com/haikyuu/inertia-node-adapter
- Owner: haikyuu
- License: mit
- Created: 2021-01-11T12:49:54.000Z (about 4 years ago)
- Default Branch: main
- Last Pushed: 2021-01-18T14:30:17.000Z (about 4 years ago)
- Last Synced: 2024-10-08T00:49:25.259Z (4 months ago)
- Language: TypeScript
- Size: 238 KB
- Stars: 7
- Watchers: 2
- Forks: 5
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: .github/CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
- awesome-inertiajs - Node.js
- trackawesomelist - Node.js (⭐7)
README
![example workflow name](https://github.com/haikyuu/inertia-node-adapter/workflows/test-and-build/badge.svg)
Note that while this is working software. It's still in very early experimentation stage.
# inertia-node-adapter
Inertia adapter for nodejs - supports Express and Koa.
This is a fork of https://github.com/jordankaerim/inertia-node with added support for koa, flash messages and integration tests that adhere to Inertia protocol.
This also includes a flash middleware for koa and express as a bonus. You can use it or use your own.
## Usage
For working examples, see the `__tests/testServers` folders. It contains two servers in koa and express. Note The code is a bit tangled because it was written for integration tests in mind.
### Koa
```typescript
import { inertiaKoaAdapter as inertia, koaFlash } from 'inertia-node-adapter';
import session from 'koa-session';
import Router from '@koa/router';const version = '1';
app.use(session({ maxAge: 86400000 }, app));
app.use(koaFlash()); // optional, but requires using middleware session beforehand
app.use(
inertia({
version,
html: getHtml,
flashMessages: (ctx) => ctx.flash.flashAll(), // optional, depends on the flash middleware used
})
);
const router = new Router();
// in your router handlers
router.get('/home', async (ctx, next) => {
// if flash middleware was added.
ctx.flash.setFlashMessage('success', 'User created successfully');ctx.Inertia.render({
component: 'home',
props: { name: 1 },
url: '/home',
version,
});
next();
})
app.use(router.routes());
return next();
});
```### Express usage
```typescript
import express from 'express';
import session from 'express-session';const app = express();
app.use(session({ secret: 'secret' }));
const router = express.Router();router.get('/home', async (req, res, next) => {
// if flash middleware was added.
req.flash.setFlashMessage('success', 'User created successfully');req.Inertia.render({
component: 'home',
props: { name: 1 },
url: '/home',
version,
});
});
app.use(flash());
app.use(
inertia({
version,
html: getHtml,
flashMessages: (req) => req.flash.flashAll() },
})
);
app.use(router);
```## Usage details
`inertia-node` expects two arguments:
1. `html`: a function that receives the Inertia `page` object and an optional `viewData` object that you can populate with additional data. The function should return an HTML string.
2. `version` (optional): your current asset versionIt will return a standard Node.js middleware that you can use with Express.js, Polka etc (or koa if you're using koa adapter). Functions can be accessed from the `Inertia` object that will be added to the `request` / `context`. You can chain functions together but you can't call another function after calling [`render`](#renderPage) or [`redirect`](#redirectUrl).
**Note:** In your HTML view function make sure to always stringify the `page` object and include it in the `data-page` attribute of the HTML node you want to render your JavaScript app in. For more infos on how Inertia works read [the protocol](https://inertiajs.com/the-protocol) on the Inertia website.
## API
### setViewData(data)
1. `data`, _Object_ - An Object of additional data you want to pass to your HTML view function
`setViewData` can be used to pass additional data to your [HTML view function](#usage) such as the page's title or other meta data.
```javascript
.use(({ Inertia }, _, next) => {
Inertia.setViewData({
title: "Todo App",
description:"A Web App to Create and Manage To-dos"
})next();
})// ...
const html = (page, viewData) => `
${viewData.title}
`;
```### shareProps(props)
1. `props`, _Object_ - An object of props you want to include with every `render` call
Shared props are props that will be combined with the props you pass to the [`render`](#renderPage) function. When you call `shareProps` more than once, props shared from previous calls will be merged with props from any subsequent calls.
```javascript
.use(({ Inertia }, _, next) => {
Inertia.shareProps({ username: "ironMan" })
next();
})
.get("/todo", ({ Inertia }) => {
Inertia.render({
component: "Todo",
props: {
todo: [
{ text: "Study Korean", done: false },
{ text: "Cook Arabic food", done: false },
]
}
// JavaScript component on the client will receive
// {
// username: "ironMan",
// todo: [
// { "Study Korean", done: false },
// { "Cook Arabic food", done: false },
// ]
// }
});
})
```### setHeaders(headers)
1. `headers`, _Object_ - An Object of custom headers you want to include in your response
Add custom headers to your response.
**Note:** Headers that are required by Inertia take precedence and cannot be overwritten.
```javascript
.get("/", ({ Inertia }) => {
Inertia
.setHeaders({
token: "7pTgHCv0JgeAyyBRDpUi"
})
.render({
component: "Index",
props: { username: "ironMan" }
});
})
```### setStatusCode(statusCode)
1. `statusCode`, _number_ - The response's status code
Change the status code when sending a response. Useful for e.g. when you want to render an error. Headers set from previous calls will be merged with headers set from any subsequent calls.
```javascript
.get("/", ({ Inertia }) => {
Inertia.render({
component: "Index",
props: { username: "ironMan" }
});
})
.use(({ Inertia }) => {
Inertia
.setStatusCode(404)
.render({
component: "Error",
props: { message: "Page not found" },
});
})
```### render(page)
1. `page`, _Object_ - the Inertia page object
This function will send your response as either a HTML or JSON string to the client depending on wether the client is requesting your page for the first time or is making a subsequent Inertia request.
The Inertia page object consists of the following properties:
1. `component`, _string_ - The name of the JavaScript component to render on the client
2. `props`, _Object_ - The page props (data)
3. `url`, _string_ - The URL of the route. This will be automatically added by the middleware.
4. `version`, _string_ - The asset version. This will be automatically added by the middleware.```javascript
.get("/todo", ({ Inertia }) => {
Inertia.render({
component: "Todo",
props: {
todo: [
{ text: "Study Korean", done: false },
{ text: "Cook Arabic food", done: false },
]
},
});
})
```On Partial Reloads only props requested by the client will be sent. To improve performance on the server you can wrap each prop inside a function so that they will only be evaluated when necessary.
```javascript
.get("/todo", ({ Inertia }) => {
const todoArray = async () => await database.getTodo();
const bookmarks = async () => await database.getBookmarks();Inertia.render({
component: "Todo",
props: {
todoArray,
bookmarks
},
});
})
```Now when the client only requests `todoArray` the middleware will hit the database only once and not call `bookmarks`.
### redirect(url)
1. `url`, _string_ - The URL to redirect to
Redirect the client to a different URL.
```javascript
.post("/todo", (req, res) => {
database.createTodo(req.body);
req.Inertia.redirect("/todo");
})
```**Note:** Inertia requires you to use a `303` status code when redirecting upon a `PUT`, `PATCH` or `DELETE` request and a `302` status code otherwise. The `redirect` function will automatically take care of this for you. If you handle redirects yourself make sure to select the correct status code.
**Note:** Calling [`setStatusCode`](#renderPage) before [`redirect`](#redirectUrl) has no effect.
## Credits
- [Jordan Kaerim](https://github.com/jordankaerim).