Skip to main content

Blog

The blog feature enables you to deploy a full-featured blog in no time. You write blog posts and classify them into categories, tags, languages. Each post can be connected by relatedPosts, nextPost or previousPost.

All blog posts are stored at app\routes\__layout\blog\__mdx\ and meta-data declared in app\data\blog.server.ts

blog posts location
my-website
├── app
│ └── routes
│ └── __layout
│ └── blog
│ └── __mdx
│ ├── hello-world.mdx
│ ├── hola.mdx
│ ├── ...
│ └── welcome.mdx

Process to create a new blog post

To add a new blog post, you need to process 2 steps

  1. For example, create a file at app\routes\__layout\blog\__mdx\your-blog-post-filename.mdx

    the file name your-blog-post-filename.mdx file will be the slug of the blog post

    my-website
    ├── app
    │ └── routes
    │ └── __layout
    │ └── blog
    │ └── __mdx
    │ ├── your-blog-post-filename.mdx
    │ └── ...

    your blog post

  2. Declare your new blog post at app\data\blog.server.ts

    app\data\blog.server.ts
    ...
    //import your blog posts
    import * as P0001 from "~/routes/__layout/blog/__mdx/your-blog-post-filename.mdx"
    ...
    //extract meta data
    const data = [
    getMdxBlogMeta(P0001),
    ...
    ]

Format of a blog post .mdx

You would need to use Markdown format to compose your article. Markdown format is simple and easy. Trust me. You would love Markdown. It helps you to concentrate to your writing, not to be distracting from anything.

note

Metadata structure: There are a lot of properties and explain seems complicated but they are really simple. Please take a look at some blog posts and you would understand easier.

/**
* `.mdx` for blog post must follow this structure
* the recommend way is to duplicate exiting file
* and do the modification. Don't create a blank file
* to start from the beginning
*/
type BlogPostMeta = {
attributes: {
meta: {
title: string
description: string
},
properties: {
/**
* a unique code your your post
* this is could be anything, just to make sure that it is unique
*/
id: string
/**
* the day that your blog post is published
*/
publishedDate: string
/**
* the day that your blog post is updated
*/
updatedDate: string
/**
* you can specify related post by
* - filenames
* - category
* - tags
*/
relatedPosts?: RelatedCriteria
/**
* helps to organize your blog posts in great flexible way
*/
tags: string[]
images: ImgSrcSet[]
categories: string[]
/**
* language of the blog post
* it would be consider as default language is not provided
* UPDATE: i use array here for some users are too lazy to do the translation,
* then, at very first time, they will let the article available
* to more than 1 language! They will update this later!
*/
language?: Language[]
/**
* filename of the original blog post
*/
translated?: string
/**
* decorate the header of the post
*/
pageHeaderMeta?: PageHeaderMeta
/**
* Author of the post, this information is for SEO purpose
* if showAuthor is true, then it would include author information
* to the page meta. The information would be get from
* `author`, if not provided, it would get from "settings.ts"
*/
showAuthor?: boolean
author?: {
name: string
jobTitle?: string
url: string
}
}
}
filename: string
}

type RelatedCriteria = {
type: "filename" | "id" | "tag" | "category",
value: string
}[]

type ImgSrcSet = {
mobile: string
desktop?: string
description?: string
}

type PageHeaderMeta = {
/**
* array of images
* if it has 2 images, 1st is for mobile, 2nd is for pc
*/
featuredImage?: ImgSrcSet
backgroundColor?: string
height?: string
/**
* allow user to define image position
* https://developer.mozilla.org/en-US/docs/Web/CSS/object-position
* the default position is `center-center` aka `50% 50%`
*/
objectPosition?: string
/**
* allow user to define image hovering position
* https://developer.mozilla.org/en-US/docs/Web/CSS/transform-origin
* the default position is `center-center` aka `50% 50%`
*/
objectOrigin?: string
}
info
  • Root folder of BlogPostMeta.attributes.properties.images, when you say /placeholder.svg. It means the file placeholder.svg is in /img/blog/ folder (or URL.BLOG_FOLDER).

  • Root folder of BlogPostMeta.attributes.properties.pageHeaderMeta.featuredImage, when you say /placeholder.svg. It means the file placeholder.svg is in /img/blog/ folder (or URL.BLOG_FOLDER).

Tags

Tag can have a background image which can be declared in app\data\settings\categoriesAndTagsProperties.ts

export const catsTags: CatsTags = {
"Microsoft": {
imageUrl: "/placeholder.svg",
},
"MSI": {
imageUrl: "/placeholder.svg",
},
}
info

Root folder is /img/background/, when you say /placeholder.svg. It means the file placeholder.svg is in /img/background/ folder (or URL.BACKGROUND_FOLDER).

Video tutorial