DEV Community

Cover image for dev.to can schedule posts from front matter. Its own documentation doesn't mention the field
Juan Camilo Auriti
Juan Camilo Auriti

Posted on AI-assisted

dev.to can schedule posts from front matter. Its own documentation doesn't mention the field

I wanted to queue two weeks of posts instead of remembering to publish one every morning. So I went looking for how to schedule on dev.to.

The editor guide mentions scheduled posts exactly once, in passing — "Links to unpublished posts (drafts or scheduled posts) are shareable for feedback/review" — and never says how to make one. The front matter fields it documents are title, published, tags, canonical_url, cover_image, series. No date field.

The API docs list the article payload as title, body_markdown, published, series, main_image, canonical_url, description, tags, organization_id. published is documented as a boolean: "set to true to immediately publish". Nothing about scheduling.

dev.to runs on Forem, which is open source. So I read it instead of guessing.

The field is published_at

# app/models/article.rb — evaluate_front_matter
self.published_at = hash["published_at"] if hash["published_at"]
Enter fullscreen mode Exit fullscreen mode

Front matter goes through evaluate_front_matter, and published_at is read straight out of the hash. Two more places confirm it's a real feature rather than an accident:

# app/models/article.rb
def scheduled?
  published_at? && published_at.future?
end
Enter fullscreen mode Exit fullscreen mode
# app/models/article.rb — validation, on: :create
def future_or_current_published_at
  # allow published_at in the future or within 15 minutes in the past
  return if !published || published_at.blank? || published_at > 15.minutes.ago
  errors.add(:published_at, ...)
end
Enter fullscreen mode Exit fullscreen mode

A future published_at isn't tolerated, it's explicitly permitted. And app/services/articles/attributes.rb lists published_at among accepted attributes, coercing it with .to_datetime.

What to write

---
title: "Your title"
published: true
published_at: 2027-03-04 13:00 +0000
tags: devto, meta
series: Your Series Name
---
Enter fullscreen mode Exit fullscreen mode

Both parts matter. published: true with a future published_at is what scheduled? keys on. published: false gives you a plain draft and the date is inert.

Three details worth knowing before you queue a fortnight of them.

Include the offset. +0000 for UTC. I'd rather write the offset than find out how a bare datetime gets interpreted on a server whose timezone isn't mine.

Time of day is yours to pick. I use 13:00 +0000 — mid-morning US Eastern — because that's where dev.to's traffic is, not where I am.

It composes with series. I half-expected one of the two to win. Both apply: the post shows as Scheduled with its series attached, and it slots into the series index at the right position when it goes live.

Does it actually work on dev.to

Reading the source tells you what Forem main does. It does not tell you what dev.to's deployment does — a self-hosted Forem, a different release, a feature flag, and you'd get a draft that publishes never or immediately.

So I tested with one post before trusting it with twelve. It came up in the dashboard as Scheduled with the right date and did not go live early. Then I queued the rest.

That's the whole method, and it's worth stating plainly because it applies to every undocumented feature you find by reading source: the source tells you the mechanism, one live test tells you whether the mechanism is deployed. Skip the second step and you've scheduled two weeks of posts into a void.

While I was in there

The same function reads a set of front matter keys I hadn't seen documented anywhere either:

# app/models/article.rb
def set_ai_disclosure_from_front_matter(hash)
  return unless Settings::General.enable_ai_disclosure
  raw_val = hash["ai_disclosure_level"] || hash["ai_disclosure"]
  if raw_val.nil?
    if hash["ai_generated"] == true || hash["ai_generated"] == "true"
      self.ai_disclosure_level = :fully_autonomous
    elsif hash["ai_assisted"] == true || hash["ai_assisted"] == "true"
      ...
Enter fullscreen mode Exit fullscreen mode

ai_generated, ai_assisted, ai_disclosure_level — gated behind an instance setting, so whether they do anything on dev.to specifically I can't tell from outside. I mention it because if you're going to disclose, you'd probably rather do it in a field the platform understands than in a sentence at the bottom of a post.

The general version

Two documentation surfaces both described dev.to's scheduling as either absent or unmentioned. The feature has been in the model, with its own predicate method and its own validation, the whole time.

If a platform you use is open source, grep beats the docs for anything the docs don't cover. git clone, search for the noun you want — scheduled, published_at — and read the model. Ten minutes, and it works on every undocumented feature rather than just the one you were looking for.

Then run the one live test, because the source is the mechanism and the deployment is the fact.

Top comments (1)