Skip to main content

Documentation 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.

The portfolio is built with TanStack Start and Nitro, which supports multiple server runtime targets through its preset system. The default preset in vite.config.ts targets Vercel (Build Output API), producing a .vercel/output directory ready for zero-configuration deployment. Cloudflare Workers is also fully supported and is the preset used automatically inside the Lovable sandbox, so live previews work without any extra configuration.

Vercel deployment

1

Push the repository to GitHub

Make sure your local changes are committed and pushed to a GitHub repository. Vercel connects directly to GitHub to trigger deployments on every push.
2

Import the repository in the Vercel dashboard

Go to vercel.com/new, click Add New → Project, and select your GitHub repository.
3

Set the framework preset to Other

Under Framework Preset, choose Other. Vercel auto-detects the Nitro Build Output API structure from the .vercel/output directory, so no further framework-specific configuration is needed.
4

Configure the build command

Set the Build Command to:
bun run build
If you are using npm instead of Bun, use npm run build. Both invoke vite build, which triggers Nitro’s Vercel preset.
5

Confirm the output directory

The Output Directory is .vercel/output. Nitro’s Vercel preset writes the Build Output API structure here automatically — you do not need to set this manually in the Vercel dashboard; Vercel detects it from the preset output.
6

Add environment variables

Before deploying, add the following environment variables in Settings → Environment Variables:
VariableRequiredPurpose
GITHUB_TOKENRecommendedRaises GitHub API rate limit to 5,000 req/hr
CRON_SECRETRequired for syncProtects POST /api/public/sync
SITE_URLRecommendedCanonical URL for sitemap and OG tags
See Environment Variables for full details on each variable.
7

Deploy

Click Deploy. Vercel builds the project, uploads the Nitro server bundle, and assigns a .vercel.app URL. Subsequent pushes to the main branch trigger automatic redeployments.
The vercel.json at the project root provides the following configuration, which Vercel reads during the build:
vercel.json
{
  "$schema": "https://openapi.vercel.sh/vercel.json",
  "framework": null,
  "devCommand": "bun run dev",
  "installCommand": "bun install",
  "buildCommand": "bun run build"
}
Setting "framework": null tells Vercel not to apply any opinionated framework defaults, deferring entirely to the Nitro Build Output API output. The nitro: { preset: 'vercel' } option in vite.config.ts is what activates this output:
vite.config.ts
import { defineConfig } from "@lovable.dev/vite-tanstack-config";

export default defineConfig({
  tanstackStart: {
    server: { entry: "server" },
  },
  nitro: { preset: "vercel" },
});

Cloudflare Workers deployment

1

Switch the Nitro preset in vite.config.ts

Open vite.config.ts and change the preset from "vercel" to "cloudflare_module":
vite.config.ts
export default defineConfig({
  nitro: { preset: "cloudflare_module" },
});
The rest of the config (TanStack Start, Tailwind, TypeScript paths) is managed by @lovable.dev/vite-tanstack-config and does not need to change.
2

Build the project

Run the standard build command:
bun run build
Nitro compiles the SSR server entry and bundles it for the Cloudflare Workers runtime instead of Vercel’s Node.js-compatible edge functions.
3

Deploy with Wrangler

Use the Wrangler CLI to push the Worker to your Cloudflare account:
wrangler deploy
Wrangler reads the generated wrangler.toml (or .wrangler/) produced by Nitro’s Cloudflare preset and uploads the Worker script automatically.
4

Set secrets via Wrangler

Add your sensitive environment variables as encrypted Cloudflare Worker secrets:
wrangler secret put GITHUB_TOKEN
wrangler secret put CRON_SECRET
Wrangler will prompt you to enter each value interactively. Secrets are stored encrypted and injected at runtime — they never appear in wrangler.toml.
On Cloudflare Workers, the snapshot cache uses caches.default (the Cloudflare Cache API), which is shared across all Worker instances running in the same datacenter. This gives significantly better cache hit rates than the in-memory Map-based fallback used in the Node.js and Vercel runtimes, where each serverless function instance keeps its own independent cache.

Production checklist

Before announcing your portfolio publicly, verify the following:
  • GITHUB_TOKEN is set — Without it, the GitHub REST API allows only 60 unauthenticated requests per hour. A single page load can consume several requests; setting a token raises the limit to 5,000 req/hr.
  • CRON_SECRET is set and a weekly sync is scheduled via GitHub Actions — This keeps repository stats, language data, and release information up to date without manual intervention.
  • SITE_URL is set to your production domain (e.g. https://santiagonieto.dev) — Required for correct absolute URLs in sitemap.xml and in Open Graph og:url meta tags.
  • The portfolio loads at https://your-domain/ with no console errors.
  • The sitemap is valid at https://your-domain/sitemap.xml — check that <loc> entries use your canonical domain, not localhost or a preview URL.

Weekly sync cron

The portfolio’s GitHub data is fetched live on every request and held in a server-side cache. To force a full refresh of that cache on a schedule, POST /api/public/sync triggers a re-fetch and snapshot update. Because Vercel Cron Jobs cannot send custom request headers (the x-cron-secret header is required), the recommended approach is a GitHub Actions workflow:
.github/workflows/sync.yml
name: Weekly portfolio sync
on:
  schedule:
    - cron: '0 6 * * 1'   # Every Monday at 06:00 UTC
jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - name: Trigger sync
        run: |
          curl -s -X POST ${{ secrets.PORTFOLIO_URL }}/api/public/sync \
            -H "x-cron-secret: ${{ secrets.CRON_SECRET }}" \
            -w "\nHTTP %{http_code}"
Add two secrets to your GitHub repository (Settings → Secrets and variables → Actions):
Secret nameValue
PORTFOLIO_URLYour deployed portfolio URL, e.g. https://santiagonieto.dev
CRON_SECRETThe same secret string set in your hosting environment
The workflow runs every Monday at 06:00 UTC, sends a POST to the sync endpoint with the shared secret in the x-cron-secret header, and prints the HTTP response code. A 200 response confirms the snapshot was refreshed successfully.

Build docs developers (and LLMs) love