Content Modeling with Blocks

BaseHub was designed from the ground up for speed and editing experience. In BaseHub, you won’t “Configure your schema” and “write content for it” in different tabs—it all happens in the same place: the Editor.

The Editor is similar, in terms of UX, to something like Notion. Inside the Editor, you type / to open the “Slash Command”. Here, you’ll have a selection of different Blocks that will help you model your data. Once you add a Block, say, a Text Block, you’ll be prompted to add a Name to it, and then fill it with content. The Name is very important, as it’s the identifier we’ll later use to query that content from the Delivery API.

An important thing you’ll notice is that, with BaseHub, you can model and write your content at the same time, without the context switch.

For the purpose of semantics, we’ll group our blocks into two categories: Layout Blocks, and Primitive Blocks.

Layout Blocks

Think of Layout Blocks as anything that will be shown in the Sidebar. Layout Blocks typically will have nested Blocks. Layout Blocks can nest other Layout Blocks, and this is a core feature that gives BaseHub a lot of flexibility when modeling content. These are our Layout Blocks:

Root

The Root Block is never visible to the user, but it’s something that—as it name implies—is the root of every Tree. Every time you create a new Repository, it comes with the “working Root“. Every time you commit, it creates a new Tree, with a new Root.

Document

The Document Block is like a page inside BaseHub. For example, if you have your Homepage, your About Page, your Pricing Page, these would all be Document Blocks, with nested blocks for things like Text, Images, etc.

Document Blocks have a structure that can’t be reused across the Repository—it’s a “singleton”.

Component

The Component Block is very similar to the Document Block, with one important trait: it can be instanced in other places of the Repository, with the structure of those instances being synced to the Component. If you’ve ever used tools like Figma, you can associate this to how a Figma Component works. It also maps well to React Components—e.g; in BaseHub, you might have a Section Component, which in React gets rendered with a <Section /> Component as well.

Instance

The Instance Block is closely related to the Component Block, as its structure is tied to the “Main Component“. You cannot alter the schema of this Block directly, you can just edit its content.

Collection

The Collection Block is pretty special as it allows users to create multiple instances of a component, and display them in an organized way in the dashboard, as well as exposing them as a list in the Delivert GraphQL API.

While this might be a bit techical to understand, thinking about some popular use cases will definiltey help: use a Collection to create a list of Blog Posts, or an Image Gallery, or some Nav Links, etc.

Primitive Blocks

Primitive Blocks, as their category name imply, are simpler to understand. These are our texts, our images, our numbers, dates, booleans, etc. Well, here’s the full list:

  • Text, for titles, names, paragraphs, etc.

  • Number, for IDs, ratings, quantity, etc.

  • Select, pick between a preset range of values.

  • Comment, for help text, or just a comment.

  • Boolean, true or false, yes or no.

  • Date, mark a point in time.

  • Reference, reference an existing block.

  • Image, self explanatory.

  • Video, self explanatory.

  • Audio, self explanatory.

  • File, any type of file.

  • Color, a color picker.

Properties

Every Block has Properties that come alongside it, configured by the user. You’ll see them in the right hand side when you select a specific Block. Here, you’ll find things like:

  • Is required

  • Min/max length

  • Regex pattern

  • Max file size for media types

  • Formatting constraints

  • Min/max rows in a collection

  • Etc…

Everything that’s configurable about a Block will be there, in the Properties Panel.

System Properties

There are some “system properties” that come with every Block. Every Block has an Id, a Title, a Type, an Api Name and a Slug. The last two are actually inferred from the Title, but we’re considering exposing them via the Properties Panel so that users can edit them.

Examples

Let’s explore some examples that will help you model your websites with BaseHub.

Simple Personal Site

Let’s take the following structure:

- Hero Section
  - Title
  - Subtitle
  - Avatar
- Portfolio
  - Title
  - Subtitle
  - List of Projects
    - Title
    - Description
    - Featured Image
    - URL
- Footer
  - List of Social Links
    - Label
    - Href

Notice how the intuitive way we think about the structure of a website is in a tree-like fashion—and how they are actually built with HTML. Blocks are perfect for this, as they allow us to nest Blocks under Blocks, thus creating any structure we can imagine.

We could use the following Blocks for our proposed structure:

- Hero Section -> Document
  - Title -> Text
  - Subtitle -> Rich Text
  - Avatar -> Image
- Portfolio -> Document
  - Title -> Text
  - Subtitle -> Rich Text
  - List of Projects -> Collection
    - Title -> Text
    - Description -> Rich Text
    - Featured Image -> Image
    - URL -> Text
- Footer -> Document
  - List of Social Links -> Collection
    - Label -> Text
    - Href -> Text

Blog

A simple blog might have the following structure to it:

- Title
- Subtitle
- Categories
- Search
- List of Posts (filtered by category or search)
  - Title
  - Slug
  - Excerpt
  - Cover Image
  - Author
  - Category
  - Publish Date
  - Body

And this is how we could model that in BaseHub:

- Title -> Text
- Subtitle -> Rich Text
- Categories -> Collection<Category>
- Search -> (API functionality, filter by search contents)
- List of Posts (filtered by category or search)
  - Title -> System Title
  - Slug -> System Slug
  - Excerpt -> Text, or infer from the Body at render time
  - Cover Image -> Image
  - Author -> Reference<Author>
  - Category -> Reference<Category>
  - Publish Date -> Date
  - Body -> Rich Text
- Authors -> Collection<Author>

Refactoring

As your website evolves, you’ll likely need to adjust your content model in BaseHub. There are a couple of key features that will help us refactor our content in an easy and predictable way:

  1. Components help us create reusable structures.

  2. Drag & Drop helps us with reordering Blocks.

  3. Diff View gives us confidence to commit new changes cross-repository.

  4. Wrap in Collection can help convert a Block that was intended to be a single instance into a Collection.

  5. (Coming Soon) Branching will make our content workflows align with the workflows we use to develop our websites—Git, GitHub, Vercel, etc.

Say you’ve built a simple homepage, and now you need an about page. Now you have another page, so it might be useful to create some common Components that get reused across pages: a Link (label, href), a Section (title, subtitle, image, collection<link>), a Metadata. These are just some examples. In the Editor, you can easily create a new Component, drag and drop stuff that you’ve already written into it, and see the Diff of all your changes before committing. Easy!