Rebuilding with Astro and Umbraco 13
Apr 3, 2024
After seeing a couple of great Astro talks (thank you to Peter Singh and Rick Butterfield) I felt like it might be time to get out of my stack, stretch my legs, and take a walk through the rich tech landscape. I quickly remembered how diverse the world of JavaScript frameworks is - as a full-stack developer who is very comfortable with .NET/Umbraco/Azure and React, it’s easy to forget.
In all the excitement I nearly went with Meteor JS, a full-stack framework that leans heavily on Mongo DB for real-time UI, having had a brief love affair with Mongo in 2017. In the end though, I went full circle and chose Astro.
Why Astro?
Astro is a relatively new JavaScript framework for building content-driven websites - it’s static-first but can be used for dynamic sites too. You might have also heard that it’s front-end framework agnostic, so you can use React, Vue or any other framework, which is always good. You can even use them all at once, if you like (but why would you do that?).
The allure of Astro, for me, is three-fold:
-
Static sites are cheaper to host, which is both a financial and sustainability benefit (less CO2e - Carbon-Dioxide Equivalent emissions - per page view)
-
Decoupling the site rendering from the CMS has benefits to maintainability and development process.
-
The promise of a static-first framework that allows a hybrid approach - islands of dynamic content supported by serverless code - seems very promising. Even if I don’t use Astro in production, I feel there are useful lessons to be gleaned from the framework's novel approach.
Why rebuild?
To get a bit of hands-on experience with Astro I decided to rebuild my personal website with Astro and use the Umbraco Content API to power it.
I built my website just before xStatic (the Umbraco static site generator) released a version for Umbraco 9, so my website still uses Umbraco 8. This seemed like a great excuse to rebuild the site and have a go with Astro.
Looking for a guide?
There are already some fantastic guides to using Umbraco with Astro, so I chose not to include detailed instructions here. Instead, this article aims to provide insight into the experience of rebuilding an Umbraco site in Astro.
For more instructive material, have a look at:
What I learnt rebuilding in Astro
The Astro app probably has its own structure
There are two ways to build web apps (React, Vue, Astro) or any other decoupled front-end on top of a CMS:
-
Build it with it’s own page structure/routing and just use the CMS content as a kind of reference or repository of content
-
Build a totally dynamic page structure that exactly mirrors the CMS structure
In my experience we’ve usually gone for approach #1: the headless CMS just provides the content and the app structure is embodied in the Astro app. This approach has always served me well but probably falls apart in larger content sites. I think I'm letting my web app/tool developer experience show through. If you have a preferred approach let me know!
Here’s my Astro page structure:
Figure 1: Astro page structure. You may notice that Astro routing is done using folder and filenames!
In this example, the blog listing (the blog folder index.html) grabs the blog page and blog posts from our content repository (Umbraco) and uses them to build the page. The major flaw here is that there is no way to have another blog listing page in the app!
I can’t think of a reason why you couldn’t do a totally dynamic Astro site that routes based on the Umbraco path and chooses page layouts based on the content type, but it would be getting further away from how Astro works out of the box.
Astro == JSX
Since Astro is so simple, rebuilding a static site in Astro is a bit of routing, then rewriting your templates in JSX. Any prior experience with JSX (i.e. with React) will go a long way. In fact, JSX might be at the heart of the question of whether or not Astro is a good fit for a team.
Assuming you’ve already decided to build a static site, choosing between Astro and Umbraco for rendering probably comes down to the following:
-
Will introducing a JavaScript rendering framework help or hinder your team's workflow?
-
Do you prefer JSX or Razor?
-
Is decoupling a requirement?
I would like to hold up my hand now and say: I don't really like Razor as a templating engine. Partials and components in particular are very clunky by modern standards. Edit: I'm reliably informed that this is not a hot-take and that no one likes Razor.
Your development workflow
I have a theory that the outcome of moving your rendering to JavaScript with Astro could depend on your development workflow/skills distribution.
-
If your team is “full-stack” but on average less comfortable with JavaScript and things like TypeScript, moving to Astro might prove a hindrance. There’s nothing wrong with rendering in Razor!
-
If your team is split along a front-end/back-end divide then Astro could be a boon for a few main reasons:
-
The FE team are usually most comfortable with modern JavaScript, the associated build processes and maybe even JSX.
-
Decoupling a UI will have significant benefits in terms of allowing the FE team to work in isolation and maintain their work without getting embroiled in running an Umbraco back-end.
-
The FE team may already be well positioned to take advantage of Astro’s excellent island architecture and hybrid rendering mode.
Conclusion
I enjoyed working with Astro and I would use it in production. I will probably advocate for use of Astro, particularly on static sites and especially when decoupling the UI is desirable.
I was sceptical at first but Astro is so simple and substituting it for Razor rendering is mostly effortless (assuming the right prerequisite skills) and in some ways feels more natural than using xStatic to use Umbraco to generate static sites.
I can’t give a complete answer until I have used the hybrid features in anger but for purely static sites it’s an easy sell. I look forward to using Astro in future projects.
Appendix
A love-letter to uSync
I just want to say that upgrading from Umbraco 8 (in this case) was incredibly straight-forward:
-
I did a clean export from uSync 8 (latest).
-
Copied the uSync folder to my fresh Umbraco 13 project.
-
Renamed the “uSync/v8” folder to “v9”.
-
Imported settings and content.
-
Everything worked! 🤯
I realise this is a very simple Umbraco 8 site but I’m still thrilled that the upgrade took me 10 minutes (I ❤️ uSync).
Caveats
A quick word on some omissions/oddities in my Astro rebuild:
-
Only static: I haven’t yet explored Astro’s hybrid features, so can’t yet comment on those (this is next on my list!).
-
All local: My Umbraco 13 website and database were only used locally, which wouldn’t be very helpful for editors!
-
No CI/CD integration: I didn’t explore building Astro in CI/CD, there just wasn’t any need and it seems like it would be mostly trivial.
-
No fancy deployment: I nearly used netlify-cli for deployment but instead I just built the Astro dist folder locally and literally dragged and dropped it into Netlify.
Thanks for reading!
If you'd like to talk about anything in this post, give me a shout on the Umbraco Discord, Mastadon or other means.