During the winter holidays I always take some time to explore new technologies.
In my previous post I have questioned the utility of static sites generators in 2020. It turns out that static websites are now a big thing and as you can see on Jamstack there are several solutions to create a static website. After spending some hours with cobalt (a static site generator built in rust) I had almost concluded my experiment before stumpling upon Sapper.
According to the website:
“Sapper is a framework for building web applications of all sizes, with a beautiful development experience and flexible filesystem-based routing.
Unlike single-page apps, Sapper doesn’t compromise on SEO, progressive enhancement or the initial load experience — but unlike traditional server-rendered apps, navigation is instantaneous for that app-like feel.”
My adventure started with their tutorial which is pretty straightforward. I soon realised that whilst sapper an export to a static website, is not really working out well for a traditional static stack as it expects JSON data, probably from a headless CMS.
But fear not, I have found a blog template that parses markdown articles. Credits to the author (joshnuss on github) for posting even 2 screencasts on how to deal with it.
I did manage to export a blog as a static website. The technology of Svelte is similar to React and Vue yet is not: it is more akin to language in its own right and the syntax is, in my opinion, way better than the other front end frameworks.
So there seems to be a great community behind the project which is great. This said I run into a number of issues: You can’t use CSS easily (well you can write it under style but forget including a CSS easily and using it to style elements) this for me was a bit of a letdown. But this issue couldn’t win with my enthusiasm for this new technology.
I didn’t give up so I stumbled upon the very cool Carbon Components Svelte from IBM. With a bit of effort (and no prior knowledge of Svelte or Sapper) I did manage to integrate it.
import "carbon-components-svelte/css/g10.css";
import * as sapper from '@sapper/app'
sapper.start({
target: document.querySelector('#sapper')
})
in client.js
<script>
import {
Header,
HeaderNav,
HeaderNavItem,
SideNav,
SideNavItems,
SideNavLink,
SkipToContent,
Content,
Grid,
Row,
Column,
} from "carbon-components-svelte";
let isSideNavOpen = false;
import Notification20 from "carbon-icons-svelte/lib/Notification20";
import UserAvatar20 from "carbon-icons-svelte/lib/UserAvatar20";
import AppSwitcher20 from "carbon-icons-svelte/lib/AppSwitcher20";
import { getContext } from "svelte";
</script>
<Header
persistentHamburgerMenu={true}
company="HTML"
platformName=".DEV"
href="/"
bind:isSideNavOpen
>
<div slot="skip-to-content">
<SkipToContent />
</div>
<HeaderNav>
<HeaderNavItem href="/about" text="About" />
<HeaderNavItem href="/contribute" text="Contribute" />
<HeaderNavItem href="/learnhtml" text="Learn Html" />
</HeaderNav>
</Header>
<SideNav bind:isOpen={isSideNavOpen}>
<SideNavItems>
<SideNavLink href="/about" text="About" />
<SideNavLink href="/contribute" text="Contribute" />
<SideNavLink href="/learnhtml" text="Learn Html" />
</SideNavItems>
</SideNav>
header.svelte notice the svelte syntax
and the posts:
<script>
export let posts
</script>
<style>
ul {
margin: 0;
padding: 0;
}
h1{
font-family: corporate-s, sans-serif;
font-weight: 700;
font-style: normal;
}
/* clearfix */
ul::after {
content: '';
display: block;
clear: both;
}
li {
display: block;
float: left;
}
[aria-current] {
position: relative;
display: inline-block;
}
[aria-current]::after {
position: absolute;
content: '';
width: calc(100% - 1em);
height: 2px;
background-color: rgb(255,62,0);
display: block;
bottom: -1px;
}
a {
text-decoration: none;
padding: 1em 0em;
display: block;
}
figure {
}
img {
margin: 1 1 1em 0;
width: 5%;
height:5%;
max-width: 400px;
margin:0;padding: 0;
padding:10px;
}
</style>
{#each posts as post}
<article>
<a href={`${post.permalink}`}>
<h2>{post.title}</h2>
</a>
<p>{post.summary}...</p>
<p>{post.humandate}</p>
</article>
{/each}
posts.svelte
and the index
<script>
import PostList from '@/components/PostList.svelte'
import rilla from 'images/HTML5.svg';
import {posts} from '@/posts'
</script>
<style>
h1, figure, p {
text-align: center;
margin: 0 auto;
}
figure {
margin: 0 0 1em 0;
}
img {
width: 10%;
max-width: 400px;
margin: 0 0 1em 0;
}
p {
margin: 1em auto;
}
@media (min-width: 480px) {
h1 {
font-size: 4em;
}
}
</style>
<svelte:head>
<title>HTML.Dev</title>
</svelte:head>
<h2> <b> Welcome to HTML.DEVđź‘Ź</b> </h2>
<PostList {posts}/>
Unfortunately the Carbon Components Svelte would add 430K or more of CSS: so once I exported my shiny new test website into a static site I received a 43% score by Google Pagesped insight. This was both weird and surprising because in other websites, where I use bootstrap or in any case failry big CSS files, I never received less than 90% (for a small, simple website like this on).
Styling apart (I am sure that other components like material might work btter): I just don’t see myself writing a post in markdown, build and then upload it on my static hosting. Is just a very tedious workflow vs simply typing your article in a gorgeous online interface, click save and watch it live on your webiste. It is just not convenient and not modern.
Nota bene: Speed benefit of static (via Nginx) or Express was zero. As a matter of fact the Express+DB website was faster than the static sapper website (benchmarked with apache benchmark 10000 requests, 100 concurrent).
Even when trying a more classic generator (like cobalt rs) I have spent a few hours fighing with their variables (not so static after all ?!) so I still think that online CMS are still the way to go. I am also not persuaded at all by these system that create javascript that generates HTML. Clearly many apps can benefit from it but I don’t see how a CMS/blog system would make the pubishing flow better. I still find the concept intriguiding (especially for websites that don’t run many updates) but for now a static website is not for me. 🚄