Skip to content

Instantly share code, notes, and snippets.

@bholmesdev
Created August 17, 2022 16:37
Show Gist options
  • Save bholmesdev/93961529c3ed600ff2294427b95edad4 to your computer and use it in GitHub Desktop.
Save bholmesdev/93961529c3ed600ff2294427b95edad4 to your computer and use it in GitHub Desktop.

Content management is broken. Let's fix it

By Ben "MDX" Holmes

What am I talking about?

Background: I worked on an ecommerce site with a medium-sized enterprise team. This team needed a lot of cross-communication copy writers, designers, product managers, and developers.

Purpose: To thoroughly understand the content management problem space, and analyze existing solutions.

⚠️ I am not discussing our own solution! Just setting the groundwork from my perspective, so Astro can build from there 😄

Use case: Managing content on a medium-to-large enterprise team, particularly in marketing and ecommerce

What is content?

Based on my team in ecommerce, you may have:

  • product information - in-house CMS, Shopify headless, Swell headless
  • structured copy about those products - Wordpress headless, Contentful [[CMS usage - Jamstack community survey 2021]]
  • UI building blocks to bring that copy to users - pure-code like React et al, or design -> code tools like Framer and Plasmic

This touches copy writing (including translations), product, design, and development.

The best content management tool should make communication and alignment between these teams seemless.

Each piece feels great to use in isolation, but integration is FAR from solved

  • Contentful -> in-house CMS is nearly impossible (and very difficult vice versa)
  • Contentful and product info -> UI = a ton of GraphQL and React hook wiring
  • Decoupling = build-your-own DX ![[Astro CMS - initial thoughts#^fe4b77]]

Approaches authoring rich content

Rich content isn't just Markdown. Headless doesn't know this. You need quite a few added goodies when content is tied to data (i.e. product catalogs). This includes:

  • Props
  • Conditionals
  • Switch cases / enums
  • Dropdown buttons, carousels, "special edition" badges... aka components

Props and switch cases are harder than the code I write

For a switch case, we needed... this: ![[Pasted image 20220816153811.png]]

Our cupcakes are a **perfect** match for your next event. If you buy {productLine
	="chocolate" {a gooey {productLine} for $3.99 each}
	="strawberry" {a delicious {productLine} for $2.99 each}
	="vanilla" {a creamy {productLine} for $2.99 each}
}, you can enjoy...

This uses ICU messaging standards to "switch" content on an input. No, I should not need a codeblock to show what copy writers needed to type 😆

These concepts of = for switch cases and {JSX-like expressions} for variables are NOT a CMS standard either. If you want features like this, you're throwing the CMS rich text tree through your own hand-rolled parser, without feedback to the copy writer they've authored this correctly.

Abuse renderers for pseudo-components

Limited to markdown syntax, you need to get creative! This could mean custom shortcodes or special strings to represent components, or map markdown elements to something else. For instance, say we need to embed a ZIP code input inside a text block. You might grab an anchor tag: ![[Pasted image 20220816153927.png]]

Available to deliver to [{ZIP code}]() in 1-2 weeks

Wire up a component from our rich text renderer:

richText.render(content, {
  renderers: {
    a: (content) => (
	    <button onClick={changeZipCode}>
		    {richText.render(content)}
		</button>
    )
  }
})

...and hope copy never needs another link tag in that text block 😉

Approaches to structuring content

Are headless CMSes broken? ~F "hot take" KS

Structured content story ![[cms-structured-content-story.png]]

Full KV

Every piece of content is a key-value pair, no grouping.

  • Pros:
    • Maximum reusability. Need "Add to Cart" translated to 8 languages? Just fetch addtoCartCta from your UI
    • Queries are flat and efficient. If a developer has the keys, they can build a page.
  • Cons:
    • Unclear where content lives in the UI. Either the copy team has a mental map of every key -> every placement, or developers build in-house DX
    • Slow to build content. More blocks = more clicks to create, more clicks to edit, more clicks to tag and release, etc
    • Key names get complex fast. Can lead to competing key naming standards (ex. is it shopPage.shoes.sizeGuide or modal.shoes.sizeGuide?)

Content in generic buckets

  • Pros:
    • (Hopefully) bring design standards to content. Designer patterns around, say, "header + body + image" are reflected by content buckets.
    • Quicker and simpler to build. Grouped content = fewer clicks and simpler content keys
  • Cons:
    • Rigid abstractions don't scale. Either you get duplicates that are similar-but-not-the-same (HeaderBodyImage, HeaderBodyImageLink, HeaderBodyImageFootnote, HeaderBody...), or an abstraction grows too large with optionals and null checks (TextBlock with all optional fields)

Content and UI are one-to-one

  • Pros:
    • Clear how content edits effect the UI. Copy writer finds modal in the deploy preview, and edits the modal entry in the CMS. Changes are predictable
    • No planning required to build the best abstraction. Nothing is higher-order.
  • Cons:
    • Tight coupling = inflexibility. Headless CMSes champion decoupling for a reason! When designers add a new element, full stack changes take place: the CMS model, dev-side queries, and UI all need toc hange
    • Headless becomes build-your-own head.

What a content editor should do

  • Bring UI components into your content (more than just Markdown)
  • Maximize content reusability
  • Show how content effects the UI
  • Align Content, Design, and Development around shared patterns / components
  • Keep patterns flexible

"Standard" headless - Contentful, Sanity, Strapi, etc.

❌ Bring UI components into your content (more than just Markdown) 🤷‍♂️ Maximize content reusability ❌ Show how content effects the UI 🤷‍♂️ Align Content, Design, and Development around shared patterns / components 🤷‍♂️ Keep patterns flexible

Content-to-code - Storyblok

❌ Bring UI components into your content (more than just Markdown) 🤷‍♂️ Maximize content reusability ✅ Show how content effects the UI ✅ Align Content, Design, and Development around shared patterns / components 🤷‍♂️ Keep patterns flexible

No-code content: Notion

✅ Bring UI components into your content (more than just Markdown) ❌ Maximize content reusability ✅ Show how content effects the UI ❌ Align Content, Design, and Development around shared patterns / components - Design and content are one, so developer customization is impossible ✅ Keep patterns flexible

Content-to-design - Builder.io and Plasmic

✅ Bring UI components into your content (more than just Markdown) ✅ Maximize content reusability ✅ Show how content effects the UI 😬 Align Content, Design, and Development around shared patterns / components - Cost for developers: core code outsourced to a design tool ✅ Keep patterns flexible

The full content studio - Astro?

✅ Bring UI components into your content (more than just Markdown)

  • start from Rich Text, add components, props, conditionals, and more in a no-code way

✅ Maximize content reusability

  • walk: pull from an existing headless CMS
  • run: use Astro to host your structured content, translations, and more

✅ Show how content effects the UI

  • live preview as you edit your content

✅ Align Content, Design, and Development around shared patterns / components

  • Flip from source code -> visual editor and visual editor -> source code seemlessly

✅ Keep patterns flexible

  • build in components that are infinitely reusable

Rough notes

  • I have components or component libraries I prefer. Let me use them when crafting my content.
  • Islands are our strength! Let's lean into that.
  • Let's outline an audience!
    • Starting point: teams with Content, Design, and Dev concerns
  • Fred thought: start from a core audience and build from there; don't leap-frog to the conclusion (ex. ecommerce)
  • 💡 Idea: Click-to-code from dev server or live preview
    • devs: opt + click element on page for source
    • future for copy: opt + click for CMS content entry
  • Hard to pipe real content into your components
    • Design = lorem ipsum driven design
    • Placeholders are dangerous
    • Word size (ESPECIALLY for translations) should be available to design ahead of time
  • ASTRO STUDIO
    • (okay Astro HQ for Fuzzy)
  • It's not about building a headless CMS. It's about managing the visuals AROUND your content in a clear way (aka visual content)
    • Can be a "component book" for visualizing my UI elements (Fuzzy sees a lot of user need!)
    • Can be a config management CLI / "HQ" for your project
    • Can be a WIZZYWIG editor for your Markdown content, MDX content, Astro content, and more
  • Astro is used at major companies for blogs. Is that a north star?
    • Note: all dev-oriented blogs (Guardian dev, Trivago dev, Firebase)
    • Are we the right fit for that use case, or were devs just excited?
    • Counterpoint: showcase page is almost all landing pages
  • Astro is focused on getting users, and making existing users happy
    • All about reducing friction for onboarding
      • Could be themes
      • Could be component book
    • Build features that let us understand what users that gravitate towards us (themes are notable)
    • Own 👏 the 👏 garden - if you have a compelling platform, you "own" users (Dan)
    • apm (Astro package manager) 👀👀👀
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment