Publicolio is a zero-configuration GitHub portfolio generator. It lets you fetch profile data, curate repositories, apply visual themes, and publish a shareable portfolio URL in minutes.
- Fetches profile and repository data from GitHub.
- Supports optional personal access token input in builder mode for private or owner-only repositories.
- Includes 6 portfolio themes with live preview.
- Exposes practical editor controls for layout, typography, card style, and accent color.
- Encodes portfolio state into query parameters for deterministic sharing.
- Supports optional short links through a Cloudflare Worker.
- Supports short-link domain selection (
auto,workers.dev,custom). - Caches builder state for returning users.
- Supports
Update Linkflow to preserve the same short code when backend overwrite is supported.
Publicolio runs in two modes:
- Builder mode
- Activated when
userandthemequery params are not present. - Renders the interactive editor (
LandingBuilder) to fetch data, choose repos, style output, and deploy links.
- Renderer mode
- Activated when
userandthemequery params are present. - Renders the final portfolio page (
PortfolioRenderer) directly from URL state.
- Builder calls
fetchDeveloperData(username, token?). - GitHub profile and repositories are fetched through proxy-aware network logic.
- Builder composes a long renderer URL from selected repositories and theme options.
- Builder sends URL to shortener endpoint (if configured).
Deploy Portfoliocreates a new short link.Update Linkrequests same-code overwrite for an existing short URL.- If backend does not support same-code overwrite, UI returns a clear update-unsupported message.
- If shortener fails, app falls back to the full long URL.
Builder state is persisted in localStorage.
Cached:
- Username
- Selected theme
- Theme options
- Short-link domain mode
- Last generated short URL
- Per-user repository selections
- Cached profile snapshot for faster restore
Not cached:
- GitHub token (intentionally excluded for safety)
Themes:
- Aurora
- Liquid Glass
- Bento Grid
- Minimalism
- Neubrutalism
- Terminal
Controls:
- Show Avatar
- Show Bio
- Show Stats
- Layout density:
compactorcomfortable - Repository sort:
featured,stars,name - Card style:
softorsharp - Text scale:
sm,md,lg - Accent color
- Short-link domain mode:
auto,workers.dev,custom
- React 19
- TypeScript
- Vite 8
- Tailwind CSS 4
- Lucide React
src/App.tsx- mode switch between builder and renderer.src/components/LandingBuilder.tsx- editor UI, fetch flow, repo selection, deploy/update actions.src/components/PortfolioRenderer.tsx- final portfolio page runtime.src/services/api.ts- GitHub and shortener network layer.src/components/themes/*- theme implementations.
Prerequisite: Node.js 20+
- Install dependencies.
npm install- Create local environment file.
cp .env.example .envPowerShell alternative:
Copy-Item .env.example .env- Start development server.
npm run dev- Build for production.
npm run build- Preview production build locally.
npm run previewCreate .env from .env.example and configure the following:
| Variable | Required | Description |
|---|---|---|
VITE_CORS_PROXY_URL |
Yes | Proxy prefix for GitHub requests. Format: https://your-proxy.workers.dev/?url= |
VITE_SHORTENER_URL |
Recommended | Primary shortener API endpoint, typically https://your-shortener.workers.dev/api/shorten |
VITE_SHORTENER_API_URL |
Optional | Backward-compatible alias for shortener endpoint |
VITE_SHORTENER_WORKERS_DOMAIN |
Optional | Domain used when short-link mode is workers.dev |
VITE_SHORTENER_CUSTOM_DOMAIN |
Optional | Domain used when short-link mode is custom |
Notes:
VITE_SHORTENER_URLandVITE_SHORTENER_API_URLare both supported.- If shortener config is missing or fails at runtime, deploy still returns a usable full URL.
Reference implementations:
- Shortener worker gist: https://gist.github.com/nishal21/ba187199cd00ea6623b6cf4407e3a48d
- CORS proxy repository: https://github.com/nishal21/portfolio-cors-proxy
Expected frontend request:
GET {VITE_CORS_PROXY_URL}{encodeURIComponent(targetUrl)}where proxy base ends with?url=- Optional request header:
X-Custom-GitHub-Token
Expected proxy behavior:
- Returns
400when?url=is missing. - For GitHub API targets, forwards either:
- user token from
X-Custom-GitHub-Token, or - worker secret
GITHUB_TOKEN.
- user token from
- Includes CORS headers allowing
X-Custom-GitHub-Token.
Expected endpoint:
POST /api/shorten
Frontend payload:
{
"longUrl": "https://...",
"url": "https://...",
"shortCode": "existing-code-when-updating",
"code": "existing-code-when-updating",
"slug": "existing-code-when-updating"
}Update-link requirement:
- To support
Update Linkwithout changing URL, worker must reuse provided code and overwrite existing KV value. - If worker always generates random codes, frontend will show an explicit update-unsupported message.
Accepted response fields:
shortUrlshortened_urlshort_urlurl
Redirect behavior:
GET /:codereturns HTTP302to original long URL.
KV binding:
- Bind KV namespace as
URL_DB.
user: GitHub usernametheme: theme keyrepos: comma-separated repository namesstats:1or0avatar:1or0bio:1or0accent: hex color without#layout:compactorcomfortablesort:featured,stars, ornamecard:softorsharptext:sm,md, orlg
Publicolio is a static frontend and can be deployed on any static host.
Production checklist:
- Configure required VITE variables on your hosting platform.
- Deploy and verify CORS proxy worker.
- Deploy and verify shortener worker.
- Point custom short-link domain to shortener worker if using
custommode.
Included workflow:
.github/workflows/deploy-pages.yml
Workflow behavior:
- Runs on every push to
main. - Installs dependencies and builds the Vite app.
- Uploads
dist/as a Pages artifact. - Deploys automatically to GitHub Pages.
Build-time env values are read from GitHub Actions Variables (preferred) and also supported via Secrets:
VITE_CORS_PROXY_URLVITE_SHORTENER_URLVITE_SHORTENER_API_URLVITE_SHORTENER_WORKERS_DOMAINVITE_SHORTENER_CUSTOM_DOMAIN
Recommended hostname split:
- Shortener:
short.example.com - App:
app.example.com
- In repository Settings -> Pages, set Source to
GitHub Actions. - Set custom domain to
app.example.com. - Enable HTTPS after DNS verification.
- Add DNS record:
- Type:
CNAME - Name:
app - Target:
username.github.io
- Type:
- Keep
public/CNAMEaligned with your custom app domain.
Important:
- DNS target must be host-only (
username.github.io), not a URL path.
If using default project URL:
https://nishal21.github.io/Publicolio/
Included assets and metadata:
index.htmlwith canonical, robots directives, Open Graph, Twitter tags, geo tags, and JSON-LD.public/robots.txtwith sitemap reference and crawler directives.public/sitemap.xmlwith canonical homepage URL.public/llms.txtfor AI/LLM crawler guidance.public/og-cover.pngfor robust social previews.
- Verify shortener endpoint env value.
- Verify worker route includes
/api/shorten. - Verify worker accepts
longUrlpayload. - Check browser network errors (CORS, 400, 500).
- Use fallback full URL if shortener is unavailable.
- Ensure worker accepts
shortCode,code, orslug. - Ensure worker overwrites KV mapping for existing code.
- Ensure redirect endpoint returns
302with updated destination. - If frontend shows update-unsupported, backend returned a different code.
- Verify
VITE_CORS_PROXY_URL. - Verify proxy forwards GitHub status and response body.
- For private repos, provide a valid token in builder mode.
Please review CONTRIBUTING.md for setup, quality checks, and pull request guidelines.
Licensed under the MIT License. See LICENSE.
Created by Nishal K.
- GitHub: @nishal21
- Instagram: @demonking.___
