--- author: Sat Naing pubDatetime: 2022-09-23T15:22:00Z modDatetime: 2025-03-20T03:22:19.075Z title: Adding new posts in AstroPaper theme slug: adding-new-posts-in-astropaper-theme featured: true draft: false tags: - docs description: Some rules & recommendations for creating or adding new posts using AstroPaper theme. --- Here are some rules/recommendations, tips & ticks for creating new posts in AstroPaper blog theme.
Free Classic wooden desk with writing materials, vintage clock, and a leather bag. Stock Photo
Photo by Pixabay
## Table of contents ## Creating a Blog Post To write a new blog post, create a markdown file inside the `src/data/blog/` directory. > Prior to AstroPaper v5.1.0, all blog posts had to be in `src/data/blog/`, meaning you couldn't organize them into subdirectories. Starting from AstroPaper v5.1.0, you can now organize blog posts into subdirectories, making it easier to manage your content. For example, if you want to group posts under `2025`, you can place them in `src/data/blog/2025/`. This also affects the post URL, so `src/data/blog/2025/example-post.md` will be available at `/posts/2025/example-post`. If you don’t want subdirectories to affect the post URL, just prefix the folder name with an underscore `_`. ```bash # Example: blog post structure and URLs src/data/blog/very-first-post.md -> mysite.com/posts/very-first-post src/data/blog/2025/example-post.md -> mysite.com/posts/2025/example-post src/data/blog/_2026/another-post.md -> mysite.com/posts/another-post src/data/blog/docs/_legacy/how-to.md -> mysite.com/docs/how-to src/data/blog/Example Dir/Dummy Post.md -> mysite.com/example-dir/dummy-post ``` > 💡 Tip: You can override a blog post’s slug in the frontmatter as well. See the next section for more details. If the subdirectory URL doesn’t appear in the build output, remove node_modules, reinstall packages, and then rebuild. ## Frontmatter Frontmatter is the main place to store some important information about the blog post (article). Frontmatter lies at the top of the article and is written in YAML format. Read more about frontmatter and its usage in [astro documentation](https://docs.astro.build/en/guides/markdown-content/). Here is the list of frontmatter property for each post. | Property | Description | Remark | | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------- | | **_title_** | Title of the post. (h1) | required\* | | **_description_** | Description of the post. Used in post excerpt and site description of the post. | required\* | | **_pubDatetime_** | Published datetime in ISO 8601 format. | required\* | | **_modDatetime_** | Modified datetime in ISO 8601 format. (only add this property when a blog post is modified) | optional | | **_author_** | Author of the post. | default = SITE.author | | **_slug_** | Slug for the post. This field is optional. | default = slugified file name | | **_featured_** | Whether or not display this post in featured section of home page | default = false | | **_draft_** | Mark this post 'unpublished'. | default = false | | **_tags_** | Related keywords for this post. Written in array yaml format. | default = others | | **_ogImage_** | OG image of the post. Useful for social media sharing and SEO. This can be a remote URL or an image path relative to current folder. | default = `SITE.ogImage` or generated OG image | | **_canonicalURL_** | Canonical URL (absolute), in case the article already exists on other source. | default = `Astro.site` + `Astro.url.pathname` | | **_hideEditPost_** | Hide editPost button under blog title. This applies only to the current blog post. | default = false | > Tip! You can get ISO 8601 datetime by running `new Date().toISOString()` in the console. Make sure you remove quotes though. Only `title`, `description` and `pubDatetime` fields in frontmatter must be specified. Title and description (excerpt) are important for search engine optimization (SEO) and thus AstroPaper encourages to include these in blog posts. `slug` is the unique identifier of the url. Thus, `slug` must be unique and different from other posts. The whitespace of `slug` should to be separated with `-` or `_` but `-` is recommended. Slug is automatically generated using the blog post file name. However, you can define your `slug` as a frontmatter in your blog post. For example, if the blog file name is `adding-new-post.md` and you don't specify the slug in your frontmatter, Astro will automatically create a slug for the blog post using the file name. Thus, the slug will be `adding-new-post`. But if you specify the `slug` in the frontmatter, this will override the default slug. You can read more about this in [Astro Docs](https://docs.astro.build/en/guides/content-collections/#defining-custom-slugs). If you omit `tags` in a blog post (in other words, if no tag is specified), the default tag `others` will be used as a tag for that post. You can set the default tag in the `/src/content/config.ts` file. ```ts // src/content/config.ts export const blogSchema = z.object({ // --- draft: z.boolean().optional(), tags: z.array(z.string()).default(["others"]), // replace "others" with whatever you want // --- }); ``` ### Sample Frontmatter Here is the sample frontmatter for a post. ```yaml # src/content/blog/sample-post.md --- title: The title of the post author: your name pubDatetime: 2022-09-21T05:17:19Z slug: the-title-of-the-post featured: true draft: false tags: - some - example - tags ogImage: ../../assets/images/example.png # src/assets/images/example.png # ogImage: "https://example.org/remote-image.png" # remote URL description: This is the example description of the example post. canonicalURL: https://example.org/my-article-was-already-posted-here --- ``` ## Adding table of contents By default, a post (article) does not include any table of contents (toc). To include toc, you have to specify it in a specific way. Write `Table of contents` in h2 format (## in markdown) and place it where you want it to be appeared on the post. For instance, if you want to place your table of contents just under the intro paragraph (like I usually do), you can do that in the following way. ```md --- # some frontmatter --- Here are some recommendations, tips & ticks for creating new posts in AstroPaper blog theme. ## Table of contents ``` ## Headings There's one thing to note about headings. The AstroPaper blog posts use title (title in the frontmatter) as the main heading of the post. Therefore, the rest of the heading in the post should be using h2 \~ h6. This rule is not mandatory, but highly recommended for visual, accessibility and SEO purposes. ## Storing Images for Blog Content Here are two methods for storing images and displaying them inside a markdown file. > Note! If it's a requirement to style optimized images in markdown you should [use MDX](https://docs.astro.build/en/guides/images/#images-in-mdx-files). ### Inside `src/assets/` directory (recommended) You can store images inside `src/assets/` directory. These images will be automatically optimized by Astro through [Image Service API](https://docs.astro.build/en/reference/image-service-reference/). You can use relative path or alias path (`@/assets/`) to serve these images. Example: Suppose you want to display `example.jpg` whose path is `/src/assets/images/example.jpg`. ```md ![something](@/assets/images/example.jpg) ![something](../../assets/images/example.jpg) something ``` > Technically, you can store images inside any directory under `src`. In here, `src/assets` is just a recommendation. ### Inside `public` directory You can store images inside the `public` directory. Keep in mind that images stored in the `public` directory remain untouched by Astro, meaning they will be unoptimized and you need to handle image optimization by yourself. For these images, you should use an absolute path; and these images can be displayed using [markdown annotation](https://www.markdownguide.org/basic-syntax/#images-1) or [HTML img tag](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img). Example: Assume `example.jpg` is located at `/public/assets/images/example.jpg`. ```md ![something](/assets/images/example.jpg) something ``` ## Bonus ### Image compression When you put images in the blog post (especially for images under `public` directory), it is recommended that the image is compressed. This will affect the overall performance of the website. My recommendation for image compression sites. - [TinyPng](https://tinypng.com/) - [TinyJPG](https://tinyjpg.com/) ### OG Image The default OG image will be placed if a post does not specify the OG image. Though not required, OG image related to the post should be specify in the frontmatter. The recommended size for OG image is **_1200 X 640_** px. > Since AstroPaper v1.4.0, OG images will be generated automatically if not specified. Check out [the announcement](https://astro-paper.pages.dev/posts/dynamic-og-image-generation-in-astropaper-blog-posts/).