@indiekit/frontend v1.0.0-beta.16
Indiekit
Indiekit is a small but powerful server that acts as the go-between your website and the wider independent web. Using IndieWeb protocols and standards, Indiekit lets you:
- publish content to your website using applications like iAWriter, Micro.blog, Icro, Indigenous and other tools that support the Micropub API
accept likes, comments and other feedback on your content using Webmentionssyndicate content to social networks like Twitter, Mastodon and LinkedIn
Quick start
The easiest way to get started is to deploy this application to Heroku.
This assumes you’ll be saving files to GitHub and publishing to a Jekyll (or similar) static site generator.
Clicking the button below will guide you through the process.
You’ll be asked to provide the following values:
GITHUB_TOKEN
- A GitHub personal access tokenGITHUB_USER
- Your username on GitHubGITHUB_REPO
- Name of the repository where you want to save filesPUBLICATION_URL
- URL of the website you want to publish to
Contents
Requirements
- Node.js v12+
Features
- Create, update and delete posts
- Upload files
- Configure different post types
- Accept post status and visibility
- Review previously published posts and files
- Bookmarklet to save and share bookmarks
- Publish to different content stores (GitHub and GitLab)
- Support for popular static site generators (Jekyll, Hugo, 11ty)
Plugin API
Install
npm install @indiekit/indiekit
Usage
Set up your server
Create a configuration file, indiekit.config.js
, setup Indiekit and export its server:
import {Indiekit} from '@indiekit/indiekit';
// Create a new indiekit instance
const indiekit = new Indiekit();
// Create a server
const server = indiekit.server();
// Export server
export default server;
Start the server with node indiekit.config.js
.
Indiekit can now listen for Micropub requests, but a few bits of information are needed before it can publish content to your website.
Configure your publication
Indiekit needs to know your website’s URL. You can provide this information using Indiekit’s configuration API, like so:
indiekit.set('publication.me', 'https://paulrobertlloyd.com');
Add a publication preset
Indiekit needs to know what post types you want to publish (for example notes and photos) and in which format. This information can be provided by setting publication.postTypes
and publication.postTemplate
. See Configuring post types and Creating a post template.
A publication preset plugin can provide default values for these options (which you can override in your configuration file).
If you use the Jekyll static site generator, you can install the Jekyll plugin:
npm install @indiekit/preset-jekyll
Then add it to your configuration file:
import {JekyllPreset} from '@indiekit/preset-jekyll';
const jekyll = new JekyllPreset();
indiekit.set('publication.preset', jekyll);
Add a content store
Indiekit needs to know where to store your posts and media files. A content store plugin provides this functionality.
If you are saving your files to GitHub, install the GitHub plugin:
npm install @indiekit/store-github
Then add it to your configuration file:
import {GithubStore} from '@indiekit/store-github';
const github = new GithubStore({
user: 'username', // Your username on GitHub
repo: 'reponame', // Repository files will be saved to
branch: 'main', // Branch to publish to
token: 'token' // GitHub personal access token
});
indiekit.set('publication.store', github);
Example configuration
With all these settings in place, your configuration file will look something like this:
import {Indiekit} from '@indiekit/indiekit';
import {JekyllPreset} from '@indiekit/preset-jekyll';
import {GithubStore} from '@indiekit/store-github';
// Create a new indiekit instance
const indiekit = new Indiekit();
// Configure GitHub content store
const github = new GithubStore({
user: 'username', // Your username on GitHub
repo: 'reponame', // Repository files will be saved to
branch: 'main', // Branch to publish to
token: 'token' // GitHub personal access token
});
// Configure Jekyll publication preset
const jekyll = new JekyllPreset();
// Configure publication
indiekit.set('publication.me', 'https://paulrobertlloyd.com');
indiekit.set('publication.preset', jekyll);
indiekit.set('publication.store', github);
// Create a server
const server = indiekit.server();
// Export server
export default server;
Enable automatic discovery
To ensure Indiekit’s endpoint can be discovered by Micropub clients (and have permission to post to your website), you need to add the follow values to your website’s <head>
:
<link rel="micropub" href="[INDIEKIT_URL]/micropub">
<link rel="authorization_endpoint" href="https://indieauth.com/auth">
<link rel="token_endpoint" href="https://tokens.indieauth.com/token">
Options
application.locale
The language used in the application interface. Available languages: en
Type: string
\
Optional, defaults to en
application.mongodbUrl
To cache files and save information about previously posts and files, you will need to connect Indiekit to a MongoDB database. You can host one on MongoDB Atlas.
Type: URL
\
Optional
application.name
The name of your server.
Type: string
\
Optional, defaults to Indiekit
application.themeColor
Accent colour used in the application interface.
Type: string
\
Optional, defaults to #0000ee
publication.categories
A list of categories or tags used on your website. Can be an array of values, or the location of a JSON file providing an array of values.
Type: Array | URL
\
Optional
publication.locale
Your publication’s locale, this value is currently used to format dates.
Type: string
\
Optional, defaults to value in application.locale
publication.me
Your website’s URL.
Type: URL
\
Required
publication.mediaEndpoint
Indiekit provides a media endpoint, but you can use a third-party endpoint by setting a value for this option.
Type: URL
\
Optional
publication.postTemplate
A post template is a function that takes post properties received and parsed by the Micropub endpoint and renders them in a given file format, for example, a Markdown file with YAML frontmatter.
Type: Function
\
Optional, defaults to MF2 JSON
publication.postTypes
A set of default paths and templates for different post types. See Configuring post types.
Type: Array
\
Optional if using a preset
publication.preset
A publication preset plugin.
Type: Function
\
Optional
publication.slugSeparator
The character used to replace spaces when creating a slug.
Type: string
\
Optional, defaults to -
publication.store
A content store plugin.
Type: Function
\
Required
publication.sydnicationTargets
An array of syndication targets. Example:
[{
uid: 'https://twitter.com/paulrobertlloyd/',
name: 'Paul Robert Lloyd on Twitter'
}, {
uid: 'https://mastodon.social/@paulrobertlloyd',
name: 'Paul Robert Lloyd on Mastodon'
}, {
uid: 'https://micro.blog/paulrobertlloyd',
name: 'Paul Robert Lloyd on Micro.blog'
}]
Type: Array
\
Optional
publication.timeZone
The time zone for your publication. By default this is set to UTC
, however if you want to offset dates according to your time zone you can provide a time zone name, for example, Europe/London
:
indiekit.set('publication.timeZone', 'Europe/London');
Some servers will have a time zone saved in the TZ
environment variable. In which case, you could supply that value instead:
indiekit.set('publication.timeZone', process.env.TZ);
Type: string
\
Optional, defaults to UTC
publication.tokenEndpoint
An IndieAuth token endpoint.
Type: URL
\
Optional, defaults to https://tokens.indieauth.com/token
Configuring post types
Micropub clients let you publish a variety of post types, and Indiekit lets you decide how these different types are handled. You can do this by using a publication preset, configuring values manually, or a combination of both.
For example, to use the Jekyll preset but override the note
and photo
post types, you would use the following configuration:
import {JekyllPreset} from '@indiekit/preset-jekyll';
// Use a preset
const jekyll = new JekyllPreset();
indiekit.set('publication.preset', jekyll);
// Override preset post type
indiekit.set('publication.postTypes', [{
type: 'note',
name: 'Journal entry',
post: {
path: '_journal/{yyyy}-{MM}-{dd}-{slug}.md',
url: 'journal/{yyyy}/{MM}/{slug}'
},
}, {
type: 'photo',
name: 'Photograph',
post: {
path: '_photos/{yyyy}-{MM}-{dd}-{slug}.md',
url: 'photos/{yyyy}/{MM}/{slug}'
},
media: {
path: 'media/photos/{yyyy}/{filename}',
}
}]);
Each post type can take the following values:
type
: The IndieWeb post type.name
: The name you use for this post type on your own site. You needn’t specify this value, but some Micropub clients use it in their publishing interfaces.post.path
: Where posts should be saved in your repository.post.url
: Permalink (the URL path) for posts on your website.media.path
: Where media files should be saved in your repository. This applies only tophoto
,video
andaudio
post types.media.url
: Public accessible URL for media files. This can use the same template variables asmedia.path
. If no value is provided, defaults tomedia.path
.
Creating custom paths and URLs
Both path
and url
values can be customised using the following date tokens:
Token | Description |
---|---|
y | Calendar year, eg 2020 |
yyyy | Calendar year (zero-padded), eg 2020 |
M | Month number, eg 9 |
MM | Month number (zero-padded), eg 09 |
MMM | Month name (abbreviated), eg Sep |
MMMM | Month name (wide), eg September |
w | Week number, eg 1 |
ww | Week number (zero-padded), eg 01 |
D | Day of the year, eg 1 |
DDD | Day of the year (zero-padded), eg 001 |
D60 | Day of the year (sexageismal), eg 57h |
d | Day of the month, eg 1 |
dd | Day of the month (zero-padded), eg 01 |
h | Hour (12-hour-cycle), eg 1 |
hh | Hour (12-hour-cycle, zero-padded), eg 01 |
H | Hour (24-hour-cycle), eg 1 |
HH | Hour (24-hour-cycle, zero-padded), eg 01 |
m | Minute, eg 1 |
mm | Minute (zero-padded), eg 01 |
s | Second, eg 1 |
ss | Second (zero-padded), eg 01 |
t | UNIX epoch seconds, eg 512969520 |
T | UNIX epoch milliseconds, eg 51296952000 |
The following template tokens are available for post paths and URLs:
Token | Description |
---|---|
slug | Provided slug, slugified name or a 5 character string, eg ycf9o |
uuid | A random UUID |
The following template tokens are available for media file paths and URLs:
Token | Description |
---|---|
basename | 5 character alpha-numeric string, eg w9gwi |
ext | File extension of uploaded file, eg jpg |
filename | basename plus ext , eg w9gwi.jpg |
originalname | Original name of uploaded file, eg flower.jpg |
uuid | A random UUID |
Creating a post template
A post template is a function that takes post properties received and parsed by the Micropub endpoint and renders them in a given file format, for example, a Markdown file with YAML frontmatter. You can see examples of this function in the Jekyll and Hugo presets:
Plugins
Endpoints
The following endpoints are included by default:
Content stores
Publication presets
Local development
npm start
If you’re developing a new feature, and want the application to automatically restart whenever a file change is detected, use npm run dev
.
Testing
npm test
The following environment variables need to be set before running tests:
TEST_PUBLICATION_URL
TEST_BEARER_TOKEN
TEST_BEARER_TOKEN_NOSCOPE
TEST_BEARER_TOKEN
and TEST_BEARER_TOKEN_NOSCOPE
provide IndieAuth access tokens whose me
value matches that set in TEST_PUBLICATION_URL
.TEST_BEARER_TOKEN
should provide scoped permissions create update delete
, whereas TEST_BEARER_TOKEN_NOSCOPE
should provide no permissions at all.
Homebrew Access Token is a useful tool for creating access tokens for this purpose.
Credits
Developed by Paul Robert Lloyd.
Thank-you to Aron Carroll for mentoring me during the development of this project. Indiekit is a much better project for his feedback and advice.
Similar projects
Indiekit is inspired by similar projects made by members of the IndieWeb community, all of which you are encouraged to try:
7 days ago
7 days ago
11 days ago
16 days ago
17 days ago
18 days ago
18 days ago
2 months ago
2 months ago
10 months ago
9 months ago
6 months ago
6 months ago
11 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago