Implementing a Static Approach
In the previous part, we looked at why a static approach often makes sense. The next step is practical:
How do you actually build it?
There are many ways to do this today. The important part is not the tool itself, but the properties it gives you:
- Pre-rendered HTML
- Minimal runtime requirements
- The ability to add interactivity when needed
One way to do it: SvelteKit
In this series, we use SvelteKit as an example. Not because it is the only option, but because it gives us a clean way to work with a static-first setup.
With the static adapter, SvelteKit can generate a fully static site at build time.
We just install the static adapter:
npm install @sveltejs/adapter-static And in our svelte config file, we configure it:
// svelte.config.{js,ts}
import adapter from '@sveltejs/adapter-static';
export default {
kit: {
adapter: adapter()
}
}; This results in:
- Pre-rendered pages
- Static HTML output
- No required server in production
Exactly the characteristics we are aiming for.
Other tools can do the same
SvelteKit is just one option. The same approach can be achieved with other tools:
- Static export in React-based frameworks
- Solutions like Fresh or Astro
- Traditional static site generators
The choice of tool matters less than the outcome. What matters is that the final result is fast to load, simple to deploy and easy to reason about.
Static First, Not Static Only
As mentioned in Part 6, even in a static setup, you can still introduce dynamic behavior.
The most obvious example is fetching data from an API (For example, a careers page can stay static while job listings are fetched dynamically.):
export async function load({ fetch }) {
const res = await fetch('https://api.example.com/jobs');
const data = await res.json();
return { data };
} This allows you to keep a static structure with dynamic data where needed without turning the entire site into a client-heavy application.
What this looks like in practice
In many projects, a static-first setup ends up looking something like this:
- Pages are pre-rendered at build time
- Content is written in Markdown or fetched from a CMS
- Layout and structure are fully static
- Small dynamic features are layered on top where needed
For example:
- A blog where posts are generated as static pages
- A company site where content rarely changes
- A careers page that fetches open positions from an API
The important part is that the core experience does not depend on JavaScript. If something fails to load, the page still works. Dynamic behavior improves the experience, but it is not required for it.
Summary
A static-first approach is not about limiting what you can build. It is about establishing a stable foundation.
By starting with pre-rendered HTML and layering in dynamic behavior only where it adds real value, you get a system that is:
- Fast by default
- Resilient when things fail
- Easier to maintain over time
And we know, it’s easy to get caught up in tools and frameworks. But the core idea is simple:
Start with static. Add complexity only when needed.
Up Next
So far, we’ve focused on structure and behavior.
Next, we step into one of the most misused parts of modern websites. It’s one of those areas where, done right, it brings clarity and flow. But done wrong, it slows everything down.
Animations
This is part of our “Building a Modern Website” series where we share how we approach software development, architecture and frontend engineering. If you’re building something similar, we also work as software development consultants. Check our Services for more details.
