tldr; In this post, I provide an overview of how my website came into this world and how it grew into the Astro beast it is today. I touch briefly on some web frameworks and concepts I learned along the way using language that (I hope) is beginner friendly. To wrap up, I list some plans coming down the pipeline for my site.
For a bit of context, I started web designing about two years ago with a background in neuroscience. As an academic neuroscientist, I gained coding experience through data science (using R and Python) and built a few data visualization apps. I’d also dabbled in web scraping and building backends using Flask. But prior to building my first website, I had only a cursory understanding of HTML, CSS, and web principles more generally.
In short, I had a fairly solid foundation as a programmer, but absolutely no clue when it came to DNS or responsive design.
My intuition back then was that web design would be a big hit with my brain because it merged coding with artistic flair, a source of creative vitality that I felt was missing from my day-to-day as a scientist. Hunch in hand, I jumped into web design with an open mind.
My old portfolio site was the first website I built from scratch (it also got me my first web design job!) When the site launched, it ran on HTML, CSS, and Bootstrap. Plain, simple, performant. I hosted it directly from a GitHub repo via GitHub Pages, and attached it to my custom domain, samifriedrich.com.
The focus of this first project was to get comfortable writing HTML and CSS, plus a little Bootstrap to make my layouts responsive. Two years later, I still think this is a fantastic beginner website stack. It taught me the basics of both building and hosting a responsive website, all neatly contained within the GitVerse (always a plus to have version control baked in!)
Having successfully launched my first site, I was ready to level up by learning tools that would make expanding and updating my site easier.
Sprinkled across the learning resources I’d used to build my first site were several mentions of static site generators (SSGs). People in the frontend community seemed really excited about them and on the surface they sounded like a logical next step to making my website easier to work with. SSGs also seemed more appropriate for my site and more beginner friendly than, say, jumping into a Javascript framework like React.
After weighing my options, I decided to rebuild my site using the SSG Jekyll. Jekyll has been around for a long time and has stood the test of time for good reason. It may not be the most powerful SSG, but it’s very approachable, hella stable, and the default engine behind GitHub Pages. Especially considering I was starting with no concept of templates or components or build processes, the Jekyll documentation provided a clear and pleasurable learning experience.
Restructuring my site for Jekyll introduced me to two related core concepts in web design: modularity and templating.
Jekyll allowed me to break up the HTML of my site into smaller HTML files, which Jekyll calls “includes”. Following common patterns from the Jekyll docs, I carved up the navigation, footer, and various content sections into separate HTML files. Because my site was initially written as one long HTML file, this made finding and updating content much easier. This also put me in a better position to add pages to my site should I decide to move away from the single-page layout.
In tandem with modularity, I learned to flexibly arrange those modular pieces (“includes”) to create layouts/templates. Jekyll uses the Liquid templating language, of which I learned a tiny bit - just enough to specify the order of my website’s pieces and sections.
Suddenly it was as though each piece of my site had a handle I could drag around. This made rearranging sections trivial, saving me the tediousness of searching through one long HTML file to capture just the right <div>
and then carefully copy-pasting it somewhere else without interrupting the HTML flow.
Despite how simple and linear my use case was, Jekyll planted the first seeds that would soon grow into a wider understanding of reusable components. Eager to dig in more and level up, I turned toward a newer and feature-rich SSG.
I first heard about Astro from the CSS Wizard, Kevin Powell. The two main benefits that sold me on learning Astro over other SSG alternatives were 1) fantastic documentation and 2) unmatched flexibility. With Astro, you can build a barebones HTML + CSS site, or you can throw all your favorite frameworks at it and do things like partial hydration. As someone that loves to have options, Astro was an easy sell.
By the time I got around to revamping my personal website with Astro I had already launched two full-featured SSG websites, one of which I built with Astro. I grew a lot as a developer through those projects. From the CSS side of things, I started working with Sass and implementing design systems to build my own Tailwind-esque utilitly classes. From the hosting side of things, I switched from GitHub Pages to Netlify. From the project architecture side of things, Astro introduced me to several useful concepts, including components, a dedicated data layer, and scoped styling.
It’s worth noting that none of the concepts I discuss here are unique to Astro - I just happened to first encounter and learn them through building with Astro.
Simply put, components are the rearrangable & reusable building blocks (button, footer, navbar, article card, etc.) used to fill in the layout of a webpage. Approaching site architecture through the lens of components was new to me when I picked up Astro. I had brushed up against the idea of components when using Jekyll’s “includes” and Bootstrap, but things solidly clicked once I started building my own Astro components from scratch.
When creating the very first HTML + CSS version of this website, I was copy-pasting and hard coding each repeating component, such as the project cards in the Portfolio section. This approach was tedious and prone to error, because changing, say, the project description from a <div>
to a <p>
required combing through each card’s HTML block for that one specific tag to make the swap.
Components offer a more elegant and efficient approach: for any chunk of HTML I found myself copy-pasting to replicate, I would instead create a generic component that specifies only the shared elements and styles for that chunk. Then the specifics (data) get filled in downstream. As I started engineering components, I found it helpful to think of components as functions - they perform a prescribed set of operations on whatever data is passed to them. In other words, components operate as ‘display functions’, formatting data into a visual output to be rendered by the browser.
Reformulated as a component, the project card becomes a mini template into which the specific data for each project (title, description, image, etc.) are interchangable bits that slot into their respective places. Configured this way, any changes I make to the card component are applied to every instance of that card, saving me the headache of CTRL+F’ing through walls of HTML.
Restructuring sites to use components prompted me to start storing website data or “content” separate from the HTML that dictates how that data gets displayed. Pivoting to this architecture was truly a game-changer and felt analagous to the way I’d learned to code as a data scientist: the data (content) is an independent entity, around which the analysis (website) is built.
The payoff from this separation is a huge gain in flexibility. If a dataset grows or shrinks, the analysis applied can remain constant, just as adding or removing content doesn’t change the styles or layouts that render that content on your site. Similarly, different analyses can be performed on the same dataset, just as different components (or entire websites) can be built from the same data sources.
Astro offers a feature called Content Collections that acts as a local data layer for your website. It’s basically just a directory supercharged with dedicated functions that streamline accessing, filtering, and using those data files within HTML files. For example, Content Collections make it trivial to retrieve an array of blog posts with the tag “travel”, or all personnel entries with the job title “PhD Student”.
I use two common file formats when building Content Collections - Markdown for text documents (like blog posts) and JSON for everything else. For example, the directory for my project data is made up of project JSON files, and each file defines a project title, description, and image path field. These fields are the interchangable bits that I can pass to the project card component (a ‘display function’ for this data) to be slotted into their respecitve places in the rendered page.
The combination of data layers (Content Collections in Astro) and components is a powerful one. Adding a new project to my Portfolio section becomes as simple as adding a JSON file with the required fields. The project card component takes over from there to structure and style the data, and voila - a new project card is born.
Separating data into its own layer also set me up well to integrate a content management system, an absolute necessity when handing over a site to a client who isn’t comfortable editing raw files in order to make changes to their site.
Scoped styling boils down to targeting CSS styles to very specific chunks of HTML. The goal is to keep those styles from “leaking” to other parts of the site. Scoping styles comes in handy when, for example, I want to style headings on project cards with a smaller font than all the other headings on the site.
There are many ways to scope styles. One method that Astro opens up is to simply write a component’s CSS styles in the same file as the component HTML. The styles declared within that file will only be applied to that component, making it possible to style basic elements like a <div>
or a <section>
without creating new classes and without affecting those tags on the rest of the site.
There are several advantages to storing components and their relevant styles together. For one, it simplifies project organization by allowing me to create components and style them within a single file. Packaging up styles with their components means I can quickly find the styles I want to edit, and clearly see where they are being applied within the component. In addition, I can safely override global styles in a component-specific manner.
To avoid frustration, it is important to understand the interplay of import order and specificity when using scoped styling alongside imported stylesheets. I won’t go into the details here, but the Astro Docs are a great starting point.
Building websites with SSGs has done wonders to fill up my developer toolbox and deepen my understanding of the web. The web design concepts discussed above are merely a sprinkling of what I learned working with Jekyll and Astro.
Most of what I learned, I learned by reading the documentation. “Read the docs” is one of the most common pieces of advice I hear developers offer to beginners, but not all documentation is created equal.
Luckily, the Astro Docs are thorough, beginner friendly, and constantly updated. Plus the Astro community is passionate and responsive. In addition to the concepts I already mentioned, the Astro Docs are fertile ground to start learning about other powerful web dev concepts like routing, image optimization, MDX, APIs, and so much more.
I feel excited to keep building when I see how much my site has changed in two short years. If you’d asked me when I first launched my site what direction it would take, I certainly couldn’t have predicted its current form.
I’ve noticed an organic texture to the evolution of the websites I build, with some changes incremental and others major transformations. And I love that unevenness and uncertainty, because there are few things more satisfying to me than surprising myself.
One thing I know is that I’ll stick with Astro to power this site for the forseeable future. Having now spent many hours in Astroland, I can say that Astro exceeds expectations from a developer experience standpoint. And the developers at Astro have lots of great new features planned, so the fun has only just begun.
Going forward, here are some things I’d like to plant in this digital garden:
If you’re curious to see how these plans come together, check back in a couple months.
And if you’re still reading, THANK YOU for making it to the end.