[READ-ONLY] Mirror of https://github.com/flo-bit/blog-template. minimalistic astro blog template flo-bit.dev/blog-template/
astro blog template
0

Configure Feed

Select the types of activity you want to include in your feed.

add embeds

+702 -73
+3 -17
README.md
··· 20 20 - ✅ Tags for posts 21 21 - ✅ Super easy to deploy as a static site 22 22 - ✅ Includes some prebuilt components for you to use 23 - - ✅ Easy to edit using [pagecms](https://pagescms.org) or by editing the markdown directly 23 + - ✅ Easy to edit by editing the markdown directly 24 24 25 25 ## tutorials 26 26 ··· 38 38 39 39 2. In your repository settings, set up github pages to deploy using github actions (*SETTINGS* -> *PAGES* -> *SOURCE*: **Github Actions**) 40 40 41 - 3. Your blog should be live in about 1 minute at `https://<your-github-username>.github.io/<your-repo-name>` 42 - 43 - For editing the blog you can either edit the code directly or use the preconfigured [pagescms](https://next.pagescms.org). 44 - 45 - ### Editing with pagescms 46 - 47 - 4. Go to [pagescms](https://next.pagescms.org) and log in with your github account and authorize the app. 48 - 49 - 5. Add your repository to pagescms and open it. 50 - 51 - 6. Now you can edit your website configuration, about page, description and blog posts directly in the browser. 52 - 53 - 7. Your changes will be automatically pushed to your repository and deployed to github pages in about 1 minute everytime you hit save. 41 + 3. Set up your blog info in `src/config.json` (most importantly change `SITE` to your deployment url, e.g. for github pages `https://<your-github-username>.github.io/` and `BASE` to your base path, e.g. for github pages `/<your-repo-name>`) 54 42 55 - ### Editing the code 56 - 57 - 4. Set up your blog info in `src/config.json` (leaving SITE, BASE, and MANUAL_SITE_BASE, as they are). 43 + 4. Your blog should be live in about 1 minute at `https://<your-github-username>.github.io/<your-repo-name>` 58 44 59 45 5. Add your blog posts in `src/content/blog/` 60 46
+17 -1
astro.config.mjs
··· 10 10 11 11 import { BASE, SITE } from "./src/config.json"; 12 12 13 + import customEmbeds from 'astro-custom-embeds'; 14 + 15 + import { transformerMetaHighlight, transformerNotationHighlight } from '@shikijs/transformers' 16 + 17 + import LinkCardEmbed from './src/embeds/link-card/embed' 18 + import YoutubeEmbed from './src/embeds/youtube/embed' 19 + 13 20 // https://astro.build/config 14 21 export default defineConfig({ 15 22 vite: { ··· 33 40 }, 34 41 }, 35 42 36 - integrations: [mdx(), sitemap(), tailwind(), svelte()], 43 + integrations: [customEmbeds({ 44 + embeds: [ 45 + YoutubeEmbed, 46 + LinkCardEmbed, 47 + 48 + ] 49 + }), mdx(), sitemap(), tailwind(), svelte()], 37 50 38 51 markdown: { 39 52 shikiConfig: { ··· 45 58 light: "github-light", 46 59 dark: "github-dark", 47 60 }, 61 + defaultColor: false, 62 + transformers: [transformerMetaHighlight(), transformerNotationHighlight()], 63 + wrap: true 48 64 }, 49 65 }, 50 66
+316 -33
package-lock.json
··· 10 10 "license": "MIT", 11 11 "dependencies": { 12 12 "@ascorbic/bluesky-loader": "^0.0.3", 13 + "@astro-community/astro-embed-utils": "^0.1.3", 13 14 "@astrojs/check": "^0.9.4", 14 15 "@astrojs/mdx": "^3.1.9", 15 16 "@astrojs/rss": "^4.0.9", 16 17 "@astrojs/sitemap": "^3.2.1", 17 18 "@astrojs/svelte": "^6.0.2", 18 19 "@astrojs/tailwind": "^5.1.2", 20 + "@shikijs/transformers": "^1.24.2", 19 21 "@tailwindcss/forms": "^0.5.9", 20 22 "astro": "^4.16.14", 23 + "astro-custom-embeds": "^0.0.1", 21 24 "astro-og-canvas": "^0.5.4", 25 + "lite-youtube-embed": "^0.3.3", 22 26 "svelte": "^5.1.1", 23 27 "tailwind-merge": "^2.5.4", 24 28 "tailwindcss": "^3.4.14", ··· 72 76 "integrity": "sha512-pg43g83gojVtEsAkXfjWuzJhuXneJp4wM/leBftGkCPV3yxKgB92EWA+nWu735BgbBMph3P7DrVqVc3ikt+dJA==", 73 77 "peerDependencies": { 74 78 "astro": "^4.14.0 || ^5.0.0-beta.0" 79 + } 80 + }, 81 + "node_modules/@astro-community/astro-embed-utils": { 82 + "version": "0.1.3", 83 + "resolved": "https://registry.npmjs.org/@astro-community/astro-embed-utils/-/astro-embed-utils-0.1.3.tgz", 84 + "integrity": "sha512-eiMO+vfCdE9GtW6qE7X5Xl6YCKZDCoXJEWqRofQcoC3GHjqN2/WhJlnaxNVRq3demSO03UNtho57Em5p7o7AOA==", 85 + "dependencies": { 86 + "linkedom": "^0.14.26" 75 87 } 76 88 }, 77 89 "node_modules/@astrojs/check": { ··· 1815 1827 ] 1816 1828 }, 1817 1829 "node_modules/@shikijs/core": { 1818 - "version": "1.23.1", 1819 - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.23.1.tgz", 1820 - "integrity": "sha512-NuOVgwcHgVC6jBVH5V7iblziw6iQbWWHrj5IlZI3Fqu2yx9awH7OIQkXIcsHsUmY19ckwSgUMgrqExEyP5A0TA==", 1830 + "version": "1.24.2", 1831 + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.24.2.tgz", 1832 + "integrity": "sha512-BpbNUSKIwbKrRRA+BQj0BEWSw+8kOPKDJevWeSE/xIqGX7K0xrCZQ9kK0nnEQyrzsUoka1l81ZtJ2mGaCA32HQ==", 1821 1833 "dependencies": { 1822 - "@shikijs/engine-javascript": "1.23.1", 1823 - "@shikijs/engine-oniguruma": "1.23.1", 1824 - "@shikijs/types": "1.23.1", 1834 + "@shikijs/engine-javascript": "1.24.2", 1835 + "@shikijs/engine-oniguruma": "1.24.2", 1836 + "@shikijs/types": "1.24.2", 1825 1837 "@shikijs/vscode-textmate": "^9.3.0", 1826 1838 "@types/hast": "^3.0.4", 1827 1839 "hast-util-to-html": "^9.0.3" 1828 1840 } 1829 1841 }, 1830 1842 "node_modules/@shikijs/engine-javascript": { 1831 - "version": "1.23.1", 1832 - "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-1.23.1.tgz", 1833 - "integrity": "sha512-i/LdEwT5k3FVu07SiApRFwRcSJs5QM9+tod5vYCPig1Ywi8GR30zcujbxGQFJHwYD7A5BUqagi8o5KS+LEVgBg==", 1843 + "version": "1.24.2", 1844 + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-1.24.2.tgz", 1845 + "integrity": "sha512-EqsmYBJdLEwEiO4H+oExz34a5GhhnVp+jH9Q/XjPjmBPc6TE/x4/gD0X3i0EbkKKNqXYHHJTJUpOLRQNkEzS9Q==", 1834 1846 "dependencies": { 1835 - "@shikijs/types": "1.23.1", 1847 + "@shikijs/types": "1.24.2", 1836 1848 "@shikijs/vscode-textmate": "^9.3.0", 1837 - "oniguruma-to-es": "0.4.1" 1849 + "oniguruma-to-es": "0.7.0" 1838 1850 } 1839 1851 }, 1840 1852 "node_modules/@shikijs/engine-oniguruma": { 1841 - "version": "1.23.1", 1842 - "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.23.1.tgz", 1843 - "integrity": "sha512-KQ+lgeJJ5m2ISbUZudLR1qHeH3MnSs2mjFg7bnencgs5jDVPeJ2NVDJ3N5ZHbcTsOIh0qIueyAJnwg7lg7kwXQ==", 1853 + "version": "1.24.2", 1854 + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.24.2.tgz", 1855 + "integrity": "sha512-ZN6k//aDNWRJs1uKB12pturKHh7GejKugowOFGAuG7TxDRLod1Bd5JhpOikOiFqPmKjKEPtEA6mRCf7q3ulDyQ==", 1844 1856 "dependencies": { 1845 - "@shikijs/types": "1.23.1", 1857 + "@shikijs/types": "1.24.2", 1846 1858 "@shikijs/vscode-textmate": "^9.3.0" 1847 1859 } 1848 1860 }, 1861 + "node_modules/@shikijs/transformers": { 1862 + "version": "1.24.2", 1863 + "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-1.24.2.tgz", 1864 + "integrity": "sha512-cIwn8YSwO3bsWKJ+pezcXY1Vq0BVwvuLes1TZSC5+Awi6Tsfqhf3vBahOIqZK1rraMKOti2VEAEF/95oXMig1w==", 1865 + "dependencies": { 1866 + "shiki": "1.24.2" 1867 + } 1868 + }, 1849 1869 "node_modules/@shikijs/types": { 1850 - "version": "1.23.1", 1851 - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.23.1.tgz", 1852 - "integrity": "sha512-98A5hGyEhzzAgQh2dAeHKrWW4HfCMeoFER2z16p5eJ+vmPeF6lZ/elEne6/UCU551F/WqkopqRsr1l2Yu6+A0g==", 1870 + "version": "1.24.2", 1871 + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.24.2.tgz", 1872 + "integrity": "sha512-bdeWZiDtajGLG9BudI0AHet0b6e7FbR0EsE4jpGaI0YwHm/XJunI9+3uZnzFtX65gsyJ6ngCIWUfA4NWRPnBkQ==", 1853 1873 "dependencies": { 1854 1874 "@shikijs/vscode-textmate": "^9.3.0", 1855 1875 "@types/hast": "^3.0.4" ··· 2399 2419 "sharp": "^0.33.3" 2400 2420 } 2401 2421 }, 2422 + "node_modules/astro-auto-import": { 2423 + "version": "0.4.4", 2424 + "resolved": "https://registry.npmjs.org/astro-auto-import/-/astro-auto-import-0.4.4.tgz", 2425 + "integrity": "sha512-tiYe1hp+VusdiyaD3INgZgbvXEPamDFiURnQR5Niz+E9fWa6IHYjJ99TwGlHh/evfaXE/U/86jp9MRKWTuJU1A==", 2426 + "dependencies": { 2427 + "@types/node": "^18.0.0", 2428 + "acorn": "^8.8.0" 2429 + }, 2430 + "engines": { 2431 + "node": ">=16.0.0" 2432 + }, 2433 + "peerDependencies": { 2434 + "astro": "^2.0.0 || ^3.0.0-beta || ^4.0.0-beta || ^5.0.0-beta" 2435 + } 2436 + }, 2437 + "node_modules/astro-auto-import/node_modules/@types/node": { 2438 + "version": "18.19.67", 2439 + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.67.tgz", 2440 + "integrity": "sha512-wI8uHusga+0ZugNp0Ol/3BqQfEcCCNfojtO6Oou9iVNGPTL6QNSdnUdqq85fRgIorLhLMuPIKpsN98QE9Nh+KQ==", 2441 + "dependencies": { 2442 + "undici-types": "~5.26.4" 2443 + } 2444 + }, 2445 + "node_modules/astro-auto-import/node_modules/undici-types": { 2446 + "version": "5.26.5", 2447 + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 2448 + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" 2449 + }, 2450 + "node_modules/astro-custom-embeds": { 2451 + "version": "0.0.1", 2452 + "resolved": "https://registry.npmjs.org/astro-custom-embeds/-/astro-custom-embeds-0.0.1.tgz", 2453 + "integrity": "sha512-8f5lYAImE38VC1ZAAQ8S2BCEa6vSBIeph+aPEW+uX10FIfvgAJ7Na+Q2cmMGoMG+p0dQ+1mEDtzvzlIAO04MSg==", 2454 + "dependencies": { 2455 + "@types/unist": "^2.0.0", 2456 + "astro-auto-import": "^0.4.2", 2457 + "remark-directive": "^3.0.0", 2458 + "unist-util-select": "^4.0.1", 2459 + "unist-util-visit": "^5.0.0" 2460 + }, 2461 + "peerDependencies": { 2462 + "astro": "^4.0.0 || ^5.0.0-beta" 2463 + } 2464 + }, 2465 + "node_modules/astro-custom-embeds/node_modules/@types/unist": { 2466 + "version": "2.0.11", 2467 + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", 2468 + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" 2469 + }, 2402 2470 "node_modules/astro-og-canvas": { 2403 2471 "version": "0.5.4", 2404 2472 "resolved": "https://registry.npmjs.org/astro-og-canvas/-/astro-og-canvas-0.5.4.tgz", ··· 2493 2561 "funding": { 2494 2562 "url": "https://github.com/sponsors/sindresorhus" 2495 2563 } 2564 + }, 2565 + "node_modules/boolbase": { 2566 + "version": "1.0.0", 2567 + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", 2568 + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" 2496 2569 }, 2497 2570 "node_modules/boxen": { 2498 2571 "version": "8.0.1", ··· 2945 3018 "node": ">= 8" 2946 3019 } 2947 3020 }, 3021 + "node_modules/css-select": { 3022 + "version": "5.1.0", 3023 + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", 3024 + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", 3025 + "dependencies": { 3026 + "boolbase": "^1.0.0", 3027 + "css-what": "^6.1.0", 3028 + "domhandler": "^5.0.2", 3029 + "domutils": "^3.0.1", 3030 + "nth-check": "^2.0.1" 3031 + }, 3032 + "funding": { 3033 + "url": "https://github.com/sponsors/fb55" 3034 + } 3035 + }, 3036 + "node_modules/css-selector-parser": { 3037 + "version": "1.4.1", 3038 + "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-1.4.1.tgz", 3039 + "integrity": "sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g==" 3040 + }, 3041 + "node_modules/css-what": { 3042 + "version": "6.1.0", 3043 + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", 3044 + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", 3045 + "engines": { 3046 + "node": ">= 6" 3047 + }, 3048 + "funding": { 3049 + "url": "https://github.com/sponsors/fb55" 3050 + } 3051 + }, 2948 3052 "node_modules/cssesc": { 2949 3053 "version": "3.0.0", 2950 3054 "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", ··· 2955 3059 "engines": { 2956 3060 "node": ">=4" 2957 3061 } 3062 + }, 3063 + "node_modules/cssom": { 3064 + "version": "0.5.0", 3065 + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", 3066 + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==" 2958 3067 }, 2959 3068 "node_modules/debug": { 2960 3069 "version": "4.3.7", ··· 3060 3169 "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", 3061 3170 "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" 3062 3171 }, 3172 + "node_modules/dom-serializer": { 3173 + "version": "2.0.0", 3174 + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", 3175 + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", 3176 + "dependencies": { 3177 + "domelementtype": "^2.3.0", 3178 + "domhandler": "^5.0.2", 3179 + "entities": "^4.2.0" 3180 + }, 3181 + "funding": { 3182 + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" 3183 + } 3184 + }, 3185 + "node_modules/domelementtype": { 3186 + "version": "2.3.0", 3187 + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", 3188 + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", 3189 + "funding": [ 3190 + { 3191 + "type": "github", 3192 + "url": "https://github.com/sponsors/fb55" 3193 + } 3194 + ] 3195 + }, 3196 + "node_modules/domhandler": { 3197 + "version": "5.0.3", 3198 + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", 3199 + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", 3200 + "dependencies": { 3201 + "domelementtype": "^2.3.0" 3202 + }, 3203 + "engines": { 3204 + "node": ">= 4" 3205 + }, 3206 + "funding": { 3207 + "url": "https://github.com/fb55/domhandler?sponsor=1" 3208 + } 3209 + }, 3210 + "node_modules/domutils": { 3211 + "version": "3.1.0", 3212 + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", 3213 + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", 3214 + "dependencies": { 3215 + "dom-serializer": "^2.0.0", 3216 + "domelementtype": "^2.3.0", 3217 + "domhandler": "^5.0.3" 3218 + }, 3219 + "funding": { 3220 + "url": "https://github.com/fb55/domutils?sponsor=1" 3221 + } 3222 + }, 3063 3223 "node_modules/dset": { 3064 3224 "version": "3.1.4", 3065 3225 "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.4.tgz", ··· 3844 4004 "url": "https://github.com/sponsors/wooorm" 3845 4005 } 3846 4006 }, 4007 + "node_modules/htmlparser2": { 4008 + "version": "8.0.2", 4009 + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", 4010 + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", 4011 + "funding": [ 4012 + "https://github.com/fb55/htmlparser2?sponsor=1", 4013 + { 4014 + "type": "github", 4015 + "url": "https://github.com/sponsors/fb55" 4016 + } 4017 + ], 4018 + "dependencies": { 4019 + "domelementtype": "^2.3.0", 4020 + "domhandler": "^5.0.3", 4021 + "domutils": "^3.0.1", 4022 + "entities": "^4.4.0" 4023 + } 4024 + }, 3847 4025 "node_modules/http-cache-semantics": { 3848 4026 "version": "4.1.1", 3849 4027 "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", ··· 4175 4353 "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", 4176 4354 "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" 4177 4355 }, 4356 + "node_modules/linkedom": { 4357 + "version": "0.14.26", 4358 + "resolved": "https://registry.npmjs.org/linkedom/-/linkedom-0.14.26.tgz", 4359 + "integrity": "sha512-mK6TrydfFA7phrnp+1j57ycBwFI5bGSW6YXlw9acHoqF+mP/y+FooEYYyniOt5Ot57FSKB3iwmnuQ1UUyNLm5A==", 4360 + "dependencies": { 4361 + "css-select": "^5.1.0", 4362 + "cssom": "^0.5.0", 4363 + "html-escaper": "^3.0.3", 4364 + "htmlparser2": "^8.0.1", 4365 + "uhyphen": "^0.2.0" 4366 + } 4367 + }, 4368 + "node_modules/lite-youtube-embed": { 4369 + "version": "0.3.3", 4370 + "resolved": "https://registry.npmjs.org/lite-youtube-embed/-/lite-youtube-embed-0.3.3.tgz", 4371 + "integrity": "sha512-gFfVVnj6NRjxVfJKo3qoLtpi0v5mn3AcR4eKD45wrxQuxzveFJUb+7Cr6uV6n+DjO8X3p0UzPPquhGt0H/y+NA==" 4372 + }, 4178 4373 "node_modules/load-yaml-file": { 4179 4374 "version": "0.2.0", 4180 4375 "resolved": "https://registry.npmjs.org/load-yaml-file/-/load-yaml-file-0.2.0.tgz", ··· 4345 4540 "@types/mdast": "^4.0.0", 4346 4541 "@types/unist": "^3.0.0", 4347 4542 "unist-util-visit": "^5.0.0" 4543 + }, 4544 + "funding": { 4545 + "type": "opencollective", 4546 + "url": "https://opencollective.com/unified" 4547 + } 4548 + }, 4549 + "node_modules/mdast-util-directive": { 4550 + "version": "3.0.0", 4551 + "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.0.0.tgz", 4552 + "integrity": "sha512-JUpYOqKI4mM3sZcNxmF/ox04XYFFkNwr0CFlrQIkCwbvH0xzMCqkMqAde9wRd80VAhaUrwFwKm2nxretdT1h7Q==", 4553 + "dependencies": { 4554 + "@types/mdast": "^4.0.0", 4555 + "@types/unist": "^3.0.0", 4556 + "devlop": "^1.0.0", 4557 + "mdast-util-from-markdown": "^2.0.0", 4558 + "mdast-util-to-markdown": "^2.0.0", 4559 + "parse-entities": "^4.0.0", 4560 + "stringify-entities": "^4.0.0", 4561 + "unist-util-visit-parents": "^6.0.0" 4348 4562 }, 4349 4563 "funding": { 4350 4564 "type": "opencollective", ··· 4707 4921 "micromark-util-types": "^2.0.0" 4708 4922 } 4709 4923 }, 4924 + "node_modules/micromark-extension-directive": { 4925 + "version": "3.0.2", 4926 + "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.2.tgz", 4927 + "integrity": "sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==", 4928 + "dependencies": { 4929 + "devlop": "^1.0.0", 4930 + "micromark-factory-space": "^2.0.0", 4931 + "micromark-factory-whitespace": "^2.0.0", 4932 + "micromark-util-character": "^2.0.0", 4933 + "micromark-util-symbol": "^2.0.0", 4934 + "micromark-util-types": "^2.0.0", 4935 + "parse-entities": "^4.0.0" 4936 + }, 4937 + "funding": { 4938 + "type": "opencollective", 4939 + "url": "https://opencollective.com/unified" 4940 + } 4941 + }, 4710 4942 "node_modules/micromark-extension-gfm": { 4711 4943 "version": "3.0.0", 4712 4944 "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", ··· 5488 5720 "node": ">=0.10.0" 5489 5721 } 5490 5722 }, 5723 + "node_modules/nth-check": { 5724 + "version": "2.1.1", 5725 + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", 5726 + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", 5727 + "dependencies": { 5728 + "boolbase": "^1.0.0" 5729 + }, 5730 + "funding": { 5731 + "url": "https://github.com/fb55/nth-check?sponsor=1" 5732 + } 5733 + }, 5491 5734 "node_modules/object-assign": { 5492 5735 "version": "4.1.1", 5493 5736 "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", ··· 5519 5762 } 5520 5763 }, 5521 5764 "node_modules/oniguruma-to-es": { 5522 - "version": "0.4.1", 5523 - "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-0.4.1.tgz", 5524 - "integrity": "sha512-rNcEohFz095QKGRovP/yqPIKc+nP+Sjs4YTHMv33nMePGKrq/r2eu9Yh4646M5XluGJsUnmwoXuiXE69KDs+fQ==", 5765 + "version": "0.7.0", 5766 + "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-0.7.0.tgz", 5767 + "integrity": "sha512-HRaRh09cE0gRS3+wi2zxekB+I5L8C/gN60S+vb11eADHUaB/q4u8wGGOX3GvwvitG8ixaeycZfeoyruKQzUgNg==", 5525 5768 "dependencies": { 5526 5769 "emoji-regex-xs": "^1.0.0", 5527 - "regex": "^5.0.0", 5528 - "regex-recursion": "^4.2.1" 5770 + "regex": "^5.0.2", 5771 + "regex-recursion": "^4.3.0" 5529 5772 } 5530 5773 }, 5531 5774 "node_modules/ora": { ··· 6112 6355 } 6113 6356 }, 6114 6357 "node_modules/regex-recursion": { 6115 - "version": "4.2.1", 6116 - "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-4.2.1.tgz", 6117 - "integrity": "sha512-QHNZyZAeKdndD1G3bKAbBEKOSSK4KOHQrAJ01N1LJeb0SoH4DJIeFhp0uUpETgONifS4+P3sOgoA1dhzgrQvhA==", 6358 + "version": "4.3.0", 6359 + "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-4.3.0.tgz", 6360 + "integrity": "sha512-5LcLnizwjcQ2ALfOj95MjcatxyqF5RPySx9yT+PaXu3Gox2vyAtLDjHB8NTJLtMGkvyau6nI3CfpwFCjPUIs/A==", 6118 6361 "dependencies": { 6119 6362 "regex-utilities": "^2.3.0" 6120 6363 } ··· 6195 6438 "url": "https://opencollective.com/unified" 6196 6439 } 6197 6440 }, 6441 + "node_modules/remark-directive": { 6442 + "version": "3.0.0", 6443 + "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.0.tgz", 6444 + "integrity": "sha512-l1UyWJ6Eg1VPU7Hm/9tt0zKtReJQNOA4+iDMAxTyZNWnJnFlbS/7zhiel/rogTLQ2vMYwDzSJa4BiVNqGlqIMA==", 6445 + "dependencies": { 6446 + "@types/mdast": "^4.0.0", 6447 + "mdast-util-directive": "^3.0.0", 6448 + "micromark-extension-directive": "^3.0.0", 6449 + "unified": "^11.0.0" 6450 + }, 6451 + "funding": { 6452 + "type": "opencollective", 6453 + "url": "https://opencollective.com/unified" 6454 + } 6455 + }, 6198 6456 "node_modules/remark-gfm": { 6199 6457 "version": "4.0.0", 6200 6458 "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz", ··· 6545 6803 } 6546 6804 }, 6547 6805 "node_modules/shiki": { 6548 - "version": "1.23.1", 6549 - "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.23.1.tgz", 6550 - "integrity": "sha512-8kxV9TH4pXgdKGxNOkrSMydn1Xf6It8lsle0fiqxf7a1149K1WGtdOu3Zb91T5r1JpvRPxqxU3C2XdZZXQnrig==", 6806 + "version": "1.24.2", 6807 + "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.24.2.tgz", 6808 + "integrity": "sha512-TR1fi6mkRrzW+SKT5G6uKuc32Dj2EEa7Kj0k8kGqiBINb+C1TiflVOiT9ta6GqOJtC4fraxO5SLUaKBcSY38Fg==", 6551 6809 "dependencies": { 6552 - "@shikijs/core": "1.23.1", 6553 - "@shikijs/engine-javascript": "1.23.1", 6554 - "@shikijs/engine-oniguruma": "1.23.1", 6555 - "@shikijs/types": "1.23.1", 6810 + "@shikijs/core": "1.24.2", 6811 + "@shikijs/engine-javascript": "1.24.2", 6812 + "@shikijs/engine-oniguruma": "1.24.2", 6813 + "@shikijs/types": "1.24.2", 6556 6814 "@shikijs/vscode-textmate": "^9.3.0", 6557 6815 "@types/hast": "^3.0.4" 6558 6816 } ··· 7095 7353 "semver": "^7.3.8" 7096 7354 } 7097 7355 }, 7356 + "node_modules/uhyphen": { 7357 + "version": "0.2.0", 7358 + "resolved": "https://registry.npmjs.org/uhyphen/-/uhyphen-0.2.0.tgz", 7359 + "integrity": "sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA==" 7360 + }, 7098 7361 "node_modules/uint8arrays": { 7099 7362 "version": "3.0.0", 7100 7363 "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.0.0.tgz", ··· 7200 7463 "type": "opencollective", 7201 7464 "url": "https://opencollective.com/unified" 7202 7465 } 7466 + }, 7467 + "node_modules/unist-util-select": { 7468 + "version": "4.0.3", 7469 + "resolved": "https://registry.npmjs.org/unist-util-select/-/unist-util-select-4.0.3.tgz", 7470 + "integrity": "sha512-1074+K9VyR3NyUz3lgNtHKm7ln+jSZXtLJM4E22uVuoFn88a/Go2pX8dusrt/W+KWH1ncn8jcd8uCQuvXb/fXA==", 7471 + "dependencies": { 7472 + "@types/unist": "^2.0.0", 7473 + "css-selector-parser": "^1.0.0", 7474 + "nth-check": "^2.0.0", 7475 + "zwitch": "^2.0.0" 7476 + }, 7477 + "funding": { 7478 + "type": "opencollective", 7479 + "url": "https://opencollective.com/unified" 7480 + } 7481 + }, 7482 + "node_modules/unist-util-select/node_modules/@types/unist": { 7483 + "version": "2.0.11", 7484 + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", 7485 + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" 7203 7486 }, 7204 7487 "node_modules/unist-util-stringify-position": { 7205 7488 "version": "4.0.0",
+4
package.json
··· 12 12 }, 13 13 "dependencies": { 14 14 "@ascorbic/bluesky-loader": "^0.0.3", 15 + "@astro-community/astro-embed-utils": "^0.1.3", 15 16 "@astrojs/check": "^0.9.4", 16 17 "@astrojs/mdx": "^3.1.9", 17 18 "@astrojs/rss": "^4.0.9", 18 19 "@astrojs/sitemap": "^3.2.1", 19 20 "@astrojs/svelte": "^6.0.2", 20 21 "@astrojs/tailwind": "^5.1.2", 22 + "@shikijs/transformers": "^1.24.2", 21 23 "@tailwindcss/forms": "^0.5.9", 22 24 "astro": "^4.16.14", 25 + "astro-custom-embeds": "^0.0.1", 23 26 "astro-og-canvas": "^0.5.4", 27 + "lite-youtube-embed": "^0.3.3", 24 28 "svelte": "^5.1.1", 25 29 "tailwind-merge": "^2.5.4", 26 30 "tailwindcss": "^3.4.14",
+2 -2
src/components/Pagination.astro
··· 91 91 clip-rule="evenodd" 92 92 /> 93 93 </svg> 94 - older posts 94 + older 95 95 </a> 96 96 ) : null 97 97 } ··· 126 126 } 127 127 class="inline-flex items-center border-t-2 border-transparent pr-1 pt-4 text-sm font-medium text-base-500 hover:border-base-300 hover:text-base-700 dark:text-base-400 dark:hover:border-base-700 dark:hover:text-base-300" 128 128 > 129 - newer posts 129 + newer 130 130 <svg 131 131 class="ml-3 h-5 w-5 text-base-400" 132 132 viewBox="0 0 20 20"
-2
src/components/bluesky/Comments.svelte
··· 21 21 } else if (uri) { 22 22 comments = await getComments(uri); 23 23 } 24 - 25 - console.log(comments); 26 24 }); 27 25 </script> 28 26
+3 -3
src/config.json
··· 1 1 { 2 + "SITE": "https://flo-bit.dev", 3 + "BASE": "/blog-template", 2 4 "SITE_TITLE": "Blog template", 3 5 "SITE_NAME": "blog template", 4 6 "SITE_DESCRIPTION": "Welcome to my website!", ··· 20 22 "EMAIL": "flo.bit.dev@gmail.com", 21 23 "BLUESKY_URL": "https://bsky.app/profile/flo-bit.dev" 22 24 }, 23 - "BLUESKY_IDENTIFIER": "flo-bit.dev", 24 - "SITE": "https://flo-bit.dev", 25 - "BASE": "/blog-template" 25 + "BLUESKY_IDENTIFIER": "flo-bit.dev" 26 26 }
+1 -1
src/content/blog/adding-content.mdx
··· 1 1 --- 2 2 title: "Adding blog posts directly" 3 - description: "Learn how to add content to your blog directly in the code (without using pagescms)" 3 + description: "Learn how to add content to your blog directly in the code" 4 4 pubDate: "Oct 24 2024" 5 5 published: true 6 6 heroImage: "/src/assets/blog-placeholder-4.jpg"
+1 -1
src/content/blog/comments-via-bluesky.mdx
··· 4 4 pubDate: "Dec 02 2024" 5 5 published: true 6 6 heroImage: "/src/assets/blog-placeholder-1.jpg" 7 - tags: ["setup"] 7 + tags: ["setup", "bluesky"] 8 8 --- 9 9 10 10 You can also show comments on your blog posts using bluesky.
+1 -1
src/content/blog/likes-via-bluesky.mdx
··· 4 4 pubDate: "Nov 22 2024" 5 5 published: true 6 6 heroImage: "/src/assets/blog-placeholder-3.jpg" 7 - tags: ["setup"] 7 + tags: ["setup", "bluesky"] 8 8 disableComments: false 9 9 --- 10 10
+29
src/content/blog/showing-code.mdx
··· 1 + --- 2 + title: "Showing code" 3 + description: "Learn how to show code in your blog posts" 4 + pubDate: "Dec 10 2024" 5 + published: false 6 + heroImage: "/src/assets/blog-placeholder-4.jpg" 7 + tags: ["code", "markdown"] 8 + --- 9 + 10 + 11 + this is some `inline code` 12 + 13 + this is some multiline code: 14 + 15 + ```js {1,2} 16 + const a = 1; 17 + 18 + console.log(a); 19 + 20 + const b = "this is a string"; 21 + 22 + console.log(b);// [!code highlight] 23 + 24 + function test() { 25 + const test = "this is a very long string, that should hopefully wrap onto multiple lines"; // [!code highlight] 26 + 27 + console.log(test); 28 + } 29 + ```
+26
src/content/blog/showing-embeds.mdx
··· 1 + --- 2 + title: "Showing embeds" 3 + description: "Learn how to show embeds in your blog posts" 4 + pubDate: "Dec 11 2024" 5 + published: true 6 + heroImage: "/src/assets/blog-placeholder-3.jpg" 7 + tags: ["embeds"] 8 + --- 9 + 10 + you can show embeds in your blog posts for youtube and link cards. 11 + 12 + simply write a youtube url in your post like this (with nothing else on the same line): 13 + 14 + ```mdx 15 + https://www.youtube.com/watch?v=dQw4w9WgXcQ 16 + ``` 17 + 18 + https://www.youtube.com/watch?v=dQw4w9WgXcQ 19 + 20 + or any other url for a link card like this (again with nothing else on the same line): 21 + 22 + ```mdx 23 + https://flo-bit.dev 24 + ``` 25 + 26 + https://flo-bit.dev
+5
src/embeds/index.ts
··· 1 + 2 + import LinkCard from './link-card/LinkCard.astro'; 3 + import YouTube from './youtube/Youtube.astro'; 4 + 5 + export { LinkCard, YouTube };
+3
src/embeds/matcher.ts
··· 1 + import YoutubeMatcher from './youtube/matcher.ts'; 2 + import LinkMatcher from './link-card/matcher.ts'; 3 + export { YoutubeMatcher, LinkMatcher };
+69
src/embeds/youtube/YouTube.astro
··· 1 + --- 2 + import "lite-youtube-embed/src/lite-yt-embed.css"; 3 + import urlMatcher from "./matcher"; 4 + 5 + export interface Props extends astroHTML.JSX.HTMLAttributes { 6 + id: string; 7 + poster?: string; 8 + posterQuality?: "max" | "high" | "default" | "low"; 9 + params?: string; 10 + playlabel?: string; 11 + } 12 + 13 + const { 14 + id, 15 + poster, 16 + posterQuality = "default", 17 + title, 18 + ...attrs 19 + } = Astro.props as Props; 20 + 21 + const idRegExp = /^[A-Za-z0-9-_]+$/; 22 + 23 + function extractID(idOrUrl: string) { 24 + if (idRegExp.test(idOrUrl)) return idOrUrl; 25 + return urlMatcher(idOrUrl); 26 + } 27 + 28 + const videoid = extractID(id); 29 + const posterFile = 30 + { 31 + max: "maxresdefault", 32 + high: "sddefault", 33 + default: "hqdefault", 34 + low: "default", 35 + }[posterQuality] || "hqdefault"; 36 + const posterURL = 37 + poster || `https://i.ytimg.com/vi/${videoid}/${posterFile}.jpg`; 38 + const href = `https://youtube.com/watch?v=${videoid}`; 39 + --- 40 + 41 + <lite-youtube 42 + {videoid} 43 + {title} 44 + data-title={title} 45 + {...attrs} 46 + style={`background-image: url('${posterURL}');`} 47 + > 48 + <a {href} class="lty-playbtn"> 49 + <span class="lyt-visually-hidden">{attrs.playlabel}</span> 50 + </a> 51 + </lite-youtube> 52 + 53 + <script src="lite-youtube-embed"></script> 54 + 55 + <style is:global> 56 + lite-youtube > iframe { 57 + all: unset !important; 58 + width: 100% !important; 59 + height: 100% !important; 60 + position: absolute !important; 61 + inset: 0 !important; 62 + border: 0 !important; 63 + } 64 + 65 + lite-youtube > .lty-playbtn { 66 + @apply fill-amber-500; 67 + background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 68 48"><path d="M66.52 7.74c-.78-2.93-2.49-5.41-5.42-6.19C55.79.13 34 0 34 0S12.21.13 6.9 1.55c-2.93.78-4.63 3.26-5.42 6.19C.06 13.05 0 24 0 24s.06 10.95 1.48 16.26c.78 2.93 2.49 5.41 5.42 6.19C12.21 47.87 34 48 34 48s21.79-.13 27.1-1.55c2.93-.78 4.64-3.26 5.42-6.19C67.94 34.95 68 24 68 24s-.06-10.95-1.48-16.26z" fill="red"/><path d="M45 24 27 14v20" fill="white"/></svg>'); 68 + } 69 + </style>
+12
src/embeds/youtube/embed.ts
··· 1 + import type { EmbedsOption } from "astro-custom-embeds"; 2 + import YoutubeMatcher from "./matcher"; 3 + 4 + const YoutubeEmbed: EmbedsOption = { 5 + componentName: 'YouTube', 6 + urlArgument: 'id', 7 + urlMatcher: YoutubeMatcher, 8 + directiveName: 'youtube', 9 + importPath: 'src/embeds', 10 + } 11 + 12 + export default YoutubeEmbed;
+14
src/embeds/youtube/matcher.ts
··· 1 + // Thanks to eleventy-plugin-youtube-embed 2 + // https://github.com/gfscott/eleventy-plugin-youtube-embed/blob/main/lib/extractMatches.js 3 + const urlPattern = 4 + /(?=(\s*))\1(?:<a [^>]*?>)??(?=(\s*))\2(?:https?:\/\/)??(?:w{3}\.)??(?:youtube\.com|youtu\.be)\/(?:watch\?v=|embed\/|shorts\/)??([A-Za-z0-9-_]{11})(?:[^\s<>]*)(?=(\s*))\4(?:<\/a>)??(?=(\s*))\5/; 5 + 6 + /** 7 + * Extract a YouTube ID from a URL if it matches the pattern. 8 + * @param url URL to test 9 + * @returns A YouTube video ID or undefined if none matched 10 + */ 11 + export default function matcher(url: string): string | undefined { 12 + const match = url.match(urlPattern); 13 + return match?.[3]; 14 + }
+30 -12
src/layouts/BaseLayout.astro
··· 27 27 <style is:global> 28 28 html.dark .astro-code, 29 29 html.dark .astro-code span { 30 - color: var(--shiki-dark) !important; 31 - /* Optional, if you also want font styles */ 32 - font-style: var(--shiki-dark-font-style) !important; 33 - font-weight: var(--shiki-dark-font-weight) !important; 34 - text-decoration: var(--shiki-dark-text-decoration) !important; 30 + color: var(--shiki-dark); 31 + } 32 + 33 + html:not(dark) .astro-code, 34 + html:not(dark) .astro-code span { 35 + color: var(--shiki-light); 35 36 } 36 37 37 38 pre { 38 - border: 1px solid rgba(0, 0, 0, 0.1); 39 - background-color: rgba(0, 0, 0, 0.03) !important; 40 - border-radius: 0.75rem !important; 39 + @apply overflow-hidden !important; 40 + @apply border border-base-300 dark:border-base-700 bg-base-200/50 dark:bg-base-950/30 rounded-xl !important; 41 41 } 42 42 43 - html.dark pre { 44 - border: 1px solid rgba(255, 255, 255, 0.1); 45 - background-color: rgba(255, 255, 255, 0.05) !important; 46 - border-radius: 0.75rem !important; 43 + .line.highlighted { 44 + margin: 0 -24px; 45 + padding: 0 24px; 46 + position: relative; 47 + 48 + display: inline-block; 49 + width: calc(100% + 48px); 50 + } 51 + .line.highlighted { 52 + @apply bg-accent-500/10 dark:bg-accent-700/10; 53 + } 54 + 55 + ::selection { 56 + @apply bg-accent-300/50 dark:bg-accent-900/40; 57 + } 58 + 59 + lite-youtube { 60 + @apply rounded-xl border border-base-300 dark:border-base-700; 61 + } 62 + 63 + .prose mark { 64 + @apply bg-accent-200 dark:bg-accent-900 text-black dark:text-white; 47 65 } 48 66 </style> 49 67 </head>