Featured image of post Just 2 Simple Steps to Permanently Add Social Feed Features Like 'Moments' to Your Static Blog

Just 2 Simple Steps to Permanently Add Social Feed Features Like 'Moments' to Your Static Blog

Adding a “Moments” or social feed page to a static blog is a long-discussed topic. Previous solutions were either cumbersome to set up or inconvenient to use. To solve this problem definitively, I recently experimented with using GitHub Issues – requiring just two simple steps to create a dynamically updatable feed page.


Core Concept

Use GitHub Issues as a publishing platform for feed content, then reference those issues on a new static blog page. GitHub Actions monitors issue changes to trigger blog updates automatically.

Advantages:

  1. Simple setup and maintenance – Built on GitHub. Any issues can be resolved with AI assistance.
  2. Mobile-friendly – GitHub’s mobile app allows pinning issues to the home screen for quick posting, similar to WeChat Moments.
  3. Secure and scalable – Fully controlled content with unlimited capacity and easy migration.

Disadvantages: None identified yet.

Implementation Guide

Step 1: Create a Feed Page in Your Blog Template

For Hugo, create a file like moments.html in the layouts folder, using resources.GetRemote to fetch content from a GitHub Issue (e.g., https://api.github.com/repos/microsoft/vscode/issues/519/comments).

Adapt a static page template with your theme settings.

Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
{{ define "main" }}  
<article class="main-article">  
    {{ $url := "https://api.github.com/repos/microsoft/vscode/issues/519/comments" }}  
    {{ $opts := dict  
        "headers" (dict "User-Agent" "Hugo Static Site Generator")  
    }}  
    {{ with resources.GetRemote $url $opts }}  
        {{ if and .Content (ne .Content "") }}  
            {{ $comments := .Content | transform.Unmarshal (dict "format" "json") }}  
            <div class="moments-feed">  
                {{ range $comments }}  
                    <article class="moment-article">  
                        <header class="article-header">  
                            <div class="article-details">  
                                <footer class="article-time">  
                                    <div>  
                                        {{ .created_at | time.Format "2006-01-02 15:04" }}</time>  
                                    </div>  
                                </footer>  
                            </div>  
                        </header>  
                        <section class="article-content">  
                            <div class="moment-content">  
                                {{ .body | markdownify }}  
                            </div>  
                        </section>  
                    </article>  
                {{ else }}  
                    <p>No updates yet</p>  
                {{ end }}  
            </div>  
        {{ else }}  
            <p class="no-content">Empty content</p>  
        {{ end }}  
    {{ else }}  
        <p class="error">⚠️ Failed to load comments</p>  
    {{ end }}  
</article>  

Step 2: Set Up an Update Trigger

Note: Private repositories block external image access in issues. Use a public repository.

Option A: Blog and Feed in the Same Repo

Add this to your deployment workflow:

1
2
3
on:  
  issue_comment:  
    types: [created, edited]  

Option B: Separate Repositories

  1. Create a public repository dedicated to feed content.
  2. Add an issue.yml file under .github/workflows as a trigger.
  3. Generate a Personal access token with repo permissions in GitHub settings, then add it to the feed repo’s Secrets as PAT.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
name: Trigger Empty Commit on Issue Update  

on:  
  issue_comment:  
    types: [created, edited]  

jobs:  
  trigger-empty-commit:  
    runs-on: ubuntu-latest  
    steps:  
      - name: Check if the comment is on the target issue  
        id: check-issue  
        run: |  
          if [ "${{ github.event.issue.number }}" != "1" ]; then  
            echo "should_trigger=false" >> $GITHUB_OUTPUT  
          else  
            echo "should_trigger=true" >> $GITHUB_OUTPUT  
          fi  

      - name: Trigger empty commit in user.github.io  
        if: steps.check-issue.outputs.should_trigger == 'true'  
        uses: actions/github-script@v6  
        env:  
          PAT: ${{ secrets.PAT }}  
        with:  
          script: |  
            const { execSync } = require('child_process');  
            const repo = 'user/user.github.io';  // Replace with your Hugo repo  
            const token = process.env.PAT;  

            try {  
              const repoUrl = `https://x-access-token:${token}@github.com/${repo}.git`;  
              console.log(`Cloning ${repo}...`);  

              execSync(`git clone ${repoUrl}`);  
              process.chdir('user.github.io'); // Replace with your Hugo repo  

              execSync('git config user.name "github-actions[bot]"');  
              execSync('git config user.email "4189+github-actions[bot]@users.noreply.github.com"');  

              execSync('git commit --allow-empty -m "Trigger update from moments/issues/1"');  
              execSync(`git push ${repoUrl} master`);  
              console.log('✅ Empty commit pushed successfully!');  
            } catch (error) {  
              console.error('❌ Error:', error.message);  
              process.exit(1);  
            }  
Built with Hugo, Powered by Github.
Total Posts: 346, Total Words: 477062.
本站已加入BLOGS·CN