The portfolio is configured entirely through environment variables. There are no configuration files to edit and no build-time constants to change — every tuneable behaviour is controlled at runtime viaDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/santiagonieto09/portafolio/llms.txt
Use this file to discover all available pages before exploring further.
.env. Only GITHUB_TOKEN and CRON_SECRET are required for a hardened production deployment; the application starts and renders correctly with none of them set.
Environment Variables
A GitHub Personal Access Token sent as the
Authorization: Bearer <token> header on every GitHub REST API request.- Why it matters: GitHub’s unauthenticated API allows 60 requests per hour per originating IP address. Setting this token raises that limit to 5,000 requests per hour, which is essential for any production workload.
- Token type: Classic personal access token (PAT). Fine-grained tokens also work if you grant them read access to public repository metadata.
- Required scopes: None. All data fetched by the portfolio (user profile, repositories, social accounts, public events) is publicly accessible without any OAuth scope.
- Security: This variable is consumed exclusively in
infrastructure/github/github-api.server.ts. The.server.tsfilename convention ensures it is stripped from the client bundle at build time and never sent to the browser. - Legacy alias: The server module also accepts
GITHUB_API_KEYas a fallback (process.env.GITHUB_TOKEN ?? process.env.GITHUB_API_KEY).GITHUB_TOKENtakes precedence;GITHUB_API_KEYis supported for backwards compatibility only. SetGITHUB_TOKENfor all new deployments.
A shared secret that protects the
POST /api/public/sync cache-refresh endpoint from unauthorized callers.- How it is verified: The endpoint reads the secret from the incoming request’s
x-cron-secretheader. If that header is absent, it falls back to theAuthorization: Bearer <secret>header. If neither matches the configured value, the endpoint returns503 Service Unavailable. - If unset: The
/api/public/syncendpoint is disabled entirely and returns503for all callers. This is a safe default — the snapshot cache is also refreshed automatically on the next organic page load after the TTL expires. - Best practice: Generate a cryptographically random secret (e.g.
openssl rand -hex 32) and store it as a secret in your deployment platform and your cron service.
The canonical base URL of the deployed site, for example
https://santiagonieto.dev.- Used in: The
sitemap[.]xml.tsroute to build absolute<loc>URLs, and in the<head>of the main page to populateog:urlfor Open Graph metadata. - If unset: The application derives the origin from the incoming HTTP request (
request.headers.get('host')) at runtime. This is accurate for most deployments but can produce incorrect results behind reverse proxies that strip theHostheader. - Format: Include the protocol and no trailing slash:
https://santiagonieto.dev✅,https://santiagonieto.dev/❌.
Creating a GitHub Token
Open Personal Access Token settings
Log in to GitHub and navigate to Settings → Developer settings → Personal access tokens → Tokens (classic).Direct URL: https://github.com/settings/tokens
Generate a new token
Click “Generate new token” and choose “Generate new token (classic)” from the dropdown.
Name the token
In the Note field enter a descriptive name such as
portfolio-site so you can identify it later.Set an expiration
Choose an expiration that fits your security policy. For a long-running production site, a 1-year expiration is common. Add a calendar reminder to rotate the token before it expires.
Select scopes
No scopes are required. Leave all checkboxes unchecked. GitHub allows unauthenticated-equivalent read access to public user profiles and repositories via authenticated requests — the token itself (rather than any attached scope) is what raises the rate limit.
Copy and store the token
Click “Generate token” and immediately copy the value — GitHub will not show it again. Add it to your local For production deployments, store the token as an encrypted environment variable or secret in your platform (Vercel, Cloudflare, GitHub Actions Secrets, etc.).
.env file:.env
Cron Sync Scheduling
The snapshot cache has a one-week TTL. For a portfolio that changes infrequently this is acceptable — but if you want the cache to refresh on a predictable schedule rather than on the next organic visit after expiry, you can callPOST /api/public/sync from an external cron service.
The endpoint is protected by CRON_SECRET. The caller must send the secret in the x-cron-secret header. Here is a complete GitHub Actions workflow that triggers a weekly refresh every Monday at 06:00 UTC:
.github/workflows/sync.yml
SITE_URL (e.g. https://santiagonieto.dev — include the protocol, no trailing slash) and CRON_SECRET as encrypted secrets in your GitHub repository settings so they are never exposed in workflow logs.
Runtime Target
The default production build target is Vercel, configured via the Nitro preset invite.config.ts:
vite.config.ts (excerpt)
cloudflare-workers to match the Workers runtime. No manual change is needed — the correct preset is injected at build time by the sandbox.
The snapshot cache implementation in infrastructure/github/snapshot-cache.ts is runtime-aware:
- Cloudflare Workers — Uses the Cloudflare Cache API (
caches.default) for edge-distributed, persistent caching across all PoPs. - Vercel / Node.js — Falls back to an in-process
Mapwhen the Cloudflare Cache API is unavailable. This cache is local to each serverless function instance and does not persist across cold starts; the cron sync workflow keeps the cache warm to minimise cold-start fetches in production.