feat:blog
Like Go's official blog system (References: https://go.dev/blog/ and https://github.com/golang/website)
Design
Blog List Page
Path: goplus.org/blog/ Like https://go.dev/blog/
- Display recent blog posts in reverse chronological order
- Each list item should include:
- Title
- Date
- Author
- Summary "More articles" button/link that leads to the complete blog list
Path: goplus.org/blog/all Like https://go.dev/blog/all
- Display all blog posts in a list format
Blog Post Format
Following Go's blog post structure, each blog post should be written in Markdown with a metadata header:
---
title: "Post Title"
date: YYYY-MM-DD HH:mm±HH:mm
by:
- Author Name
summary: Brief description of the post.
---
Post content...
The Go website sorts blog posts based on the Date field in their metadata, using the YYYY-MM-DD format. While this approach includes a secondary sort by title, it may not always reflect the precise posting order.
https://github.com/golang/website/blob/master/cmd/golangorg/godev.go
Although introducing an ID field could solve this, it would add unnecessary cognitive overhead for post authors.
I believe the current time-based sorting offers a significant advantage: it allows authors to write posts in a natural Markdown style (despite requiring metadata), similar to how they would write any other Markdown document.
However, I suggest using the YYYY-MM-DD HH:mm±HH:mm format for the date field. This would:
- Provide more precise sorting while maintaining chronological order
- Not increase cognitive load for authors (they just need to include the posting time)
- Preserve the simplicity of the current metadata approach
Blog Detail Page
Path: goplus.org/blog/article/[slug] Like https://go.dev/blog/swisstable Renders the corresponding md_name.md file Includes navigation links to previous and next blog posts
Image Handling
Two approaches for handling images in blog posts: 1.Standard Markdown Format (Current GoPlus approach):

- HTML Format (Go's blog approach):
<div class="image"><div class="centered">
<figure>
<img src="path/to/image.png" alt="Image description"/>
</figure>
</div></div>
Note: For now, maintain the current markdown image syntax without modification. Use default styling for markdown images.
Expect Markdown source structure
in /goplus.org/articles
articles/
├── 6years.md # Blog post without images
├── community-outreach-working-group.md # Blog post without images
├── fuzz-beta.md # Blog post without images
├── 6years/ # Resources for 6years.md
│ ├── growth-chart.png
│ └── community-stats.svg
├── community-outreach-working-group/ # Resources for community post
│ └── team-structure.png
└── fuzz-beta/ # Resources for fuzz post
├── benchmark.png
└── workflow.svg
Implement
- use SSG to generate all blog page.
- A timezone-aware date display that adapts to the user's local time through client-side hydration
- [x] basic structure
- [x] goplus.org/blog show newest blog
- [x] link to goplus.org/blog/all
- [x] show items(title,date,author,summary)
- [x] show different date format in different zone
- [x] goplus.org/blog/all show all blog
- [x] goplus.org/blog/[slug] show correspoding markdown
- [x] title,author,date
- [x] prev&next articles
- [x] markdown render
- [x] code highlight
- [x] goplus.org/blog show newest blog
react-markdown not render the heading's id https://github.com/remarkjs/react-markdown/issues/69 and it's not the basic markdown feature. maybe support it in another pr.
The latest updates on your projects. Learn more about Vercel for Git ↗︎
| Name | Status | Preview | Comments | Updated (UTC) |
|---|---|---|---|---|
| www | ✅ Ready (Inspect) | Visit Preview | 💬 Add feedback | Mar 19, 2025 9:59am |
use copy-webpack-plugin will cause build widget some error, so only when building goplus.org to use the plugin
> [email protected] build:widgets
> tsc widgets/global/loader.ts && node widgets/build.js && rm widgets/global/loader.js
node_modules/@types/node/globals.d.ts:72:13 - error TS2403: Subsequent variable declarations must have the same type. Variable 'AbortSignal' must be of type '{ new (): AbortSignal; prototype: AbortSignal; abort(reason?: any): AbortSignal; timeout(milliseconds: number): AbortSignal; }', but here has type '{ new (): AbortSignal; prototype: AbortSignal; }'.
72 declare var AbortSignal: {
~~~~~~~~~~~
node_modules/typescript/lib/lib.dom.d.ts:2071:13
2071 declare var AbortSignal: {
~~~~~~~~~~~
'AbortSignal' was also declared here.
Found 1 error in node_modules/@types/node/globals.d.ts:72