{"id":26422975,"url":"https://github.com/linjonh/techblog","last_synced_at":"2026-04-13T21:03:02.430Z","repository":{"id":40232473,"uuid":"134693573","full_name":"linjonh/TechBlog","owner":"linjonh","description":"技术博客，软件研发相关的技术文章网站","archived":false,"fork":false,"pushed_at":"2026-04-12T10:02:47.000Z","size":705075,"stargazers_count":26,"open_issues_count":4,"forks_count":3,"subscribers_count":1,"default_branch":"nextjs","last_synced_at":"2026-04-12T12:06:55.099Z","etag":null,"topics":["android","blog","hugo","hugo-site","jekyll","static-site-generator","website"],"latest_commit_sha":null,"homepage":"https://tech-blogs.web.app/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/linjonh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2018-05-24T09:34:51.000Z","updated_at":"2026-01-20T05:15:35.000Z","dependencies_parsed_at":"2025-02-05T10:29:48.415Z","dependency_job_id":"5a501879-515c-4d4b-99e5-2f8d0e9c61b5","html_url":"https://github.com/linjonh/TechBlog","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/linjonh/TechBlog","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linjonh%2FTechBlog","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linjonh%2FTechBlog/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linjonh%2FTechBlog/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linjonh%2FTechBlog/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/linjonh","download_url":"https://codeload.github.com/linjonh/TechBlog/tar.gz/refs/heads/nextjs","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linjonh%2FTechBlog/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31770727,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-13T20:17:16.280Z","status":"ssl_error","status_checked_at":"2026-04-13T20:17:08.216Z","response_time":93,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","blog","hugo","hugo-site","jekyll","static-site-generator","website"],"created_at":"2025-03-18T02:37:04.069Z","updated_at":"2026-04-13T21:03:02.424Z","avatar_url":"https://github.com/linjonh.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Next-js Blog Project\n\n# 导入makerdown文件到数据库记录\n\n需要修改js里的 authentication API token 和数据库部署的URL地址\n\n```bash\nnode create-categories-tags.js\nnode import-md-with-relations.js\n```\n# 博客框架：strapi + PostgreSQL + nextjs-blog\n我目前情况：\n\n    ✔ 有非常多文章（上万篇）\n    ✔ 内容以 Markdown 为主\n    ✔ 有技术背景（Node.js、CI/CD、Prisma、Next.js 都熟）\n    ✔ 想要性能好、可扩展\n\n最优解：Next.js + Strapi（Headless CMS） + Meilisearch\n\n优势非常明显：\n\n    功能\t实现方式\n    内容管理\tStrapi（超级方便）\n    存储\tPostgreSQL\n    前台展示\tNext.js\n    搜索\tMeilisearch（极速）\n    部署\tVercel/Cloudflare 或你自己的 VPS\n\n性能：\n\n    上万篇文章毫无压力\n\n    不再有静态构建卡死\n\n    可扩展为门户网站级别\n\n\n**一步一步搭建一个最适合上万篇文章的 Headless CMS 架构**。\n\n## 🚀 推荐的组合\n\n为了简单、稳定、扩展性强，我建议：\n\n### **Strapi（后端 CMS） + PostgreSQL（数据库） + Next.js（前端）** \n\n这是现在“上万篇文章网站”最常用、可扩展性最强的组合。\n\n---\n\n# ✅ 第一步：搭建 Strapi（内容后台）\n\nStrapi 是基于 Node.js 的 Headless CMS，很容易用。\n\n## 1. 安装 Node.js 18+\n\n本地或服务器（建议 Linux）安装 Node.js（18 或以上）。\n\n## 2. 新建 Strapi 项目\n\n```bash\nnpx create-strapi-app blog-cms --quickstart\n```\n\n运行后打开：\n\n```\nhttp://localhost:1337/admin\n```\n\n即可进入后台。\n\n---\n\n# ✅ 第二步：创建“文章模型”\n\n在 Strapi 后台里：\n\n1. Content-Type Builder → Create new collection type\n2. 名字：`article`\n3. 添加字段：\n\n   * `title`（文本）\n   * `slug`（唯一文本）\n   * `content`（Rich Text 或 Markdown）\n   * `date`（日期）\n   * `tags`（多选）\n   * `category`（单选）\n\n保存后 Strapi 会自动生成 API：\n\n```\nGET /api/articles\nGET /api/articles/:id\n```\n\n你已经有一个可供前端使用的 API 了。\n\n---\n\n# ✅ 第三步：让 Strapi 支持 markdown 批量导入（上万篇文章）\n\n你可能已有大量 markdown 文件。\n\n你可以用命令行脚本批量导入，例如：\n\n```bash\nconst fs = require('fs');\nconst axios = require('axios');\n\nasync function uploadMD() {\n  const files = fs.readdirSync('./posts');\n\n  for (const file of files) {\n    const md = fs.readFileSync(`./posts/${file}`, 'utf8');\n    const title = file.replace('.md', '');\n\n    await axios.post('http://localhost:1337/api/articles', {\n      data: {\n        title,\n        content: md,\n      }\n    });\n  }\n}\n\nuploadMD();\n```\n\n这可以把所有 markdown 文章导入 Strapi 的数据库。\n\n\u003e 你有多少篇文章都没关系，10 万篇都能存。\n\n---\n\n# ✅ 第四步：搭建 Next.js 前端\n\nNext.js 负责展示文章页面。\n\n## 新建 Next.js 项目\n\n```bash\nnpx create-next-app blog-web\n```\n\n## 获取文章列表\n\n在 Next.js 页面中 API 调用：\n\n```js\nconst res = await fetch('http://localhost:1337/api/articles');\nconst data = await res.json();\n```\n\n## 获取单篇文章\n\n```js\nconst res = await fetch(`http://localhost:1337/api/articles/${slug}`);\n```\n\n### Next.js 里用 ISR（Incremental Static Regeneration）\n\n让页面自动更新而无需全站构建：\n\n```js\nexport async function getStaticProps() {\n  const res = await fetch('http://localhost:1337/api/articles');\n  const data = await res.json();\n\n  return {\n    props: { articles: data },\n    revalidate: 60, // 每 60 秒自动更新一次\n  };\n}\n```\n\n---\n\n# ✅ 第五步：加入搜索（上万篇文章必须要有）\n\n你可以用：\n\n### ⭐ **Meilisearch（极速、开源、强烈推荐）**\n\n安装：\n\n```bash\ncurl -L https://install.meilisearch.com | sh\n./meilisearch\n```\n或\n```bash\ndocker run -it --rm \\\n  -p 7700:7700 \\\n  -e MEILI_MASTER_KEY=\"masterKey\" \\\n  getmeili/meilisearch:latest\n```\n\n同步 Strapi 内容：\n\n* 安装 strapi-plugin-meilisearch\n* 自动 push 数据到搜索索引\n\n前端调用搜索 API 即可。\n\n---\n\n# ✅ 第六步：部署方案（最稳）\n\n### Strapi（后端）部署到 VPS 或 Docker：\n\n```bash\ndocker run -p 1337:1337 strapi/strapi\n```\n\n### Next.js（前端）部署到：\n\n* Vercel（最简单）\n* Cloudflare Pages（免费）\n* Netlify\n\n### 搜索（Meilisearch）部署到：\n\n* VPS 上 Docker\n* 或 Meilisearch Cloud\n\n---\n\n# ✅ 整体架构图（超简单版本）\n\n```\n     你写文章（Markdown）\n             ↓\n      Strapi (CMS) —— PostgreSQL\n             ↓\n      Meilisearch (全文搜索)\n             ↓\n      Next.js 前端网站 (ISR/SSR)\n             ↓\n           用户访问\n```\n\n**无论几千篇、上万篇文章，都能秒级访问、稳定运行。**\n\n---\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flinjonh%2Ftechblog","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flinjonh%2Ftechblog","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flinjonh%2Ftechblog/lists"}