1
0
mirror of https://github.com/kremalicious/blog.git synced 2024-12-22 09:13:35 +01:00
🍭 My blog kremalicious.com built with Astro. Neat. https://kremalicious.com
Go to file
2023-09-19 19:37:10 +01:00
.config remove twitter 2023-09-19 19:37:10 +01:00
.github more build artifact isolation 2023-09-19 16:25:19 +01:00
content related posts tweaks 2023-09-19 13:41:37 +01:00
public Gatsby → Astro (#829) 2023-09-18 02:16:53 +01:00
scripts uncache favicon.ico 2023-09-19 14:33:50 +01:00
src remove twitter 2023-09-19 19:37:10 +01:00
test more unit tests 2023-09-19 19:04:02 +01:00
.editorconfig add prettier-plugin-sort-imports 2023-01-29 21:58:19 +00:00
.env.sample Gatsby → Astro (#829) 2023-09-18 02:16:53 +01:00
.eslintrc.json Gatsby → Astro (#829) 2023-09-18 02:16:53 +01:00
.gitignore Gatsby → Astro (#829) 2023-09-18 02:16:53 +01:00
.nvmrc Gatsby v5 (#731) 2022-11-08 21:03:54 +00:00
.prettierrc.json Gatsby → Astro (#829) 2023-09-18 02:16:53 +01:00
LICENSE cleanup 2018-08-29 00:17:24 +02:00
package-lock.json Gatsby → Astro (#829) 2023-09-18 02:16:53 +01:00
package.json Gatsby → Astro (#829) 2023-09-18 02:16:53 +01:00
README.md Gatsby → Astro (#829) 2023-09-18 02:16:53 +01:00
tsconfig.json Gatsby → Astro (#829) 2023-09-18 02:16:53 +01:00

🍭 My blog built with Astro + TypeScript. Neat.

kremalicious.com



🎉 Features

The whole blog is a statically exported site built with Astro and TypeScript. Almost all components are Astro or native Web Components, with some React components loaded client-side.

Styling happens through a combination of basic global styles and on components level either through CSS modules or CSS in <style> tags within Astro components.

Content lives under content/ and Astro creates a content collection for each subfolder, which are then queried in components. Every post is a folder with a markdown file and all respective post assets colocated inside.

Retrieving content collections will enrich every post's frontmatter metadata, like extracting date and slug from the post folder name, or exif extraction for photos.

🌅 Image handling

Uses Astro's native astro:assets feature, all required image sizes are automatically generated from source images, working in combination with my own custom <picture> component. Making heavy use of Astro's getImage() and custom markup results in full image sizing control and properly object-fit images with varying aspect ratios.

Teaser images are all defined in a post's frontmatter image key, which is then passed to the <Picture /> component for display.

If you want to know how this works, have a look at the respective files:

🎆 EXIF extraction

Automatically extracts EXIF & IPTC metadata from my photos and adds it to markdown frontmatter of respective photo posts. For minimal overhead, fast-exif & node-iptc is used to parse every JPG file whenever a content collection is accessed.

In the end looks like this, including location display with pigeon-maps:

screen shot 2018-10-14 at 20 27 39

If you want to know how this works, have a look at the respective files:

💰 Cryptocurrency donation via Web3/MetaMask

Lets visitors say thanks with Bitcoin or Ether. Uses RainbowKit for wallet connection & wagmi for sending transactions via browser wallets.

screen shot 2018-10-14 at 22 03 57

If you want to know how this works, have a look at the respective components under

A global search is provided with fuse.js. Whenever search is opened, all posts metadata is fetched, which is then queried against when the search field is used. This prevents a huge search index from being bundled in the site build.

screen shot 2018-11-18 at 19 44 30

If you want to know how this works, have a look at the respective components under

Under each post a list of related posts is displayed which are based on the tags and other metadata of the currently viewed post, also done with fuse.js.

screen shot 2018-10-11 at 21 03 03

If you want to know how this works, have a look at the respective component under

📝 GitHub changelog rendering

Adds ability to show contents of a changelog, rendered from a CHANGELOG.md on GitHub from the given repository. The use case is to enhance release posts about projects hosted on GitHub. Makes use of the GitHub GraphQL API.

Adding this to a post's YAML frontmatter:

changelog: kremalicious/gatsby-plugin-matomo

will render this at the end of the post:

screen shot 2018-11-21 at 23 03 38

See it live e.g. on Matomo plugin for Gatsby.

If you want to know how this works, have a look at the respective component under

🌗 Theme Switcher

Includes a theme switcher which allows user to toggle between a light and a dark theme. Switching between them also happens automatically based on user's system preferences. Uses nanostores to share its state between components/frameworks.

If you want to know how, have a look at the respective components:

💎 SVG assets as components

All SVG assets under src/images/ and from select iconset dependencies are converted to Astro components before building the site. Compiled components are placed under src/images/components/ and all include the cleaned SVGs as inline HTML.

All SVGs can then be imported from @images/components in all Astro components.

If you want to know how this works, have a look at the respective files:

redirect_from

Still a remnant of the old Jekyll days, which survived in gatsby-redirect-from and now works in Astro. For all post slugs defined in a redirect_from frontmatter key, redirects will be put in place by Astro.

Before building the site, a script scans all markdown files and creates a json file under .config/redirects.json. This file is then imported into astro.config.ts under its redirects option.

If you want to know how, have a look at the respective files:

RSS & JSON feeds

Development

git clone git@github.com:kremalicious/blog.git
cd blog/

# required env vars
cp .env.sample .env
vi .env

npm i
npm start

🔮 Linting

ESlint, Prettier, and Stylelint are setup for all linting purposes:

npm run lint

To automatically format all code files:

npm run format

🔮 Type Checking

Type checking can be invoked to check all TypeScript code, including within .astro files:

npm run typecheck

👩‍🔬 Testing

Test suite is setup with Vitest, react-testing-library, and Playwright.

All unit test files live beside the respective component with naming pattern *.test.ts(x). Integration test files live under ./test/e2e/ exclusively, with naming pattern *.spec.ts.

Testing setup, fixtures, and mocks shared between unit & integration tests can be found in ./test folder.

To run all unit tests:

npm run test:unit

For End-to-End integration testing, ideally run against the production build:

npm run build && npm run preview

# mapping `playwright` command
npm run test:e2e
npm run test:e2e -- --ui
npm run test:e2e -- path/to/file.spec.ts.
npm run test:e2e -- --update-snapshots

🎈 Content creation helpers

Add a new post

npm run new "Hello World"
npm run new "Hello World" 2017-12-27

Create a new photo post with date, title & description pre-filled from EXIF/IPTC data of a given image file:

npm run new photo /path/to/photo.jpg
npm run new photo /path/to/photo.jpg "Hello Photo Post"

🚚 Deployment

Every branch or Pull Request is automatically deployed by Vercel with their GitHub integration. A link to a preview deployment will appear under each Pull Request. Vercel is not used for the production deployment.

S3 Deployment

The latest deployment of the main branch is automatically deployed to S3 from the GitHub Action as the production deployment, aliased to kremalicious.com. The deploy command simply calls the scripts/deploy-s3.sh script, syncing the contents of the dist/ folder to S3:

npm run deploy:s3

🏛 Licenses

The MIT License (MIT)

EXCEPT FOR:

Posts

Creative Commons License

All post content under ./content/articles & ./content/links is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Photos & images

All photos & image assets are plain ol' copyright.

Copyright (c) 20082023 Matthias Kretschmann

Don't care if you fork & play with it, but you're not allowed to publish anything from it as a whole without my written permission. Also please be aware, the combination of typography, colors & layout makes up my brand identity. So please don't just clone everything, but rather do a remix!