Part 3: building a high performing static backoffice on AWS with SvelteKit

Depascale Matteo
8 min readMar 15, 2023

--

Build a fast and reliable single page application (SPA) with SvelteKit, deploy it to S3 and serve SPA with Amazon CloudFront 🚀.

⚠️ Hey! This blog post was initially published on my own blog. Check it out from the source: https://cloudnature.net/blog/building-a-high-performing-static-backoffice-on-aws-with-sveltekit--part-3

Figure 1: blog posts list

Introduction

This is the third part of a really long journey, in this series I talk about all the steps you need to do to create your own blog on AWS.

If you didn’t follow the first 2 parts you can find them here:
👉 https://cloudnature.net/blog/blog-series-from-zero-to-hero-part-1-serverless-infrastructure-on-aws-for-blogwebsite
👉 https://cloudnature.net/blog/blog-series-from-zero-to-hero-part-2-serverless-backend-api-on-aws-for-blog-website

We are going to create a SPA which host the backoffice for our blog. We are going to do some changes to our infrastructure and api layer, so I won’t talk only about FE don’t worry 😜.

⚠️Note: I’m not going to explain how the frontend works, I’m sure you guys know it better than me. But you can learn about those topics:
why SvelteKit;
how to create SPA with SvelteKit;
how to deploy SPA to S3 and serve it through Amazon CloudFront;
how to handle authentication and authorization with Amazon Cognito;
🚀 overall performance.

🙏Special thanks to my friend Gianmarco Pettenuzzo for helping me with the frontend, he has done the most of it and it’s cool just because of him. Give him some love ❤️

Requirements

As always we are going to list requirements and analyze them one by one, let’s start.

Only admins can create blog posts

This is a pretty requirements, which means we need authentication and authorization. How can we do it? We are going to use Amazon Cognito to authenticate users and its groups to authorize api access. As per the SPA we are going to use Amplify with SvelteKit because I find it really smart and relieves loads of logic from the frontend.

Alright so we need an authentication page and some logic to get everything work as smooth as possibile, you really don’t want to write a post and then find out it cannot be saved because your token has expired ❌.

Admins must be able to:

📃 list posts
📃 create posts
📃 update posts and images
📃 delete posts
📃 publish posts

To be able to do those actions we need a few pages:

1️⃣ list posts: it should be paginated, every post within the list has 🗑️ delete botton and ✏️ update button;
2️⃣ create posts: it should be easy to create blog posts. We are going to use Quill as a text editor for blog content and a few inputs like title, description, image, ecc.;
3️⃣ update posts: same as create but it also has the ✅ publish botton;
4️⃣ update images: we are going to use S3 presigned url to be safe and sound when admins need to upload images.

Why SvelteKit?

Out there there are a lot of frameworks to work with, I know some of them and I’m sure the blog can be build with every single one of them.

We wanted to try something different and explore a few scenarios no one has explored yet, hoping it will probably help us improve our overall frontend know how. Furthermore SvelteKit is less verbose than other frameworks and I feel like its performance could really satisfy my obsession for speed: it should be ⚡lightning fast⚡. Also one thing it does out of the box is pre-fetching once you go over a link with your mouse, a lovely feature 🥰. I took a snapshot of it, keep reading to find it.

Other than that I need SEO, I need lots of SEO!

Figure 2: no one can get enough SEO.

And this framework does exactly that… out of the box.

But you are building a SPA, why don’t you build a SSR? Really interesting question you got there, the reason is my time to market is tight and my requirements say I need to use AWS which means I would have to create my own infrastructure for supporting SSR in AWS.

⚠️Note: if everything goes as planned in the future you could read a blog post about switching from SPA to SSR. I know the full potential of SvelteKit is when SSR is enabled.

If you want to learn more of SvelteKit here is the starting point https://kit.svelte.dev/, have fun 🎉

Create SPA with SvelteKit

I’m gonna say it! it’s……… really easy. You just need to import an adapter. What are adapters? They are plugins which take the build app as input and generate the adapted output for your deployment target.

SPA means we need to bundle a static website with a single file serving content, to build (better yet: adapt) the app we need to install @sveltejs/adapter-static
Edit svelte.config.js like so:

Perfect but not there quite yet, we need to disable SSR and prerender in src/routes/+page.ts 😩:

To test it out you can run a build and, if everything is right, you should see static adapter being used:

Figure 3: build success.

Deploy SPA to S3 and serve it through Amazon CloudFront

This one is a little bit tricky, right now we have the build and we can deploy it to S3 with this command

aws s3 sync ./build s3://{BUCKET_NAME} --delete
aws cloudfront create-invalidation --distribution-id {DISTRIBUTION_ID}--paths \"/*\"

which deletes previous items, replace them with the new ones and then invalidate CloudFront cache. Aaaaand voilà 🎉🎉

Login page
Figure 4: login page.

🔝 our blog works, let’s go and see all blog posts (if we have any)

Figure 5: all posts page.

Perfect, love to see it. Let’s try to refresh that page…..

Figure 6: Cloudfront error.

Cloudfront search for /blog/index.html but can’t find in S3 because there aren’t any files in that directory 🤯.

To fix this error we need to redirect every 403 status code to /index.html:

Alright time to deploy and wait ⌛. When everything is complete you can test it out going to /blog and, thanks to this fix, it will be redirected to /blog page.

Now that we know our SPA is working we can move on to explain the next step.

Authentication and authorization with Cognito

I wanted to test Amplify with Cognito for SvelteKit, I’ve already wrote an article about it so if you want to read more you can check this post out 👇

With that we have set up Amplify and can use its methods. Which methods we need to set up?

  • currentAuthenticatedUser
  • signIn
  • signOut
  • currentSession: to retrieve current session and the id token of it; moreover if the session expires it tries to get a new session using the refresh token, really useful in my opinion 💪

Meanwhile if you are asking yourself how does it work for the backend then you can find the answer in one of the previous posts 👇

I did also a few upgrades to the backend as well, I got 2 main paths for apis:

  • /admin/posts which contains all administrator apis, which means they need authentication;
  • /posts which contains public apis which don’t need any authentication.

Other than that I had to add a few more indexes to our DynamoDB table because:

  • admins can see every post, from drafted ones to published, meanwhile users can only see published posts; which means we need to use state as primary key (pk) and published at as sort key (sk);
  • admin can select featured posts that can be seen from the homepage; which means we need featured as pk and published at as sk.

Upload images with S3 presigned url

This one is the ace up my sleeve. Using S3 presigned urls we can enable admins to upload files, or better yet images, right where we wanted it to be uploaded because we can define the key and the expiration date for that url.

Figure 7: presigned url flow.

In this diagram we can actually see the flow admins do when uploading the cover image for a particular post. The code? Again it’s just a few lines:

After doing that remember to enable CORS from S3, otherwise S3 bloks your frontend and you are not able to upload images.

SvelteKit pre-fetching

This is just a praise for a really straightforward feature SvelteKit has out of the box, you just have to add one simple line in app.html

<body data-sveltekit-preload-data="hover">

And the result is pure magic 🌈

Figure 8: SvelteKit prefeching example

Conclusion

We had a lot of fun making the website and learning a few things about SvelteKit, I really liked how it turned out and can’t wait to do the customer facing frontend. Now that we have our backoffice ready to create content we just need to build the frontend and improve its performance as much as we can while keeping an eye to our time to market👀.

🙏Huge thanks to Gianmarco Pettenuzzo for helping me out and creating a really reliable website, check him out 🙇.

You can find the project here https://github.com/Depaa/website-blog-part3 😉

This series is literally a journey to production, hence you will see a lot of blog posts, here is a list I’ll try to keep updated:

Thank you so much for reading! 🙏 I will keep posting different AWS architecture from time to time so follow me on Medium ✨ or on LinkedIn 👉 https://www.linkedin.com/in/matteo-depascale/.

--

--

Depascale Matteo
Depascale Matteo

Written by Depascale Matteo

Hi I'm Matteo👋! I’m an AWS Cloud Engineer and AWS Community Builder passionate about Serverless on AWS. Follow me https://www.linkedin.com/in/matteo-depascale/

No responses yet