diff --git a/.gitignore b/.gitignore index b4b4347..1c9d475 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ _site # nix packages .direnv +result # Environment variables .env diff --git a/_data/site.js b/_data/site.js new file mode 100644 index 0000000..e214bbe --- /dev/null +++ b/_data/site.js @@ -0,0 +1,7 @@ +module.exports = { + // Set SITE_URL environment variable to build for different domains: + // SITE_URL=https://blog.jan-leila.com pnpm run build + // SITE_URL=https://volpe.jan-leila.com pnpm run build + // SITE_URL=http://your-onion-address.onion pnpm run build + url: process.env.SITE_URL || "http://localhost:8080" +}; \ No newline at end of file diff --git a/_includes/base.njk b/_includes/base.njk index a1186f7..394a3fa 100644 --- a/_includes/base.njk +++ b/_includes/base.njk @@ -3,9 +3,47 @@ - {{ title }} | Volpe - - + Volpe{% if title %} | {{ title }}{% endif %} + {% if description %} + + {% endif %} + + {# Critical CSS inlined for faster initial render #} + + + {# Preload full stylesheet with cache-busted filename #} + + + + {# Defer prism.css - only needed for syntax highlighting #} + + +
@@ -19,7 +57,12 @@ \ No newline at end of file diff --git a/eleventy.config.js b/eleventy.config.js index 1551fcb..0726aed 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -4,8 +4,26 @@ const markdownItFootnote = require("markdown-it-footnote"); const markdownItMermaid = require('markdown-it-mermaid').default const syntaxHighlight = require("@11ty/eleventy-plugin-syntaxhighlight"); const fs = require("fs"); +const crypto = require("crypto"); +const path = require("path"); const { DateTime } = require("luxon"); +const cssHashCache = {}; +const getCssHash = (cssFile) => { + if (cssHashCache[cssFile]) return cssHashCache[cssFile]; + + const cssPath = path.join(__dirname, "css", cssFile); + try { + const content = fs.readFileSync(cssPath, "utf-8"); + const hash = crypto.createHash("md5").update(content).digest("hex").slice(0, 8); + cssHashCache[cssFile] = hash; + return hash; + } catch (e) { + console.warn(`Could not hash CSS file: ${cssFile}`); + return null; + } +}; + const extractTags = (content, mdInstance) => { if (!content) return []; @@ -36,7 +54,7 @@ const getPostTags = (post, mdInstance) => { } const isReleased = (post) => { - return post.data.unreleased !== true; + return post.data.released !== false; } const markdownItHashtag = (md) => { @@ -220,7 +238,39 @@ module.exports = (eleventyConfig) => { return tagMap; }); - eleventyConfig.addPassthroughCopy("css"); + // Cache busting filter: returns hashed CSS filename + eleventyConfig.addFilter("cssHash", (cssFile) => { + const hash = getCssHash(cssFile); + const ext = path.extname(cssFile); + const base = path.basename(cssFile, ext); + return `/css/${base}.${hash}${ext}`; + }); + + eleventyConfig.on("eleventy.before", async () => { + const cssDir = path.join(__dirname, "css"); + const outputCssDir = path.join(__dirname, "_site", "css"); + + if (!fs.existsSync(outputCssDir)) { + fs.mkdirSync(outputCssDir, { recursive: true }); + } + + const cssFiles = fs.readdirSync(cssDir).filter(f => f.endsWith(".css")); + for (const cssFile of cssFiles) { + const hash = getCssHash(cssFile); + const ext = path.extname(cssFile); + const base = path.basename(cssFile, ext); + const hashedName = `${base}${hash == null ? '' : `.${hash}`}${ext}`; + + fs.copyFileSync( + path.join(cssDir, cssFile), + path.join(outputCssDir, hashedName) + ); + } + }); + + eleventyConfig.addPassthroughCopy("robots.txt"); + + eleventyConfig.ignores.add("README.md"); return { dir: { diff --git a/flake.nix b/flake.nix index 91bbb0e..00aa531 100644 --- a/flake.nix +++ b/flake.nix @@ -1,5 +1,5 @@ { - description = "A Nix-flake-based Node.js development environment"; + description = "Volpe Blog"; inputs.nixpkgs.url = "https://flakehub.com/f/NixOS/nixpkgs/0.1.*.tar.gz"; @@ -19,9 +19,46 @@ pkgs = import nixpkgs {inherit overlays system;}; }); in { + packages = forEachSupportedSystem ({pkgs}: { + default = pkgs.callPackage ./nix/package.nix { + siteUrl = "https://blog.jan-leila.com"; + }; + blog = pkgs.callPackage ./nix/package.nix { + siteUrl = "https://blog.jan-leila.com"; + }; + volpe = pkgs.callPackage ./nix/package.nix { + siteUrl = "https://volpe.jan-leila.com"; + }; + }); + devShells = forEachSupportedSystem ({pkgs}: { default = pkgs.mkShell { - packages = with pkgs; [node2nix nodejs pnpm sqlite]; + packages = with pkgs; [ + nodejs + nodePackages.pnpm + ]; + }; + }); + + nixosConfigurations.volpe = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + {nixpkgs.overlays = overlays;} + ./nix/configuration.nix + ]; + }; + + # Deployment helper - use with: nix run .#deploy + apps = forEachSupportedSystem ({pkgs}: { + deploy = { + type = "app"; + program = toString (pkgs.writeShellScript "deploy-volpe" '' + set -e + echo "Building and deploying to cyberian@69.61.19.180..." + nixos-rebuild switch --flake .#volpe \ + --target-host cyberian@69.61.19.180 \ + --sudo + ''); }; }); }; diff --git a/index.njk b/index.njk index ff56fb5..bc952c7 100644 --- a/index.njk +++ b/index.njk @@ -1,8 +1,13 @@ --- layout: base.njk title: Blog +description: Welcome to my website! I write about tech, politics, food, and hobby projects. Stay a while, make some friends, learn something, and help your neighbors. --- +
+

{{ description }}

+
+

Blog Posts