Originally posted athuwfulcher.com
Introduction
TinaCMS, the successor toForestry has just gone to v1.0, bringing a stable, open-source, git based CMS to static sites. I've just started using TinaCMS withmy site and I'm actually writing this post using it!
While there issome documentation on adding TinaCMS to a non-NextJS site there are few extra steps that are needed to get it working nicely with Jekyll.
1. Install TinaCMS
npx @tinacms/cli@latest init
Note: Docs as of (10/11/2022) specify a --static flag, this is removed and won't work- Choose whatever package manager is preferable
- Choose
Other
when asked for a framework - (Optional) Use Typescript, it is recommended
- When asked where public assets are stored specify the top level with
/
. Jekyll considers all folders that are not prefixed with_
to be public. Storing tina in theassets
folder will cause issues with pathing later on.
2. Configure TinaCMS
a) Update package.json
Replace the contentscripts
with the following (or add based on what you need):
"dev": "tinacms dev -c \"bundle exec jekyll serve\"","build": "tinacms build && jekyll build",
Runnpm run dev
to check no errors are present. You should be able to navigate tolocalhost:4000/admin/
and see the TinaCMS interface.
Theadmin
folder should be at the top level of the directory.
b) Edit schema
At this point TinaCMS is looking atcontent/posts
for the.md
files to display and edit. For Jekyll this path should be_posts/
. To fix this we can edit theconfig.ts
file in.tina
.
i. Update media folder
TinaCMS supports uploading and embedding media in your markdown documents from the web editor. Themedia
property inconfig.ts
controls where this folder is placed. For Jekyll, this should be underassets
. Changemedia
to:
media: { tina: { mediaRoot: "uploads", publicFolder: "assets", },},
You can change themediaRoot
name to whatever you like, this specifies the folder name underassets
.
ii. Update schema path
Underschema
the different types of content are defined as a list ofcollections
. The only collection present when first creating TinaCMS ispost
. Each collection will have apath
variable that defines where TinaCMS should look for the associated files. Update this to_posts
.
Once done yourcollections
should look like this:
collections: [ { name: "post", label: "Posts", path: "_posts", fields: [ { type: "string", name: "title", label: "Title", isTitle: true, required: true, }, { type: "rich-text", name: "body", label: "Body", isBody: true, }, ], },],
iii. Tidy up existing posts
Depending on if you're doing a fresh Jekyll install or already have an existing blog, TinaCMS prefers filenames to be.md
rather than.markdown
. Update those accordingly.
Now when you accesslocalhost:4000/admin/
and gotPosts
you should see your existing markdown files.
iv. Updating the schema
At this point you can happily use TinaCMS to update or create new markdown files but it will be restricted to only being able to interact with the title and body. If you have any additional frontmatter it will ignore it. To resolve this you can update thefields
section of yourconfig.ts
. Using the starter jekyll site I've created one below:
fields: [ { type: "string", name: "layout", label: "Layout", required: true, }, { type: "string", name: "title", label: "Title", isTitle: true, required: true, }, { type: "datetime", name: "date", label: "Date", required: true, }, { type: "string", name: "categories", label: "Categories", }, { type: "rich-text", name: "body", label: "Body", isBody: true, },],
Go ahead and try creating a new markdown file using the editor. You should see it appear in_posts
but there's a snag... Jekyll requires a specific naming convention to know which markdown files it should show:
YEAR-MONTH-DAY-title.md
Thankfully, TinaCMS allows us to customise our own filename conventions. Add the following to yourpost
collection just afterpath
:
ui: { filename: { readonly: false, slugify: values => { const date = new Date(); const day = date.getDate(); const month = date.getMonth() + 1; const year = date.getFullYear(); let currentDate = `${year}-${month}-${day}`; return `${currentDate}-${values?.title?.toLowerCase().replace(/ /g, '-')}` } }},
This will take the title you specify, slugify it and prefix it with the current date. When you save files they will be in the correct format for Jekyll to find!
Wrapping up
This just scratches the surface of the customisation you can do with TinaCMS. It has the ability to add custom components, fields, templates and a whole lot more. If something in this guide doesn't work get in touch with any of the social links below and I'll see if I can help.
References
Top comments(3)

Thanks for the article! What can you say about drafts, how to solve them? If I put the md file without a date in the posts folder, can it work?

- Email
- LocationCardiff
- EducationMSc Data Science & Analytics, BSc Computer Science
- WorkSenior Software Engineer
- Joined
Hey David! Yes you can use a field called published in the front matter.
Jekyll recognises this automatically so there's no need for custom logic to filter out drafts!
For further actions, you may consider blocking this person and/orreporting abuse