Astro
Overview
Section titled OverviewFrom their site:
Astro is the web framework for building content-driven websites like blogs, marketing, and e-commerce.
Note that “content-driven” is as opposed to a web application, e.g. social networks, TODO lists, dashboards, etc (reference). It’s not that Astro can’t make non-content-driven sites, it just apparently makes some trade-offs so that the focus is for content-driven sites.
Other frameworks might use a single-page app (SPA) approach, but Astro uses a multi-page-app (MPA) approach.
Astro uses a new front-end architecture called “islands”. An island refers to any interactive UI component (as opposed to static UI) on the page (reference). Islands are marked by the use of client:*
directives (reference, all client directives). In other words, they’re components that require scripting to work, and the directives tell Astro when to send the JavaScript to the client.
Getting started
Section titled Getting started- Just follow the tutorial
- Note: if you already know Astro and just want to add it to a new project, start with this page (I use this command, which even creates
package.json
:pnpm create astro@latest -- --template with-tailwindcss
). The target directory needs to be empty. - Maybe install the VSCode extension before that if you want
- Note: if you already know Astro and just want to add it to a new project, start with this page (I use this command, which even creates
- Starting a project based on a template (reference)
- A template is basically just any folder or repo that follows the Astro folder/naming conventions. The official list is here. You can easily create a project from an official template with
pnpm create astro@latest -- --template TEMPLATE_NAME
(whereTEMPLATE_NAME
is something likewith-tailwindcss
).
- A template is basically just any folder or repo that follows the Astro folder/naming conventions. The official list is here. You can easily create a project from an official template with
- Folder structure (reference)
- The reference link is good, so I’ll just highlight some things here
/
- Config files (like
astro.config.mjs
,tsconfig.json
,package.json
) public
- Assets like
favicon.svg
, fonts, etc. e.g. for use fromastro
files
- Assets like
src
components
,layouts
,pages
,styles
, etc.lib
orlibs
: this isn’t an “official” convention, but it’s commonly the location for any TypeScript you need, e.g. for API endpoints.
- Config files (like
Quick reference
Section titled Quick reference- Change the port that Astro listens on
- Modify
astro.config.mjs
:
- Modify
Basics
Section titled BasicsExample using variables, conditional rendering, and a .map
call:
Specifying types for Astro.props
:
Slots (reference) are how you pass children to different components:
Passing variables from frontmatter to a <script>
tag
Section titled Passing variables from frontmatter to a <script> tagThere are two ways to do this:
- Use
data-*
attributes (reference).- If you don’t want to define a custom element, then you could do something like this:
- Use
define:vars
(reference)- (I don’t recommend using this over
data-*
attributes) - Use of
define:vars
implies the use ofis:inline
, so you may hit this issue.- Also, if you’re going to use
define:vars
, don’t import scripts fromnpm
since that code won’t be bundled.
- Also, if you’re going to use
- (I don’t recommend using this over
- Could also use a UI framework like React and pass the commands as props to the framework itself
Using Preact, React, etc.
Section titled Using Preact, React, etc.There’s no reason not to use these UI frameworks, but if all you really need is a click handler, you can accomplish this with a custom element (reference).
Content collections (reference)
Section titled Content collections (reference)The tutorial has you create a set of .md
files that represent blog posts. This is a great use for content collections. They’re raw content (typically .md
, .mdx
, .json
, etc.) that can be validated for types, length, and other properties of the data itself using Zod.
This is why you’ll rarely find Astro.glob
calls in production code; collections are used instead.
Server endpoints (reference)
Section titled Server endpoints (reference)Server endpoints, AKA “API routes”, are endpoints that are built when they’re requested. To do this, you need an adapter, which is what tells Astro how to actually do the building (e.g. “use Node” vs. “use Netlify’s serverless functions”).
To use it:
- Write the endpoint itself:
- Add the adapter:
pnpm astro add node
→ follow the instructions that print out- (you can do
pnpm astro add --help
to see all possible adapters) - The node adapter’s documentation is here
- (you can do
- Choose which default you want: on-demand rendering (
output: "server"
) or static rendering (output: "hybrid"
) and modifyastro.config.mjs
with that option.
Static file endpoints (reference)
Section titled Static file endpoints (reference)You can generate a file at build time by naming a file pages/FILE.EXT.ts
, where the .ts
is going to be stripped from the URL that a user needs to type. E.g.:
This recipe is very straightforward and easy to understand. Everything takes place in just a single file. Make sure that you have server-side rendering enabled.
Ignoring eslint
warnings/errors
Section titled Ignoring eslint warnings/errorsMake the comment like this:
The <!--
-style comments will be emitted into the client-side HTML.
Rather than using the define-vars
directive as discussed in the tutorial, it’s more common to just use CSS variables directly. The define-vars
bit is really pulling values from JavaScript that isn’t ever sent to the client.
Example CSS:
View transitions
Section titled View transitions- Demo site: https://events-3bg.pages.dev/
Lucia
Section titled LuciaNote that this should probably be separated into its own note if this gets big enough.
- Lucia is an authentication library for TypeScript. It aims to abstract away the complexity of authentication.
- It’s pronunced “loo-shya” (it says at the bottom of this page
- Note that v3 is very different from v2. v2 is now old news.
What I did to use Lucia
Section titled What I did to use Lucia- Follow this guide for Astro
- Install stuff
pnpm install lucia@beta oslo
pnpm install @lucia-auth/adapter-postgresql@beta
pnpm install pg @types/pg
- Make a database
pgcli foo -p 5432 -h localhost -u postgres
create database learning_lucia
- Create schemas
- Just copy/paste these (you may need to do them one at a time)
Troubleshooting
Section titled TroubleshootingVSCode doesn’t autocomplete as you’d expect
Section titled VSCode doesn’t autocomplete as you’d expectAssuming you have the VSCode extension, this is typically just a result of needing to restart the extension host (which you can do through the command palette).