{"id":15392629,"url":"https://github.com/jackdbd/personal-website","last_synced_at":"2025-07-08T12:40:20.361Z","repository":{"id":38041762,"uuid":"351187251","full_name":"jackdbd/personal-website","owner":"jackdbd","description":"My personal website and blog, built with 11ty and Workbox.","archived":false,"fork":false,"pushed_at":"2025-02-19T00:35:43.000Z","size":4350,"stargazers_count":3,"open_issues_count":10,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-23T17:37:26.835Z","etag":null,"topics":["blog","eleventy","service-worker","workbox"],"latest_commit_sha":null,"homepage":"https://www.giacomodebidda.com/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jackdbd.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-03-24T18:40:04.000Z","updated_at":"2025-02-19T00:35:47.000Z","dependencies_parsed_at":"2023-11-14T18:50:49.146Z","dependency_job_id":"2b2bdbba-1f46-43d3-b2f1-b10dd9f7816a","html_url":"https://github.com/jackdbd/personal-website","commit_stats":{"total_commits":384,"total_committers":2,"mean_commits":192.0,"dds":0.3515625,"last_synced_commit":"3519166a8be9458e0174c67adad08565636858ee"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jackdbd%2Fpersonal-website","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jackdbd%2Fpersonal-website/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jackdbd%2Fpersonal-website/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jackdbd%2Fpersonal-website/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jackdbd","download_url":"https://codeload.github.com/jackdbd/personal-website/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241212185,"owners_count":19927897,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blog","eleventy","service-worker","workbox"],"created_at":"2024-10-01T15:15:25.558Z","updated_at":"2025-02-28T19:30:45.711Z","avatar_url":"https://github.com/jackdbd.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# personal-website\n\n\u003c!-- Do NOT edit this file manually. Instead, re-run `npm run readme`. --\u003e\n\n[![HSTS preload](https://img.shields.io/hsts/preload/giacomodebidda.com)](https://hstspreload.org/?domain=giacomodebidda.com)\n[![HSTS preload](https://github.com/jackdbd/personal-website/actions/workflows/ci.yaml/badge.svg)](https://github.com/jackdbd/personal-website/actions/workflows/ci.yaml)\n[![HSTS preload](https://github.com/jackdbd/personal-website/actions/workflows/cloudflare-pages-deploy-hook.yaml/badge.svg)](https://github.com/jackdbd/personal-website/actions/workflows/cloudflare-pages-deploy-hook.yaml)\n\nMy personal website and blog, built with [11ty](https://www.11ty.dev/) and [Workbox](https://github.com/googlechrome/workbox). Hosted on [Cloudflare Pages](https://pages.cloudflare.com/).\n\n- [Features](#features)\n- [Installation](#installation)\n- [Development](#development)\n  - [Test the production build locally](#test-the-production-build-locally)\n- [Deploy](#deploy)\n- [Security](#security)\n  - [Run a security audit on the HTTP headers](#run-a-security-audit-on-the-http-headers)\n  - [Security policy](#security-policy)\n- [Dependencies](#dependencies)\n  - [Production dependencies](#production-dependencies)\n  - [Development dependencies](#development-dependencies)\n- [Troubleshooting](#troubleshooting)\n  - [Troubleshooting the service worker](#troubleshooting-the-service-worker)\n- [License](#license)\n\n## Features\n\n\u003c!-- - PWA with  [web application manifest](https://developer.mozilla.org/en-US/docs/Web/Manifest)\n- RSS feed with [`@11ty/eleventy-plugin-rss`](https://www.11ty.dev/docs/plugins/rss/) --\u003e\n\n- PWA with [web application manifest](https://developer.mozilla.org/en-US/docs/Web/Manifest)\n- RSS feed with [@11ty/eleventy-plugin-rss](https://www.11ty.dev/docs/plugins/rss/)\n- [webmentions](https://indieweb.org/Webmention) sent to [Webmention.io](https://webmention.io/) and collected by [Bridgy](https://brid.gy)\n- [WebC](https://www.11ty.dev/docs/languages/webc/) component to send webmentions using a Progressive Enhancement friendly HTML form\n- `sitemap.xml` and `robots.txt` for SEO\n- `security.txt` in `.well-known` directory\n- just-in-time preloading with [instant.page](https://instant.page/)\n- Service worker generated with [workbox-core](https://developer.chrome.com/docs/workbox/modules/workbox-core/) and [esbuild](https://github.com/evanw/esbuild)\n- Modular type scale and fluid space system thanks to [Utopia](https://utopia.fyi/)\n- Performance reports with multiple [performance budgets](https://www.afasterweb.com/2020/01/28/performance-budgets-with-lighthouse/) using the [Lighthouse CLI](https://github.com/GoogleChrome/lighthouse#using-the-node-cli) and [webhint](https://github.com/webhintio/hint)\n- HTML minified using [html-minifier-terser](https://github.com/terser/html-minifier-terser) (only when building for production)\n- CSS on the critical path minified with [clean-css](https://www.11ty.dev/docs/quicktips/inline-css/) and inlined in the `\u003chead\u003e`. All other CSS is managed by [PostCSS](https://github.com/postcss/postcss).\n- Embeds for YouTube and Video thanks to [eleventy-plugin-youtube-embed](https://github.com/gfscott/eleventy-plugin-embed-everything/tree/main/packages/youtube) and [eleventy-plugin-vimeo-embed](https://github.com/gfscott/eleventy-plugin-embed-everything/tree/main/packages/vimeo)\n- Framework agnostic partial hydration with [@11ty/is-land](https://github.com/11ty/is-land)\n- [Custom HTTP headers](https://developers.cloudflare.com/pages/how-to/add-custom-http-headers/) for the [Reporting API](https://developer.mozilla.org/en-US/docs/Web/API/Reporting_API):\n  - [Report-To](https://developers.google.com/web/updates/2018/09/reportingapi#header) and [Reporting-Endpoints](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Reporting-Endpoints)\n  - [Content-Security-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP)\n  - [Network Error Logging](https://developer.cdn.mozilla.net/en-US/docs/Web/HTTP/Headers/NEL)\n  - [Permissions-Policy](https://scotthelme.co.uk/goodbye-feature-policy-and-hello-permissions-policy/)\n- Configurable text to speech synthesis, thanks to [@jackdbd/eleventy-plugin-text-to-speech](https://github.com/jackdbd/undici/tree/main/packages/eleventy-plugin-text-to-speech)\n- [Scripts](./scripts/README.md) I use for various administrative tasks\n\n## Installation\n\nClone the repo:\n\n```shell\ngit clone git@github.com:jackdbd/personal-website.git\n```\n\nThis project should work on Node.js \u003e=20.0.0.\n\n\u003e :information_source: **What's that `devenv.nix`?**\n\u003e\n\u003e This project uses [devenv](https://devenv.sh/) to create and manage a developer environment that has all the necessary dependencies. Thanks to [devenv's automatic shell activation](https://devenv.sh/automatic-shell-activation/), this environment is activated automatically when you enter the root directory of this repository (you will just have to wait a few seconds).\n\u003e\n\u003e If you don't use Nix, you can safely ignore the `devenv.nix` file in the repository root.\n\u003e\n\u003e In alternative to the Nix dev shell provided by this repository, you could use a Node.js version manager like [nvm](https://github.com/nvm-sh/nvm), [asdf](https://github.com/asdf-vm/asdf), or [volta](https://github.com/volta-cli/volta).\n\nIf you want to run scrips/tests that rely on [Playwright](https://playwright.dev/), you will also need to install/update the browsers it uses:\n\n```sh\nnpx playwright install\n```\n\n## Development\n\nWatch all templates, CSS, JS, and automatically refresh the browser:\n\n```sh\nnpm run dev\n```\n\nGo to http://localhost:8080/ to visit the website.\n\nIn alternative, develop and preview the site with [wrangler](https://developers.cloudflare.com/pages/platform/functions/#develop-and-preview-locally) (this is useful when developing functions that will be deployed to [Cloudflare Pages Functions](https://developers.cloudflare.com/pages/platform/functions/)):\n\n```sh\nnpm run wrangler\n```\n\nGo to http://localhost:8788/ to visit the website.\n\n### Test the production build locally\n\nBuild all templates, CSS, JS, `_headers` file and the service worker:\n\n```sh\nnpm run build\n```\n\nServe the production build:\n\n```sh\nnpm run site:serve\n```\n\n## Deploy\n\nJust push to the remote repository. [This GitHub workflow](./.github/workflows/ci.yaml) will automatically deploy the website to Cloudflare Pages.\n\n- Each push on the `main` branch will trigger a production deployment.\n- Each push on any other branch will trigger a [preview deployment](https://developers.cloudflare.com/pages/platform/preview-deployments/).\n\n\u003e :warning: **Node.js version on Cloudflare Pages**\n\u003e\n\u003e Don't forget to set the environment variables `NODE_ENV` and `NODE_VERSION` in the [Cloudflare Pages dashboard](https://developers.cloudflare.com/pages/functions/bindings/#environment-variables). In particular, `NODE_VERSION` is used by the [Cloudflare Pages V2 build system](https://developers.cloudflare.com/pages/configuration/language-support-and-tools/#v2-build-system).\n\n## Security\n\n### Run a security audit on the HTTP headers\n\nGenerate the `_headers` file which will be used by Cloudflare Pages:\n\n```sh\nnode scripts/headers.mjs\n```\n\nCheck the `Content-Security-Policy` and the other security headers with these online tools:\n\n- https://observatory.mozilla.org/\n- https://securityheaders.com/\n- https://csp-evaluator.withgoogle.com/\n\n### Security policy\n\nSee [SECURITY.md](./SECURITY.md).\n\n## Dependencies\n\n### Production dependencies\n\nThis project has **53** `dependencies`.\n\n| Package | Version |\n|---|---|\n| [@11ty/eleventy](https://www.npmjs.com/package/@11ty/eleventy) | `^3.0.0` |\n| [@11ty/eleventy-fetch](https://www.npmjs.com/package/@11ty/eleventy-fetch) | `^4.0.1` |\n| [@11ty/eleventy-navigation](https://www.npmjs.com/package/@11ty/eleventy-navigation) | `^0.3.5` |\n| [@11ty/eleventy-plugin-rss](https://www.npmjs.com/package/@11ty/eleventy-plugin-rss) | `^2.0.2` |\n| [@11ty/eleventy-plugin-syntaxhighlight](https://www.npmjs.com/package/@11ty/eleventy-plugin-syntaxhighlight) | `^5.0.0` |\n| [@11ty/eleventy-plugin-webc](https://www.npmjs.com/package/@11ty/eleventy-plugin-webc) | `^0.11.2` |\n| [@11ty/is-land](https://www.npmjs.com/package/@11ty/is-land) | `^4.0.0` |\n| [@chrisburnell/eleventy-cache-webmentions](https://www.npmjs.com/package/@chrisburnell/eleventy-cache-webmentions) | `^2.1.8` |\n| [@google-cloud/storage](https://www.npmjs.com/package/@google-cloud/storage) | `^7.13.0` |\n| [@google-cloud/text-to-speech](https://www.npmjs.com/package/@google-cloud/text-to-speech) | `^5.5.0` |\n| [@jackdbd/content-security-policy](https://www.npmjs.com/package/@jackdbd/content-security-policy) | `^3.0.0` |\n| [@jackdbd/eleventy-plugin-ensure-env-vars](https://www.npmjs.com/package/@jackdbd/eleventy-plugin-ensure-env-vars) | `^1.2.0` |\n| [@jackdbd/eleventy-plugin-telegram](https://www.npmjs.com/package/@jackdbd/eleventy-plugin-telegram) | `^2.2.0` |\n| [@jackdbd/eleventy-plugin-text-to-speech](https://www.npmjs.com/package/@jackdbd/eleventy-plugin-text-to-speech) | `^3.2.0` |\n| [@jackdbd/hosting-utils](https://www.npmjs.com/package/@jackdbd/hosting-utils) | `^1.0.0` |\n| [@jackdbd/permissions-policy](https://www.npmjs.com/package/@jackdbd/permissions-policy) | `^1.0.0` |\n| [@thi.ng/transclude](https://www.npmjs.com/package/@thi.ng/transclude) | `^0.1.108` |\n| [autoprefixer](https://www.npmjs.com/package/autoprefixer) | `^10.4.20` |\n| [clean-css](https://www.npmjs.com/package/clean-css) | `^5.3.3` |\n| [cloudinary](https://www.npmjs.com/package/cloudinary) | `^2.5.1` |\n| [cssnano](https://www.npmjs.com/package/cssnano) | `^7.0.6` |\n| [debug](https://www.npmjs.com/package/debug) | `^4.3.7` |\n| [eleventy-plugin-embed-cloudinary](https://www.npmjs.com/package/eleventy-plugin-embed-cloudinary) | `^1.0.2` |\n| [eleventy-plugin-embed-twitter](https://www.npmjs.com/package/eleventy-plugin-embed-twitter) | `^1.4.1` |\n| [eleventy-plugin-emoji](https://www.npmjs.com/package/eleventy-plugin-emoji) | `^1.1.0` |\n| [eleventy-plugin-helmet](https://www.npmjs.com/package/eleventy-plugin-helmet) | `^0.2.2` |\n| [eleventy-plugin-nesting-toc](https://www.npmjs.com/package/eleventy-plugin-nesting-toc) | `^1.3.0` |\n| [eleventy-plugin-reading-time](https://www.npmjs.com/package/eleventy-plugin-reading-time) | `^0.0.1` |\n| [eleventy-plugin-vimeo-embed](https://www.npmjs.com/package/eleventy-plugin-vimeo-embed) | `^1.3.8` |\n| [eleventy-plugin-youtube-embed](https://www.npmjs.com/package/eleventy-plugin-youtube-embed) | `^1.11.0` |\n| [esbuild](https://www.npmjs.com/package/esbuild) | `^0.24.0` |\n| [globby](https://www.npmjs.com/package/globby) | `^14.0.2` |\n| [html-minifier-terser](https://www.npmjs.com/package/html-minifier-terser) | `^7.2.0` |\n| [instant.page](https://www.npmjs.com/package/instant.page) | `^5.2.0` |\n| [luxon](https://www.npmjs.com/package/luxon) | `^3.5.0` |\n| [markdown-it](https://www.npmjs.com/package/markdown-it) | `^14.1.0` |\n| [markdown-it-anchor](https://www.npmjs.com/package/markdown-it-anchor) | `^9.2.0` |\n| [npm-run-all](https://www.npmjs.com/package/npm-run-all) | `^4.1.5` |\n| [pagefind](https://www.npmjs.com/package/pagefind) | `^1.1.1` |\n| [postcss](https://www.npmjs.com/package/postcss) | `^8.4.47` |\n| [postcss-cli](https://www.npmjs.com/package/postcss-cli) | `^11.0.0` |\n| [sanitize-html](https://www.npmjs.com/package/sanitize-html) | `^2.13.1` |\n| [slugify](https://www.npmjs.com/package/slugify) | `^1.6.6` |\n| [stripe](https://www.npmjs.com/package/stripe) | `^17.2.1` |\n| [tailwindcss](https://www.npmjs.com/package/tailwindcss) | `^3.4.14` |\n| [terser](https://www.npmjs.com/package/terser) | `^5.36.0` |\n| [tsm](https://www.npmjs.com/package/tsm) | `^2.3.0` |\n| [workbox-build](https://www.npmjs.com/package/workbox-build) | `^7.1.1` |\n| [workbox-core](https://www.npmjs.com/package/workbox-core) | `^7.1.0` |\n| [workbox-expiration](https://www.npmjs.com/package/workbox-expiration) | `^7.1.0` |\n| [workbox-precaching](https://www.npmjs.com/package/workbox-precaching) | `^7.1.0` |\n| [workbox-routing](https://www.npmjs.com/package/workbox-routing) | `^7.1.0` |\n| [zod](https://www.npmjs.com/package/zod) | `^3.23.8` |\n\n### Development dependencies\n\nThis project has **19** `devDependencies`: [@hint/hint-performance-budget](https://www.npmjs.com/package/@hint/hint-performance-budget), [@jackdbd/checks](https://www.npmjs.com/package/@jackdbd/checks), [@types/yargs](https://www.npmjs.com/package/@types/yargs), [form-data](https://www.npmjs.com/package/form-data), [himalaya](https://www.npmjs.com/package/himalaya), [hint](https://www.npmjs.com/package/hint), [lighthouse](https://www.npmjs.com/package/lighthouse), [linkedin-api-client](https://www.npmjs.com/package/linkedin-api-client), [openpgp](https://www.npmjs.com/package/openpgp), [playwright-chromium](https://www.npmjs.com/package/playwright-chromium), [playwright-start](https://www.npmjs.com/package/playwright-start), [prettier-plugin-tailwindcss](https://www.npmjs.com/package/prettier-plugin-tailwindcss), [pretty-error](https://www.npmjs.com/package/pretty-error), [serve](https://www.npmjs.com/package/serve), [snoowrap](https://www.npmjs.com/package/snoowrap), [taze](https://www.npmjs.com/package/taze), [typescript](https://www.npmjs.com/package/typescript), [uuid](https://www.npmjs.com/package/uuid), [yargs](https://www.npmjs.com/package/yargs).\n\n## Troubleshooting\n\n### Troubleshooting the service worker\n\nWhen developing, open Chrome DevTools, go to `Application \u003e Service Workers` and check that:\n\n- `Update on reload` is **enabled**. This ensures that the latest service worker will be **installed** and **activated** on the page.\n- `Bypass for network` is **disabled**. This ensures that the route matchers, route handlers and runtime caches of the service worker will be used.\n\n## License\n\n\u0026copy; 2020 - 2024 [Giacomo Debidda](https://www.giacomodebidda.com/) // [MIT License](https://spdx.org/licenses/MIT.html)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjackdbd%2Fpersonal-website","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjackdbd%2Fpersonal-website","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjackdbd%2Fpersonal-website/lists"}