Preview, commit and push to git from Darkmatter

Previously, for Darkmatter to open the entry you’re editing in the browser, you would need to run an Astro dev server yourself. Also, when you would finish writing, you’d need to go to the terminal again, commit the changes and push to deploy.

Now the entire content editing process can happen fully inside Darkmatter, end to end.

Commit and push

I’ve added a simple UI to commit and push your changes without leaving Darkmatter. You’ll notice a new button with a cloud icon in the top right corner when editing a collection entry.

publish-button.png

It opens a dialog to describe the changes you’ve made, which will be used as a commit message. There’s also a list of files to be included in this commit, in case you want to leave something out of this deploy. CleanShot 2023-08-19 at 11.53.59@2x.png

Darkmatter has some basic safe guards in place to make sure this feature is working, but I decided to keep merge conflict handling out of scope to ship sooner.

Automatic start/stop of Astro dev server

Before publishing content, you might want to preview how it looks on the actual website. To do that, you can press the button with an eye icon in the top right.

Darkmatter would detect the port of the running Astro dev server and open the page for the current entry in the browser. However, if you haven’t started the dev server yourself, it would trigger an error and nothing would happen.

This feature just got whole lot better. If there’s no Astro dev server running, Darkmatter will just start its own, on a random available port. When Darkmatter quits, dev server shuts down. Easy peasy.

Configurable entry preview URLs

Darkmatter assumes that the name of the content collection matches the route where its entries can be viewed. For example, if there’s a “posts” content collection, it’s assumed that each post can be viewed at /posts/[slug] route.

However, that’s not always the case. I have blog posts defined in a “posts” content collection, but my website displays them on the /blog/[slug] route. If I tried opening the blog post I was editing from Darkmatter, it’d open “/posts/abc” page, which would show a 404 page.

To solve this, the base path portion of the preview URLs can be configured with the new darkmatter exports from your src/content/config.js file and defineDarkmatterCollections() function from darkmatter-sdk.

import {z as zod, defineCollection} from 'astro:content';
import {defineDarkmatterCollections} from 'darkmatter-sdk';

const posts = defineCollection({
  schema: zod.object({
    title: zod.string()
  });
});

export const collections = {posts};

export const darkmatter = defineDarkmatterCollections({
  posts: {
    basePath: '/blog'
  }
});

Now that base path of the “posts” collection is “/blog”, Darkmatter will start opening /blog/[slug] URLs instead of /posts/[slug].

In the future releases I plan to make this more flexible and let you configure the entire preview URL, not just the base path before the slug.

Thanks to these updates, there’s no need to keep the terminal open side by side with Darkmatter anymore. I was reluctant to add these features at first, but I already feel how much they speed up my writing workflow.

I believe they’ll have an especially big impact for non-technical users. You could clone your website repository for them once, install Darkmatter on their machine and let them write and publish content. You retain full control over the technical side of the website, while your team members or clients have the freedom to manage the content in a nice UI without ever touching the code or git.

New field types

There are also two new field types that shipped this week - multi-line text field and date time field. Let’s check them out.

Multi-line text field

Darkmatter displays zod.string() fields as single-line inputs by default. However, for fields like “Description” or “Excerpt” it’d be better to show them as multi-line inputs for a more comfortable editing.

With a new darkmatter-sdk package, you can use a text() function to define a multi-line text field in your collection schema.

import {z as zod, defineCollection} from 'astro:content';
import {text} from 'darkmatter-sdk';

const posts = defineCollection({
  schema: zod.object({
    title: zod.string(),
    description: text()
  });
});

export const collections = {posts};

68747470733a2f2f6765746461726b6d61747465722e6465762f72656c656173652d6e6f7465732f6d756c74692d6c696e652d746578742d6669656c642e706e67.png

text() function returns the same ZodString instance as zod.string(), so the Zod API stays the same.

Date time field

Last release changed zod.date() fields to only set the calendar date, without the time part. The new darkmatter-sdk package mentioned earlier exposes a dateTime() function to define the same field, but with an option to set hours and minutes.

import {z as zod, defineCollection} from 'astro:content';
import {dateTime} from 'darkmatter-sdk';

const posts = defineCollection({
  schema: zod.object({
    title: zod.string(),
    date: dateTime()
  });
});

export const collections = {posts};

68747470733a2f2f6765746461726b6d61747465722e6465762f72656c656173652d6e6f7465732f646174652d74696d652d6669656c642e706e67.png

As with text(), dateTime() function returns the same ZodDate instance as zod.date(), so the Zod API stays the same too.

Defining such fields requires a darkmatter-sdk package, because there’s no way for Darkmatter to tell otherwise whether you want zod.string() field to be a single or a multi line input.


At this point I completed all the major items I had on my launch roadmap. Next week I’m going to focus on implementing license keys, updating the website, writing documentation and polishing.

Launch day is getting close!

Follow the development

Darkmatter is in active development and may launch next month. Follow the updates, get early access and watch the building process.

If email is not your thing, read the blog or follow on Twitter.