diff --git a/README.md b/README.md index 35524b5..11d4f69 100644 --- a/README.md +++ b/README.md @@ -1,231 +1,121 @@
- Astro Cactus logo + Prad Nukala
-

- Astro Cactus -

+

prad.nu

-Astro Cactus is a simple opinionated starter built with [Astro](https://astro.build). Use it to create an easy-to-use blog or website. +

The personal CV & portfolio site of Prad Nukala — engineer and founder.

-## Table Of Contents +## What this is -1. [Key Features](#key-features) -2. [Demo](#demo-) -3. [Quick start](#quick-start) -4. [Preview](#preview) -5. [Commands](#commands) -6. [Configure](#configure) -7. [Updating](#updating) -8. [Adding posts, notes, and tags](#adding-posts-notes-and-tags) - - [Post Frontmatter](#post-frontmatter) - - [Note Frontmatter](#note-frontmatter) - - [Tag Frontmatter](#tag-frontmatter) - - [Frontmatter Snippets](#frontmatter-snippets) -9. [Pagefind search](#pagefind-search) -10. [Analytics](#analytics) -11. [Deploy](#deploy) -12. [Acknowledgment](#acknowledgment) +This repo is my personal website at [prad.nu](https://prad.nu). It's a static [Astro](https://astro.build) site (originally forked from the [Astro Cactus](https://github.com/chrismwilliams/astro-theme-cactus) theme) reworked into a portfolio organised around four sections: -## Key Features +| Section | Route | Purpose | +| ------------------ | -------------- | ------------------------------------------------------------ | +| **Projects** | `/projects` | Things I've built, with links to live sites and source. | +| **Experience** | `/experience` | Resume-style roles, which also act as a taxonomy (see below). | +| **Writing** | `/writing` | Essays, notes, and articles. | +| **Speaking** | `/speaking` | Talks, with an embedded [Cloudflare Stream](https://developers.cloudflare.com/stream/) player and a link to the original recording. | -- Astro v6 Fast 🚀 -- Tailwind v4 -- Accessible, semantic HTML markup -- Responsive & SEO-friendly -- Dark & Light mode -- MD & [MDX](https://docs.astro.build/en/guides/markdown-content/#mdx-only-features) posts & notes - - Includes [Admonitions](https://astro-cactus.chriswilliams.dev/posts/markdown-elements/admonitions/) -- [Satori](https://github.com/vercel/satori) for creating open graph png images -- [Automatic RSS feeds](https://docs.astro.build/en/guides/rss) -- [Webmentions](https://webmention.io/) -- Auto-generated: - - [sitemap](https://docs.astro.build/en/guides/integrations-guide/sitemap/) - - [robots.txt](https://github.com/alextim/astro-lib/blob/main/packages/astro-robots-txt/README.md) - - [web app manifest](https://github.com/alextim/astro-lib/blob/main/packages/astro-webmanifest/README.md) -- [Pagefind](https://pagefind.app/) static search library integration -- [Astro Icon](https://github.com/natemoo-re/astro-icon) svg icon component -- [Expressive Code](https://expressive-code.com/) code blocks and syntax highlighter +### Experience as a taxonomy -## Demo 💻 +Experience entries are the connective tissue of the site. Projects, writing, and talks each declare an `experiences` array in their frontmatter that references experience entries by id. Each experience page then renders its own write-up **plus** every project, post, and talk filed under it — so the content cross-links automatically. -Check out the [Demo](https://astro-cactus.chriswilliams.dev/), hosted on Netlify +## Tech -## Quick start - -[Create a new repo](https://github.com/chrismwilliams/astro-theme-cactus/generate) from this template. - -```bash -# npm 7+ -npm create astro@latest -- --template chrismwilliams/astro-theme-cactus - -# pnpm -pnpm dlx create-astro --template chrismwilliams/astro-theme-cactus -``` - -[![Deploy with Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/chrismwilliams/astro-theme-cactus) [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fchrismwilliams%2Fastro-theme-cactus&project-name=astro-theme-cactus) - -## Preview - -![Astro Theme Cactus in a light theme mode](https://github.com/chrismwilliams/astro-theme-cactus/assets/12715988/84c89d42-4525-4674-b10c-6d6ebdc06382) - -![Astro Theme Cactus in a dark theme mode](https://github.com/chrismwilliams/astro-theme-cactus/assets/12715988/e0e575e2-445f-4c2d-a812-b5b53d2d9031) +- [Astro](https://astro.build) v6 (static output, no adapter required) +- [Tailwind CSS](https://tailwindcss.com) v4 +- [Content Collections](https://docs.astro.build/en/guides/content-collections/) with type-checked frontmatter (`src/content.config.ts`) +- [Cloudflare Stream](https://developers.cloudflare.com/stream/) for speaking videos +- [Satori](https://github.com/vercel/satori) OG images, [Pagefind](https://pagefind.app/) search, RSS, sitemap, and `Person` JSON-LD on the homepage for SEO +- Dark / light mode, accessible semantic markup ## Commands -Replace pnpm with your choice of npm / yarn +| Command | Action | +| :--------------- | :-------------------------------------------------- | +| `pnpm install` | Install dependencies | +| `pnpm dev` | Start the local dev server | +| `pnpm build` | Build the production site to `./dist/` | +| `pnpm postbuild` | Build the Pagefind static search index | +| `pnpm preview` | Preview the production build locally | +| `pnpm sync` | Generate types from the content config | -| Command | Action | -| :--------------- | :------------------------------------------------------------- | -| `pnpm install` | Installs dependencies | -| `pnpm dev` | Starts local dev server at `localhost:3000` | -| `pnpm build` | Build your production site to `./dist/` | -| `pnpm postbuild` | Pagefind script to build the static search of your blog posts | -| `pnpm preview` | Preview your build locally, before deploying | -| `pnpm sync` | Generate types based on your config in `src/content/config.ts` | +## Content + +Content lives in `src/content/` as `.md`/`.mdx` files; the filename becomes the slug. The schema for each collection is defined in `src/content.config.ts`. + +### Projects (`src/content/projects`) + +| Property | Required | Notes | +| --------------- | :------: | -------------------------------------------------- | +| `title` | ✓ | Max 60 chars. | +| `publishDate` | ✓ | ISO 8601 (offsets allowed). | +| `description` | | Used for meta description. | +| `link` | | URL to the live project. | +| `repo` | | URL to the source repository. | +| `tags` | | String array. | +| `experiences` | | Array of experience ids this project is filed under. | + +### Experience (`src/content/experience`) + +| Property | Required | Notes | +| --------------- | :------: | -------------------------------------------------- | +| `title` | ✓ | Display name of the experience (also its id via filename). | +| `organization` | ✓ | Company / org. | +| `startDate` | ✓ | Date. | +| `endDate` | | Omit for current/ongoing. | +| `role` | | Job title. | +| `location` | | e.g. "Remote". | +| `url` | | Org website. | +| `description` | | Short summary. | + +### Writing (`src/content/writing`) + +| Property | Required | Notes | +| --------------- | :------: | -------------------------------------------------- | +| `title` | ✓ | Max 60 chars. | +| `description` | ✓ | Meta description. | +| `publishDate` | ✓ | Date. | +| `updatedDate` | | Date. | +| `coverImage` | | `{ src, alt }`. | +| `ogImage` | | Skip Satori generation with a custom OG image. | +| `tags` | | String array. | +| `experiences` | | Array of experience ids. | +| `draft` | | `true` excludes the post from production builds. | +| `pinned` | | Pin to the top of `/writing`. | + +### Speaking (`src/content/speaking`) + +| Property | Required | Notes | +| ---------------- | :------: | ------------------------------------------------- | +| `title` | ✓ | Max 60 chars. | +| `description` | ✓ | Meta description. | +| `publishDate` | ✓ | Date. | +| `videoId` | ✓ | Cloudflare Stream video UID. | +| `originalSource` | | Link to the original (e.g. YouTube) recording. | +| `event` | | Conference / event name. | +| `tags` | | String array. | +| `experiences` | | Array of experience ids. | +| `draft` | | `true` excludes the talk from production builds. | ## Configure -- Edit the template's config file `src/site.config.ts` - - **Important**: set the url property with your own domain. - - Modify the settings for markdown code blocks, generated by [Expressive Code](https://expressive-code.com). Astro Cactus has both a dark (dracula) and light (github-light) theme. You can find more options [@ expressive-code](https://expressive-code.com/guides/themes/#available-themes). -- Update file `astro.config.ts` - - [astro-webmanifest options](https://github.com/alextim/astro-lib/blob/main/packages/astro-webmanifest/README.md) -- Replace & update files within the `/public` folder: - - icon.svg - used as the source to create favicons & manifest icons - - social-card.png - used as the default og:image -- Modify file `src/styles/global.css` with your own light and dark styles, and customise [Tailwind's theme settings](https://tailwindcss.com/docs/theme#customizing-your-theme). -- Edit social links in `src/components/SocialList.astro` to add/replace your media profile. Icons can be found @ [icones.js.org](https://icones.js.org/), per [Astro Icon's instructions](https://www.astroicon.dev/guides/customization/#find-an-icon-set). -- Create/edit posts & notes for your blog within `src/content/post/` & `src/content/note/` with .md/mdx file(s). See [below](#adding-posts-notes-and-tags) for more details. - - Read [this post](http://astro-cactus.chriswilliams.dev/posts/webmentions/) for adding webmentions to your site. - - Add any custom Tag pages for related blog posts in `/src/content/tag/`, ensuring that the file name is the same as the tag. -- OG Image: - - If you would like to change the style of the generated image the Satori library creates, open up `src/pages/og-image/_ogMarkup.ts` to the markup function where you can edit the html/tailwind-classes as necessary. You can use this [playground](https://og-playground.vercel.app/) to aid your design. - - You can also create your own og images and skip satori generating it for you by adding an ogImage property in the frontmatter with a link to the asset, an example can be found in `src/content/post/testing/social-image.md`. More info on frontmatter can be found [below](#post-frontmatter) -- Optional: - - Fonts: This theme sets the body element to the font family `font-mono`, in `src/layouts/Base.astro` on the ``. You can change fonts by removing the variant `font-mono`, after which TailwindCSS will default to the `font-sans` [font family stack](https://tailwindcss.com/docs/font-family). +Most site-wide settings live in **`src/site.config.ts`**: -## Updating +- `siteConfig` — title, author, description, `url` (used for canonical URLs and OG tags), locale. +- `socialLinks` — GitHub / X / LinkedIn / email, shown in the footer and homepage intro. +- `streamOrigin` — the Cloudflare Stream origin (your `customer-.cloudflarestream.com` subdomain or a Worker/custom domain). The speaking player loads `${streamOrigin}//iframe`. +- `menuLinks` — header/footer navigation. -If you've forked the template, you can [sync the fork](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork) with your own project, remembering to **not** click Discard Changes as you will lose your own. - -If you have a template repository, you can add this template as a remote, [as discussed here](https://stackoverflow.com/questions/56577184/github-pull-changes-from-a-template-repository). - -## Adding posts, notes, and tags - -This theme uses [Content Collections](https://docs.astro.build/en/guides/content-collections/) to organise local Markdown and MDX files, as well as type-checking frontmatter with a schema -> `src/content.config.ts`. - -Adding a post/note/tag is as simple as adding your .md(x) files to either `src/content/post`, `src/content/note`, and `src/content/tag` folders, the filename of which will be used as the slug/url. - -The Tag collection allows you to override the content for generated tag pages. For example the template includes `src/content/tag/test.md` which overrides the content shown in `your-domain.com/tags/test`. - -> **Note** -> For a tag page to work, the file name (`src/content/tag/*`) must also be in a post's [tags frontmatter.](#post-frontmatter) - -The posts/notes/tags included with this template are there as an example of how to structure your frontmatter. Additionally, the [Astro docs](https://docs.astro.build/en/guides/markdown-content/) has a detailed section on markdown pages. - -### Post Frontmatter - -| Property (\* required) | Description | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| title \* | Self explanatory. Used as the text link to the post, the h1 on the posts' page, and the pages title property. Has a max length of 60 chars, set in `src/content/config.ts` | -| description \* | Similar to above, used as the seo description property. Has a min length of 50 and a max length of 160 chars, set in the post schema. | -| publishDate \* | Again pretty simple. To change the date format/locale, currently **en-GB**, update the date option in `src/site.config.ts`. Note you can also pass additional options to the component `` if required. | -| updatedDate | This is an optional date representing when a post has been updated, in the same format as the publishDate. | -| tags | Tags are optional with any created post. Any new tag(s) will be shown in `your-domain.com/posts` & `your-domain.com/tags`, and generate the page(s) `your-domain.com/tags/[yourTag]` | -| coverImage | This is an optional object that will add a cover image to the top of a post. Include both a `src`: "_path-to-image_" and `alt`: "_image alt_". You can view an example in `src/content/post/testing/cover-image/index.md`. | -| ogImage | This is an optional property. An OG Image will be generated automatically for every post where this property **isn't** provided. If you would like to create your own for a specific post, include this property and a link to your image, the theme will then skip automatically generating one. | -| draft | This is an optional property as it is set to false by default in the schema. By adding true, the post will be filtered out of the production build in a number of places, inc. getAllPosts() calls, og-images, rss feeds, and generated page[s]. You can view an example in `src/content/post/testing/draft-post.md` | - -### Note Frontmatter - -| Property (\* required) | Description | -| ---------------------- | --------------------------------------------------------------------------------------------------------------------- | -| title \* | Used as the link text to the note, the pages title property, and the h1 of said note page. Has a max length 60 chars. | -| description | Optional. Used for the head meta description property. | -| publishDate \* | ISO 8601 format with offsets allowed. | - -### Tag Frontmatter - -| Property (\* required) | Description | -| ---------------------- | ------------------------------------------------------------------------------------------------------- | -| title | Optional. Used as the h1 on the tags' page, and the pages title property. Has a max length of 60 chars. | -| description | Optional. Used for the head meta description and the first paragraph under the h1. | - -### Frontmatter snippets - -Astro Cactus includes a helpful VSCode snippet which creates a frontmatter 'stub' for posts and note's, found here -> `.vscode/post.code-snippets`. Start typing the word `frontmatter` on your newly created .md(x) file to trigger it. Visual Studio Code snippets appear in IntelliSense via (⌃Space) on mac, (Ctrl+Space) on windows. - -## Pagefind search - -This integration brings a static search feature for searching blog posts and notes. In its current form, pagefind only works once the site has been built. This theme adds a postbuild script that should be run after Astro has built the site. You can preview locally by running both build && postbuild. - -Search results only includes pages from posts and notes. If you would like to include other/all your pages, remove/re-locate the attribute `data-pagefind-body` to the article tag found in `src/layouts/BlogPost.astro` and `src/components/note/Note.astro`. - -It also allows you to filter posts by tags added in the frontmatter of blog posts. If you would rather remove this, remove the data attribute `data-pagefind-filter="tag"` from the link in `src/components/blog/Masthead.astro`. - -If you would rather not include this integration, simply remove the component `src/components/Search.astro`, and uninstall both `@pagefind/default-ui` & `pagefind` from package.json. You will also need to remove the postbuild script from here as well. - -You can reduce the initial css payload of your css, [as demonstrated here](https://github.com/chrismwilliams/astro-theme-cactus/pull/145#issue-1943779868), by lazy loading the web components styles. - -## Analytics - -You may want to track the number of visitors you receive to your blog/website in order to understand trends and popular posts/pages you've created. There are a number of providers out there one could use, including web hosts such as [vercel](https://vercel.com/analytics), [netlify](https://www.netlify.com/products/analytics/), and [cloudflare](https://www.cloudflare.com/web-analytics/). - -This theme/template doesn't include a specific solution due to there being a number of use cases and/or options which some people may or may not use. - -You may be asked to included a snippet inside the **HEAD** tag of your website when setting it up, which can be found in `src/layouts/Base.astro`. Alternatively, you can add the snippet in `src/components/BaseHead.astro`. +Replace `public/avatar.png` (header logo) and `public/social-card.png` (default OG image) with your own. ## Deploy -For guidence, the [Astro docs](https://docs.astro.build/en/guides/deploy/) has a great breakdown of how to deploy your own Astro site on various platforms and their idiosyncrasies. - -By default, the theme prerenders all pages and endpoints, with the [`'static'` output](https://docs.astro.build/en/reference/configuration-reference/#output), and the [`'./dist'`](https://docs.astro.build/en/reference/configuration-reference/#outdir) output directory. - -You do not need to add any adapter to use this theme. - -### Cloudflare Workers - -If deploying via Cloudflare Workers, you may have [issues](https://github.com/chrismwilliams/astro-theme-cactus/issues/454) with regards to the OG image endpoints and it requiring a Node environment. To solve this, you will need to add a [Wrangler configuration file](https://developers.cloudflare.com/workers/framework-guides/web-apps/astro/#if-you-have-a-static-site) for a static build. - -```jsonc -{ - "name": "astro-cactus", - // Set this to today's date - "compatibility_date": "2026-05-11", - "assets": { - "directory": "./dist", - "not_found_handling": "404-page" - } -} -``` - -If you are intending to use the [Clouflare adapter](https://docs.astro.build/en/guides/integrations-guide/cloudflare/), please set the [`prerenderEnvironment`](https://docs.astro.build/en/guides/integrations-guide/cloudflare/#prerenderenvironment) to `'node'`, and follow the [Cloudflare docs](https://developers.cloudflare.com/workers/framework-guides/web-apps/astro/#if-your-site-uses-on-demand-rendering). - -> Please note the `nodejs_compat` flag, and the main entry point which is incorrect on Cloudflare's docs at the time of writing. - -```jsonc -{ - "name": "astro-cactus", - "main": "@astrojs/cloudflare/entrypoints/server", - // Set this to today's date - "compatibility_date": "2026-05-11", - "compatibility_flags": ["global_fetch_strictly_public", "nodejs_compat"], - "assets": { - "binding": "ASSETS", - "directory": "./dist", - "not_found_handling": "404-page" - }, - "observability": { - "enabled": true - } -} -``` - - +Static output, so it builds to `./dist/` with no adapter. See the [Astro deploy guides](https://docs.astro.build/en/guides/deploy/). For Cloudflare Workers, point the assets directory at `./dist` with a static [Wrangler config](https://developers.cloudflare.com/workers/framework-guides/web-apps/astro/). ## Acknowledgment -This theme was inspired by [Hexo Theme Cactus](https://github.com/probberechts/hexo-theme-cactus) +Built on the [Astro Cactus](https://github.com/chrismwilliams/astro-theme-cactus) theme by Chris Williams. ## License