A customizable yet simple, GitHub-hosted, React-powered, and Markdown-supported blogging system that is easily integrated into existing sites and applications. Used by Ptorx and other projects in the Xyfir Network.
- Xyfir Network Blog
- Ptorx Blog
- Have a blog that uses
@xyfir/blog
? Add it to this list and submit a PR!
Note: This package is currently in alpha, meaning its API may change significantly in the future. Backwards compatibility will be strived for, but cannot be guaranteed.
See the example directory for a working, up-to-date, example.
npm install @xyfir/blog
Then, somewhere in your React application:
import Blog from '@xyfir/blog';
// ...
<Blog
// (optional) ID of the post being viewed
// You'll have to handle extracting the id from the current URL based on your
// `linkFormat` prop!
post="group/year/month/filename"
// (optional) Groups from the repo to allow posts from.
// Defaults to allowing all groups.
// A "group" is a subdirectory in the GitHub repository
groups={['group1', 'group2']}
// (required) GitHub repository id.
// Example: `":user/:repo" | "Xyfir/blog-posts"`
repository="GitHubUser/GitHubRepository"
// (required) Format to use for blog links
// Example: `"/blog/{{post.id}}" | "/blog?id={{post.id}}"`
linkFormat="/blog/{{post.id}}"
// (optional) Format to use for the page title (`<title>`).
// The first element is for when _not_ viewing a post, and the second element
// is for when the user _is_ viewing a post.
// All post properties are allowed: post.id, post.author, ...
titleFormat={['Example Blog', '{{post.title}} - Example Blog']}
// (optional) Passed to `marked('', markedOptions)` when converting Markdown
// to HTML. See: https://marked.js.org
// Nothing passed by default, meaning Markdown is NOT sanitized
markedOptions={{}}
// (optional) Format to use for the page description
// (`<meta name="description" content="..." >`)
// The first element is for when _not_ viewing a post, and the second element
// is for when the user _is_ viewing a post.
// All post properties are allowed: post.id, post.author, ...
descriptionFormat={[
'The best blog in the whole wide world.',
'{{post.description}}'
]}
/>;
// ...
That's pretty much it in terms of code, but you'll have to style everything yourself. Optionally, you can use the default styles which you can import from node_modules/@xyfir/blog/dist/blog.css
, which pairs nicely with the GitHub Markdown styles as found in github-markdown-css.
You should have a public GitHub repository created which you'll point to in <Blog>
's repository
prop. The repository should have a structure that looks something like this:
some-group/
2017/
02/
some-post.md
another-post.md
04/
hello-world.md
2018/
01/
hello-world.md
12/
lorem-ipsum.md
some-other-group/
...
posts.json
The first subdirectories within the repository are your "groups", which allow you to optionally organize things however you want. For Xyfir, we use it to organize posts by site name, since we have lots of sites but want all of our posts in a single repository. You can do whatever you want however.
Within groups, are year subdirectories, simply YYYY
-formatted years. Within year subdirectories are month subdirectories, simply MM
-formatted months.
Finally, within the month subdirectories are the posts themselves, which can be named anything you want but generally should be URL-friendly and contain at least part of the post's title. Post names must only be unique within the subdirectory that they reside.
posts.json
allows you to make posts publicly available to the <Blog>
component by adding the post's metadata to its array. The posts.json
array should look something like this:
[
{
"id": "test/2018/07/test-2",
"group": "test",
"title": "Test #2",
"author": "Bob",
"posted": "2018-07-13",
"description": "Lorem ipsum dolor sit amet..."
},
{
"id": "test/2018/07/test-1",
"group": "test",
"title": "Test #1",
"author": "Alice",
"posted": "2018-07-12",
"edited": "2018-07-13",
"canonical": "https://www.xyfir.com/blog/test/2018/07/test-1"
}
]
Order doesn't matter, but we generally recommend putting the newest posts at the top.
id
- required - A post id is a unique identifier for each post of the following format:group/year/month/filename
. Note thatfilename
excludes the.md
extension!group
- required - The group the post resides in.title
- required - The post's title.author
- required - The post's author.posted
- required - The date the post was posted. Format:YYYY-MM-DD
.edited
- optional - The date the post was edited. Format:YYYY-MM-DD
.canonical
- optional - The canonical link for the post if it is available at multiple locations. See Wikipedia: Canonical link element.description
- optional - A (typically short) description for the post.
To create, edit, or delete a post is easy: add/edit/delete the file within the repository at group/year/month/filename
, and then update posts.json
to reflect the changes if needed, and then commit and push your changes to the live repository. All of the blogs that point to that repository will automatically be updated upon the next page load.