Published on

Thoughts on Astro

Author

My biggest Astro project went live last Friday, so I thought I'd write a bit about using it. The tl;dr is "astro is pretty okay for making a websight".

I need a way to run the Tailwind build and do some basic includes for layout, common UI components (because tailwind), and make sure my images are vroomvroom fast. Pretty straightforward stuff.

I saw Aria Salvatrice talking about Astro on fedi for her syth stuff and went "oh huh that seems like it might be a good thing to try". So I did for our corporate website.

I'm not looking for SSR, and I haven't needed to use collections yet. You're supposed to use them to set up some routes and have it show people, say, a post from your src/content/blog folder when they go to that post's slug, and it's got some capabilities to generate a list of 'em for your index page.

I know a lot of people like Jekyll or Hugo for this. I've got a slight preference for staying in the nodejs ecosystem with Astro/VuePress because I've already got node installed everywhere.

Project Review

My large Astro project was the website for the Homestuck: Atypical Card Game1. It's not that large in the grand scheme of things, but I am a poor web designer and it took a while to make everything look good.

This has some UI libs (Alpine, simple-datatables and a whole bunch of Astro shenannigans to load/optimize the images for that card DB tables.

Dynamic Thumbnails

The game designer uses something called nanDECK to manage the data/art for the cards. I think she's able to make the cards for TTS through nanDECK, but it can also dump them out as CSVs and a folder of images.

The site is set up so you can drop the CSV/image dump into src/cards and it figures out what to put in the tables and set galleries2.

The CSV files have filenames for cards. I tried to put most of the code for loading the CSVs and are into repositories, but one caveat I slammed into is my src/lib code wasn't allowed to use Astro.glob(). That can only happen in a page file3, so my repo calls end up looking like:

const cards = CardRepository.allCharacter();
const artCollection = ArtRepository.loadAll(await Astro.glob('../../cards/images/*.png'));

Putting the card + art collection together is done by passing the card and the whole art collection to a component. It does something like this (unrolling the code from the libs/etc for demonstration purposes):

import { getImage } from "astro:assets";
import CardNotFound from "../images/card-not-found.svg";

const CardArtResolver = async (card, artCollection) => {
    // Most cards have 1, but planets have 2, so we're using an array to deal with em.
    const pictureField = card.Pictures ?? card.Picture ?? '';
    let cardArt = pictureField.split('//').map((pic) => artCollection[pic.trim()]);

    return await Promise.all(
        cardArt.map(async (art) => {
            if (!art) {
                art = CardNotFound;
            }

            const publicImage = await getImage({src: art});

            return {
                asset: art,
                public: publicImage,
            };
        })
    );
};

const cardArt = await CardArtResolver(card, artCollection);

To display it, and get Astro to generate thumbnails for you, you feed the art into an <Image> tag with height/width set:

{ cardArt.map((image) => <Image src={ image.asset } width="34" height="48" alt="Card {card.TITLE}"/> )}

Markdown and MDX

Astro supports MDX in addition to markdown or their own .astro files (which are HTML with JS frontmatter).

Most of the pages are .astro files, but the rules pages are markdown, because I wanted those to be easier to update. That ended up being a terrible decision, because the figures and advanced rule boxes end up making the whole markdown file look like shit. I don't think it ends up being more maintainable than a .astro file.

My initial thought was MDX made it more difficult to update the text docs, since stuff like unbalanced curly braces would now cause JS errors.

I think I may revisit this decision -- components would be GREAT in here, actually.


  1. I have nothing to do with game design; I just made some websight for it. Please direct all questions about playing the game to somebody who is good at card games. 

  2. Which aren't on there. I have some stuff I was testing for the set page where it'd give you a big gallery view of all the cards, but it was A Lot to behold. I'm not sure exactly what Lucheek wants to put on that page yet, but I made some gallery components that take a query against the card CSVs on the assumption that it will end up having some number of cards there for promo purposes. 

  3. Not sure if that's only in .astro files or files in src/pages