Indiekit.addEndpoint
An endpoint plug-in adds new routes to an Indiekit server. Routes can add new pages to the web interface, or provide API endpoints that support IndieWeb (or other) protocols or APIs.
Constructor
Property | Type | Description |
---|---|---|
id | String | Kebab-cased plug-in ID. Required. |
meta | i | Required. |
name | String | Human readable plug-in name. Required. |
options | Object | Plug-in options. Optional. |
Properties
Property | Type | Description |
---|---|---|
mountPath | String | Path to mount routes onto. Required. |
navigationItems | Object or Array | Add navigation items to the web interface. Optional. |
routes | Router | Plug-in routes that require authentication to access. Optional. |
routesPublic | Router | Plug-in routes that can be publicly accessed. Optional. |
routesWellKnown | Router | Plug-in routes that can be accessed at /.well-known/ . Optional. |
mountPath
Path to mount routes onto.
get mountPath() {
return "/example";
}
get mountPath() {
return "/example";
}
navigationItems
Add items to the web interface’s navigation menu using the navigationItems
property. For example, to add a link to the /example
path:
get navigationItems() {
return {
href: this.mountPath,
text: "Example",
};
}
get navigationItems() {
return {
href: this.mountPath,
text: "Example",
};
}
navigationItems
will accept either an Object
or an Array
. Use an Array
if you want to add multiple items to the navigation menu, for example:
get navigationItems() {
return [{
href: this.mountPath,
text: "Example",
}, {
href: this.mountPath + "/page",
text: "Example page",
}];
}
get navigationItems() {
return [{
href: this.mountPath,
text: "Example",
}, {
href: this.mountPath + "/page",
text: "Example page",
}];
}
Each object in navigationItems
should return the following values:
Property | Type | Description |
---|---|---|
href | String | The value of the navigation link’s href attribute. Required. |
text | String | Text of the navigation link. Required. |
requiresDatabase | Boolean | Whether feature requires a database. Optional, defaults to false . |
Note that, if your plug-in is localised, the text
value should be the key path to the corresponding localisation string, for example:
get navigationItems() {
return {
href: this.mountPath,
text: "example.navigation.label",
};
}
get navigationItems() {
return {
href: this.mountPath,
text: "example.navigation.label",
};
}
routes
Routes can be added to Indiekit’s Express server by providing an instance of an Express Router
with the paths and methods you wish to support.
For example, given a mountPath
of /example
, to accept a POST
request at /example/secret
, add the following:
get routes() {
router.post("/secret", (req, res, next) => {…});
return router;
}
get routes() {
router.post("/secret", (req, res, next) => {…});
return router;
}
routesPublic
The routes
method attaches routes to Indiekit’s own router after rate limiting and IndieAuth authentication middleware. Any request to your endpoint path will therefore require a user to be signed in or otherwise authenticated.
You can bypass authentication by using the routesPublic
method.
For example, given a mountPath
of /example
, to accept an unauthenticated GET
request at /example/public
, add the following:
get routesPublic() {
router.get("/public", (req, res, next) => {…});
return router;
}
get routesPublic() {
router.get("/public", (req, res, next) => {…});
return router;
}
routesWellKnown
Sometimes its necessary to serve requests to .well-known paths, standardized locations for discovering domain-wide metadata (see this registry of Well-Known URIs).
The routesWellKnown
method allows you to add resources at this location.
For example, to accept a GET
request at /.well-known/posh/spice.json
, add the following:
get routesWellKnown() {
router.get("/posh/spice.json", (req, res, next) => {…});
return router;
}
get routesWellKnown() {
router.get("/posh/spice.json", (req, res, next) => {…});
return router;
}
Example
import express from "express";
const router = express.Router();
export default class ExampleEndpoint {
constructor() {
this.id = "example-endpoint";
this.meta = import.meta;
this.name = "Example endpoint";
this.mountPath = "/example";
}
get navigationItems() {
return {
href: this.mountPath,
text: "Example",
};
}
get routes() {
router.post("/secret", (req, res, next) => {…});
return router;
}
get routesPublic() {
router.get("/public", (req, res, next) => {…});
return router;
}
get routesWellKnown() {
router.get("/posh/spice.json", (req, res, next) => {…});
return router;
}
init(Indiekit) {
Indiekit.addEndpoint(this);
}
}
import express from "express";
const router = express.Router();
export default class ExampleEndpoint {
constructor() {
this.id = "example-endpoint";
this.meta = import.meta;
this.name = "Example endpoint";
this.mountPath = "/example";
}
get navigationItems() {
return {
href: this.mountPath,
text: "Example",
};
}
get routes() {
router.post("/secret", (req, res, next) => {…});
return router;
}
get routesPublic() {
router.get("/public", (req, res, next) => {…});
return router;
}
get routesWellKnown() {
router.get("/posh/spice.json", (req, res, next) => {…});
return router;
}
init(Indiekit) {
Indiekit.addEndpoint(this);
}
}
Example endpoint plug-ins:
@indiekit/endpoint-auth
adds supports for granting and verifying IndieAuth tokens and authenticating users.@indiekit/endpoint-share
adds a share page to Indiekit’s web interface.