GitHub-native CMS for Markdown blogs.
- GitHub OAuth authentication with secure cookie-based session.
- Repository bootstrap for blogex-managed repos (
blogex.config.json+ starter_postsfile). - Guided workspace flow for selecting repository and branch.
- Markdown authoring workflow with explorer, edit/preview, create, rename, and commit.
- Per-repo workspace settings for target repo/branch/directory.
- Sync and compare tools between source and target markdown files.
- Client-side caching for repository/session UX with manual refresh.
- Mobile-friendly UI with consistent styling and reusable components.
- Frontend: React 19 with Next.js 16 (App Router)
- Backend: Next.js Route Handlers (
src/app/api) - Styling: Tailwind CSS 4
- Editor: Custom markdown editor UI with preview via
react-markdown,remark-gfm, and frontmatter parsing viagray-matter - Routing: Next.js App Router (
src/app) - API: Internal REST endpoints in Next.js + GitHub REST API (
api.github.com)
blogex/
└─ src/
├─ app/ # Next.js App Router pages and API route handlers
│ ├─ api/ # Server API endpoints used by the UI
│ ├─ auth/ # OAuth callback route segment
│ ├─ user/ # Logged-in user landing page
│ └─ workspace/ # Workspace and workspace settings pages
├─ components/ # Reusable UI components and workspace step views
├─ hooks/ # Client hooks (workspace orchestration logic)
└─ lib/ # Shared utilities, API clients, constants, config helpers- Node.js
v20.19.6(recommended) - npm
v10+ - A GitHub OAuth App with callback URL set to:
http://localhost:3000/auth/github/callback(local development)
- Use the expected Node version:
nvm use 20.19.6- Install dependencies:
npm install-
Create a GitHub OAuth App:
- Open GitHub and go to
Settings->Developer settings->OAuth Apps. - Click
New OAuth App. - Set
Application name(example:blogex-local). - Set
Homepage URLtohttp://localhost:3000. - Set
Authorization callback URLtohttp://localhost:3000/auth/github/callback. - Click
Register application. - Copy the
Client ID. - Click
Generate a new client secret, then copy the generated secret.
- Open GitHub and go to
-
Create
.env.local:-
Copy the example file:
cp .env.example .env.local
-
Update
.env.localwith your values:# .env.local GITHUB_CLIENT_ID=your_github_oauth_client_id GITHUB_CLIENT_SECRET=your_github_oauth_client_secret APP_URL=http://localhost:3000 # Optional: set to enable Google Analytics NEXT_PUBLIC_GA_MEASUREMENT_ID=G-XXXXXXXXXX
-
-
Run the app:
npm run dev- Open
http://localhost:3000.
npm run dev: Start the development server.npm run build: Build for production.npm run start: Run the production server.npm run lint: Run ESLint.
- Push your repository to GitHub.
- In Vercel, click
Add New->Project, then import this repository. - Configure production environment variables in Vercel:
GITHUB_CLIENT_IDGITHUB_CLIENT_SECRETAPP_URL=https://<your-vercel-domain>NEXT_PUBLIC_GA_MEASUREMENT_ID(optional)
- Deploy the project.
- In your existing GitHub OAuth App settings, update:
Homepage URL=https://<your-vercel-domain>Authorization callback URL=https://<your-vercel-domain>/auth/github/callback
- Redeploy if needed, then test login/logout and repository actions in production.
-
Login: Authenticate with GitHub
- Open the app and click
Login with GitHub. - Complete OAuth consent on GitHub.
- You will be redirected to the user page after successful login.
- Open the app and click
-
Create Repository: Set up a blogex markdown manager repository
- On the user page, enter a repository name and visibility.
- Submit the create form.
- blogex initializes the repository with:
blogex.config.jsonat root_posts/hello-world.mdas starter content
-
Open Workspace: Select repository and branch
- Click
Open Workspace. - Step 1: Select a repository.
- Step 2: Select a branch.
- Step 3: Open the explorer to browse
_posts.
- Click
-
Write And Edit Markdown
- Select a markdown file from the explorer.
- Edit in
Editmode or preview rendered output inPreviewmode. - Save changes to create a commit on the selected branch.
-
Create Or Rename Markdown Files
- Create a new file by entering a title.
- blogex generates a slug filename and default frontmatter.
- Rename existing files directly from the explorer action bar.
-
Configure Workspace Settings
- Open
/workspace/settings. - Load or save
blogex.config.jsonfor the selected repo/branch. - Configure
targetRepo,targetBranch, andtargetDirectoryfor sync features.
- Open
-
Sync From Target Repository
- In Workspace Settings, use
Sync markdownsto list source files from target repo. - Select one file and sync it into the current repo.
- In workspace explorer, use file status and compare to verify source vs target.
- In Workspace Settings, use
-
Logout
- Use
Log outon the user page to clear the session cookie and return home.
- Use
blogex uses a per-repository blogex.config.json file for workspace target settings.
Full configuration details and examples are available in docs/config.md.
Full API documentation is available in docs/api.md.
Contributions are welcome. Please open an issue for bugs or feature proposals before large changes.
For pull requests, keep changes focused, update docs when behavior/API changes, and run npm run lint before submitting.