Feature request: import from Markdown with expanded frontmatter

Feature request: import from Markdown with expanded frontmatter

Right now the Markdown component renders content, but it doesn’t read anything from YAML frontmatter. Other CMS platforms use frontmatter to build schema and metadata automatically. Elements could do the same.

I’d want to upload a Markdown file with frontmatter and have Elements build out the page details on import: title, meta description, tags, whatever fields make sense. This should work on native Elements pages, not just the Markdown component.

I know this is all doable with a script and a proper markdown parser, if the team is looking at where AI fits into Elements, this is a good candidate.

Frontmatter Schema Reference

Each block below is a page type, the schema.org type it maps to, a sample frontmatter with example content, and the JSON-LD that frontmatter would generate on import. All URLs use elements.com.

A field dictionary follows the examples, defining every field once so there’s no ambiguity about what goes where.


Article

Schema type: Article

---
type: article
title: "Why We Rebuilt the Elements Component Engine"
slug: why-we-rebuilt-the-component-engine
description: "A look at the performance problems that pushed us to rewrite how components render, and what changed under the hood."
lang: en
canonical_url: https://elements.com/articles/why-we-rebuilt-the-component-engine
robots: index
image: /images/component-engine-hero.jpg
og_image: /images/component-engine-social.jpg
author: "Dan Counsell"
author_url: https://elements.com/about
author_image: /images/dan-counsell-headshot.jpg
date_published: 2026-07-01
date_modified: 2026-07-10
tags:
  - engineering
  - performance
  - components
category: Engineering
publisher: "Elements"
publisher_logo: /images/elements-logo.png
---
{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": "Why We Rebuilt the Elements Component Engine",
  "description": "A look at the performance problems that pushed us to rewrite how components render, and what changed under the hood.",
  "inLanguage": "en",
  "image": "https://elements.com/images/component-engine-hero.jpg",
  "author": {
    "@type": "Person",
    "name": "Dan Counsell",
    "url": "https://elements.com/about",
    "image": "https://elements.com/images/dan-counsell-headshot.jpg"
  },
  "publisher": {
    "@type": "Organization",
    "name": "Elements",
    "logo": {
      "@type": "ImageObject",
      "url": "https://elements.com/images/elements-logo.png"
    }
  },
  "datePublished": "2026-07-01",
  "dateModified": "2026-07-10",
  "mainEntityOfPage": {
    "@type": "WebPage",
    "@id": "https://elements.com/articles/why-we-rebuilt-the-component-engine"
  },
  "keywords": "engineering, performance, components",
  "articleSection": "Engineering"
}

Blog Post

Schema type: BlogPosting

---
type: blog_post
title: "Five Lessons From Ten Years of Building Mac Software"
slug: five-lessons-ten-years-mac-software
description: "What a decade of shipping desktop apps taught us about focus, pricing, and saying no to feature requests."
lang: en
canonical_url: https://elements.com/blog/five-lessons-ten-years-mac-software
robots: index
image: /images/ten-years-hero.jpg
og_image: /images/ten-years-social.jpg
author: "Dan Counsell"
author_url: https://elements.com/about
author_image: /images/dan-counsell-headshot.jpg
date_published: 2026-06-15
date_modified: 2026-06-15
tags:
  - company
  - lessons-learned
category: Blog
reading_time_minutes: 6
---
{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "headline": "Five Lessons From Ten Years of Building Mac Software",
  "description": "What a decade of shipping desktop apps taught us about focus, pricing, and saying no to feature requests.",
  "inLanguage": "en",
  "image": "https://elements.com/images/ten-years-hero.jpg",
  "author": {
    "@type": "Person",
    "name": "Dan Counsell",
    "url": "https://elements.com/about",
    "image": "https://elements.com/images/dan-counsell-headshot.jpg"
  },
  "datePublished": "2026-06-15",
  "dateModified": "2026-06-15",
  "mainEntityOfPage": {
    "@type": "WebPage",
    "@id": "https://elements.com/blog/five-lessons-ten-years-mac-software"
  },
  "keywords": "company, lessons-learned",
  "articleSection": "Blog",
  "timeRequired": "PT6M"
}

About Page

Schema type: AboutPage (with an embedded Person or Organization)

---
type: about_page
title: "About"
slug: about
description: "Who Dan Counsell is and why he founded Elements."
lang: en
canonical_url: https://elements.com/about
robots: index
image: /images/dan-counsell-headshot.jpg
og_image: /images/dan-counsell-social.jpg
entity_type: Person
name: "Dan Counsell"
job_title: "Founder"
founded_organization: "Elements"
same_as:
  - https://elements.com
  - https://twitter.com/dancounsell
---
{
  "@context": "https://schema.org",
  "@type": "AboutPage",
  "url": "https://elements.com/about",
  "description": "Who Dan Counsell is and why he founded Elements.",
  "inLanguage": "en",
  "mainEntity": {
    "@type": "Person",
    "name": "Dan Counsell",
    "image": "https://elements.com/images/dan-counsell-headshot.jpg",
    "jobTitle": "Founder",
    "sameAs": [
      "https://elements.com",
      "https://twitter.com/dancounsell"
    ],
    "worksFor": {
      "@type": "Organization",
      "name": "Elements"
    }
  }
}

Commentary

Schema type: Article with about pointing to the subject (works well for ongoing analysis or review series)

---
type: commentary
title: "The Shift From Themes to Components"
slug: shift-from-themes-to-components
description: "Why website builders are moving away from fixed themes and toward composable components, and what that means for design freedom."
lang: en
canonical_url: https://elements.com/commentary/shift-from-themes-to-components
robots: index
author: "Dan Counsell"
author_url: https://elements.com/about
author_image: /images/dan-counsell-headshot.jpg
date_published: 2026-05-01
date_modified: 2026-05-20
tags:
  - static-site-generator
  - design-system
series: "Elements Commentary"
series_position: 1
about: "Component-based website design"
---
{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": "The Shift From Themes to Components",
  "description": "Why website builders are moving away from fixed themes and toward composable components, and what that means for design freedom.",
  "inLanguage": "en",
  "author": {
    "@type": "Person",
    "name": "Dan Counsell",
    "url": "https://elements.com/about",
    "image": "https://elements.com/images/dan-counsell-headshot.jpg"
  },
  "datePublished": "2026-05-01",
  "dateModified": "2026-05-20",
  "mainEntityOfPage": {
    "@type": "WebPage",
    "@id": "https://elements.com/commentary/shift-from-themes-to-components"
  },
  "about": {
    "@type": "Thing",
    "name": "Component-based website design"
  },
  "isPartOf": {
    "@type": "CreativeWorkSeries",
    "name": "Elements Commentary",
    "position": 1
  },
  "mentions": [
    { "@type": "DefinedTerm", "name": "static-site-generator" },
    { "@type": "DefinedTerm", "name": "design-system" }
  ]
}

Define Terms (Glossary Entry)

Schema type: DefinedTerm (inside a DefinedTermSet)

---
type: glossary_entry
title: "Static Site Generator"
slug: static-site-generator
description: "A tool that builds a website's pages ahead of time into plain HTML files, rather than generating them on each request."
lang: en
canonical_url: https://elements.com/glossary/static-site-generator
robots: index
tags:
  - jamstack
  - build-process
term_set: "Elements Glossary"
letter: S
referenced_in:
  - /commentary/shift-from-themes-to-components
date_modified: 2026-04-12
---
{
  "@context": "https://schema.org",
  "@type": "DefinedTerm",
  "name": "Static Site Generator",
  "description": "A tool that builds a website's pages ahead of time into plain HTML files, rather than generating them on each request.",
  "url": "https://elements.com/glossary/static-site-generator",
  "inLanguage": "en",
  "inDefinedTermSet": {
    "@type": "DefinedTermSet",
    "name": "Elements Glossary",
    "url": "https://elements.com/glossary"
  },
  "dateModified": "2026-04-12"
}

Photo Gallery

Schema type: ImageGallery (containing multiple ImageObject entries)

---
type: photo_gallery
title: "Elements 3.0 Redesign, Behind the Scenes"
slug: elements-3-redesign-behind-the-scenes
description: "Screenshots and early sketches from the Elements 3.0 interface redesign."
lang: en
canonical_url: https://elements.com/gallery/elements-3-redesign-behind-the-scenes
robots: index
image: /images/gallery/redesign-cover.jpg
og_image: /images/gallery/redesign-social.jpg
date_published: 2026-03-01
images:
  - src: /images/gallery/redesign-01.jpg
    caption: "Early wireframes for the new component panel"
  - src: /images/gallery/redesign-02.jpg
    caption: "First working build of the theme studio"
  - src: /images/gallery/redesign-03.jpg
    caption: "Final interface, ready for release"
---
{
  "@context": "https://schema.org",
  "@type": "ImageGallery",
  "name": "Elements 3.0 Redesign, Behind the Scenes",
  "description": "Screenshots and early sketches from the Elements 3.0 interface redesign.",
  "url": "https://elements.com/gallery/elements-3-redesign-behind-the-scenes",
  "inLanguage": "en",
  "datePublished": "2026-03-01",
  "image": "https://elements.com/images/gallery/redesign-cover.jpg",
  "associatedMedia": [
    {
      "@type": "ImageObject",
      "contentUrl": "https://elements.com/images/gallery/redesign-01.jpg",
      "caption": "Early wireframes for the new component panel"
    },
    {
      "@type": "ImageObject",
      "contentUrl": "https://elements.com/images/gallery/redesign-02.jpg",
      "caption": "First working build of the theme studio"
    },
    {
      "@type": "ImageObject",
      "contentUrl": "https://elements.com/images/gallery/redesign-03.jpg",
      "caption": "Final interface, ready for release"
    }
  ]
}

Terms and Conditions

Schema type: WebPage (legal pages don’t get rich schema; the useful fields are the ones that keep the page current and correctly indexed)

---
type: legal_page
title: "Terms and Conditions"
slug: terms-and-conditions
description: "The terms that govern use of elements.com."
lang: en
canonical_url: https://elements.com/terms-and-conditions
robots: index
date_published: 2025-01-01
date_modified: 2026-06-01
version: "2.3"
---
{
  "@context": "https://schema.org",
  "@type": "WebPage",
  "name": "Terms and Conditions",
  "description": "The terms that govern use of elements.com.",
  "url": "https://elements.com/terms-and-conditions",
  "inLanguage": "en",
  "datePublished": "2025-01-01",
  "dateModified": "2026-06-01"
}

Field Dictionary

Every field used above, defined once. If a field isn’t listed here, it doesn’t belong in the frontmatter.

Core fields — required on every page type

Field Type Definition
title string The page’s headline or name. Maps to headline on content types, name on entity and page types.
slug string The URL segment for the page, lowercase, hyphenated. Not sent to JSON-LD directly; used to build canonical_url.
description string A one- to two-sentence summary. Maps to description in every schema type and doubles as the meta description tag.
lang string The page’s language, as a two-letter ISO code (en, fr, de). Maps to inLanguage in JSON-LD and to the page’s <html lang> attribute. Required even on single-language sites.
canonical_url URL The full, final URL of the page. Maps to url or @id depending on schema type. Prevents duplicate-content issues if the page is ever reachable at more than one address.
robots string Either index or noindex. Controls whether search engines are allowed to list the page. Every page type needs this, not just legal pages.
date_published date (YYYY-MM-DD) When the page went live. Maps to datePublished.
date_modified date (YYYY-MM-DD) When the page was last edited. Maps to dateModified. Should update automatically on every save, not just be typed in once.

Media fields — required where the page has visuals

Field Type Definition
image path The primary image for the page: hero image, headshot, or gallery cover. Maps to image in JSON-LD. One name, used consistently across every page type — no more cover_image as a separate concept.
og_image path The image used for social sharing cards (Facebook, Twitter/X, Slack previews). Kept separate from image because social cards crop to a fixed ratio, usually 1200×630, and the hero image on the page is rarely that shape. Falls back to image if left blank.

Author fields — required on content types (article, blog post, commentary)

Field Type Definition
author string The author’s display name. Maps to Person.name.
author_url URL A link to the author’s own page, usually their About page. Maps to Person.url. This is what lets schema.org treat the author as a real, connected entity instead of a bare string.
author_image path A photo of the author. Maps to Person.image.

Tagging — required on content types, optional elsewhere

Field Type Definition
tags list of strings Keywords or related concepts for the page. One field name used everywhere content can be tagged. Replaces the old split between tags and related_terms — they were doing the same job under two names. Maps to keywords on articles and blog posts, and to mentions on commentary.
category string A single broad grouping, distinct from tags. Maps to articleSection. Optional; use when a site has a small number of top-level sections (Engineering, Blog, Company).

Type-specific fields

Field Type Applies to Definition
publisher / publisher_logo string / path Article The organization behind the content, separate from the individual author. Maps to Organization.name and Organization.logo.
reading_time_minutes integer Blog post Estimated read time. Maps to timeRequired, formatted as an ISO 8601 duration (PT6M).
entity_type string About page Either Person or Organization. Determines which schema.org type the mainEntity block uses.
job_title string About page (Person) Maps to Person.jobTitle.
founded_organization string About page (Person) The company or project the person founded. Maps to Person.worksFor.name.
same_as list of URLs About page Links to the person’s or organization’s other official profiles (social accounts, other sites). Maps to sameAs.
series / series_position string / integer Commentary The name of an ongoing series and this entry’s position in it. Maps to CreativeWorkSeries.name and .position.
about string Commentary The subject the commentary covers. Maps to about.name.
term_set string Glossary entry The name of the glossary or reference collection this term belongs to. Maps to DefinedTermSet.name.
letter string Glossary entry The alphabetical grouping for the term. Used for building an A–Z index; not sent to JSON-LD.
referenced_in list of paths Glossary entry Other pages that link to or cite this term. Used for building “referenced in” sections; not sent to JSON-LD.
images list of objects (src, caption) Photo gallery The individual photos in the gallery. Maps to associatedMedia, one ImageObject per entry.
version string Legal page The document’s version number, for tracking changes to terms over time. Not sent to JSON-LD; used for display and changelog purposes.

The JSON-LD blocks above map field-for-field to the frontmatter. That mapping is the actual feature: on import, Elements would read the YAML, drop the matching values into the right schema.org properties, and inject the JSON-LD into the page head automatically.

Fine line… how would this affect existing CMS?

Some have thousands of markdown files…

Maybe I misunderstood would it ‘translate’ to new format?

I spent two agonizing days with Claude going through 365 markdown files - restructuring frontmatter - adding “ “ checking settings in elements - checking checking editing editing - constant changes trying make my CMS work… (very painful for me)

It ended up being a . Instead of a , in file 138 - it took down the whole CMS!!!

Looking at your changes… makes me very very very nervous…. - for me

Can you imagine trying to troubleshoot thousands of markdown files looking for an errant . ???

Good questions. :slight_smile:

Would this touch existing CMS content? No. This is a request for a new import path, not a migration tool. Your existing files stay exactly as they are. Nothing about this request converts, rewrites, or touches content you already have. It only applies when you choose to import a new file through it.

Does it “translate” to a new format? No translation involved. The frontmatter fields map directly to schema.org properties for whatever page type you’re building: article, blog post, about page, and so on. One field, one property, no conversion step in between.

On the corruption problem What happened to you was a parsing failure, not a frontmatter problem. One bad character in one file shouldn’t be able to take down thousands of others. That’s a sign the tool reading the files had no validation and no isolation between them.

A properly built import would check each file’s frontmatter before doing anything with it, reject the one file with the error, and tell you exactly which file and which line broke. The other 364 files stay untouched. What you went through is the exact failure mode this kind of validation exists to prevent.

So the short version: this wouldn’t change how your CMS handles the files you already have, and it’s not asking you to touch a syntax that already burned you. It’s a request for Elements to read frontmatter safely when you choose to import something new.

Thanks for the detailed response…

Very much seems all positive….