Skip to content

Sergo706/portfolio

Repository files navigation

Personal Portfolio

This repository contains the source code for my personal portfolio website.

The application uses Nuxt, Nuxt UI, Tailwind CSS, Nuxt Content to manage content, and a custom read-only Git repository viewer.

You can check it out here.

The site is statically generated; however, the Git viewer is purely client-side.

Beyond standard portfolio features, this repository serves as a serverless, read-only Git infrastructure. It includes a custom-built Git repository viewer that parses bare repositories natively in the browser. Instead of exposing repository contents through an API, the application downloads Git packfiles via the Git Dumb HTTP protocol and reconstructs the repository client-side using isomorphic-git. Trees, blobs, commits, history, and diffs are derived directly from Git objects in the browser.

The Git repository viewer uses a custom Nitro API proxy (/api/git-proxy) to fetch static Git objects (.pack, info/refs) from a private Cloudflare R2 bucket via the Dumb HTTP protocol, rendering them entirely client-side.

Cloudflare is optional. You can point the proxy to a local path where you store all your repositories and serve them directly from there.

The Git features will not work properly on massive repositories (QEMU, the Linux kernel, etc.). For this scale, consider looking into cgit or similar.

Features

Git

  • Clones and reads bare repositories directly in the browser using isomorphic-git.

  • Calculates character-level diffs on the client using the diff library, supports both split and unified views, and weaves them into server-rendered Shiki HTML tokens.

  • Virtual File System: Uses lightning-fs backed by IndexedDB to cache repository objects, reducing bandwidth usage and load times for repeat visits.

  • Has file views with code highlighting, tree views, commit trees, and filtering functionality.

  • Uses aggressive caching.

Portfolio

Usage

Using Cloudflare

If you decide to use this repository for your own portfolio, you will need to modify scripts/getPublicRepos.mjs to point to your account, create a GitHub App with configured webhooks pointing to https://your-domain.com/webhooks/repos-sync, configure an appropriate secret, and provide it as the NUXT_WEBHOOK_SECRET environment variable. Then simply install the GitHub App on all your repositories.

Your webhook needs to fire on Create, Push, Repository, Delete, and Release events.

Once you have a GitHub App, create a GitHub Personal Access Token with Read access to code and metadata, and Read & Write access to Actions, allowing the application to trigger the sync-repos.yml workflow.

At this point, every time you make a change to one of your repositories, GitHub will fire a webhook to /webhooks/repos-sync. This handler validates that the request is coming from GitHub and triggers the workflow at:

https://api.github.com/repos/${owner}/${portfolioRepo}/actions/workflows/sync-repos.yml/dispatches

where ${portfolioRepo} is portfolio and ${owner} is pushPayload.repository.owner.login, for public repositories.

The workflow uploads the bare repositories generated by scripts/getPublicRepos.mjs to the configured Cloudflare R2 bucket using the credentials configured in your repository secrets:

CLOUDFLARE_R2_ACCOUNT_ID: secrets.CLOUDFLARE_R2_ACCOUNT_ID
CLOUDFLARE_R2_ACCESS_KEY_ID: secrets.CLOUDFLARE_R2_ACCESS_KEY_ID
CLOUDFLARE_R2_SECRET_ACCESS_KEY: secrets.CLOUDFLARE_R2_SECRET_ACCESS_KEY
CLOUDFLARE_R2_BUCKET: secrets.CLOUDFLARE_R2_BUCKET

Then go to your Cloudflare account and supply the following environment variables:

NUXT_RESEND_API_KEY=your_resend_api_key
NUXT_TURNSTILE_SECRET_KEY=your_turnstile_secret_key
NUXT_PUBLIC_TURNSTILE_SITE_KEY=your_turnstile_site_key
NUXT_WEBHOOK_SECRET=the_webhook_secret
NUXT_GITHUB_TOKEN=the_pat_you_generated

Finally, bind the R2 bucket you want to use to the R2_BUCKET environment variable.

Self-hosting

If you do not want this behavior, supply the NUXT_REPOS_DIR environment variable, or simply make sure all repositories you want to expose are located in cwd/repos.

This option does not require GitHub webhooks, buckets, or any additional infrastructure. It also does not include any automation except the scripts/getPublicRepos.mjs script.

Site Configuration

To modify the site name, URL, and related settings, edit nuxt.config.ts and app/app.config.ts with your data.

To modify the site's content, edit the files in the content/ directory before building or deploying the site.

Environment Variables

  • NUXT_RESEND_API_KEY - Used for receiving emails from leads. Emails will be sent using this key to your configured email address (Required). Change the receiving email in server/api/contact.post.ts.
  • NUXT_TURNSTILE_SECRET_KEY - Secret key for the Cloudflare Turnstile CAPTCHA used by the contact form (Required).
  • NUXT_PUBLIC_TURNSTILE_SITE_KEY - Public site key for the Cloudflare Turnstile CAPTCHA (Required).
  • NUXT_WEBHOOK_SECRET - Secret used to verify that webhook requests originate from your GitHub App (Required when using Cloudflare).
  • NUXT_GITHUB_TOKEN - GitHub Personal Access Token used to trigger the synchronization workflow (Required when using Cloudflare).
  • NUXT_REPOS_DIR - Directory containing your repositories. Defaults to cwd/repos when omitted and when an R2 bucket binding is not configured.

Local Development

You will need Node.js and npm installed to run the project locally.

Clone the repository:

git clone https://github.com/Sergo706/portfolio.git
cd portfolio

Or:

git clone https://riavzon.com/api/git-proxy/portfolio.git

Install dependencies:

npm install

Configure environment variables.

Create a .env file in the root directory. You will need to provide the required keys for the contact form and Git proxy to function fully during local development.

NUXT_RESEND_API_KEY=your_resend_api_key
NUXT_TURNSTILE_SECRET_KEY=your_turnstile_secret_key
NUXT_PUBLIC_TURNSTILE_SITE_KEY=your_turnstile_site_key
NUXT_WEBHOOK_SECRET=the_webhook_secret
NUXT_GITHUB_TOKEN=the_pat_you_generated
NUXT_REPOS_DIR=local_development_dir

Start the Nuxt development server:

npm run dev

The application will be available at http://localhost:3000.

Deployment

This application is built for the Cloudflare Pages environment. Deployment is fully automated via GitHub Actions (.github/workflows/deploy.yml).

To build the application manually for production:

npm run build

This generates the .output directory containing the Nitro server and static public assets, ready to be deployed.

About

portfolio website

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors