blog Updated

Moving from a self-built Framework to Astro 6.3

Why I moved off my self-built, web-components based framework to Astro 6.3, the SEO problems that forced the switch, and how I brute-forced my translation layer to work again.

  • Framework Transition
  • Migration

This was a long term project. After finishing writing the blog Turning points into 3D clouds I realized that my custom Framework has some problems. Here I will describe how I switched from the self-built framework to Astro, what I had to do to make translation snippets work, and if it was worth switching.

The Good and Bad about the self-built Framework

Firstly the good points from the Framework I used:

  • Everything was raw HTML, fast and easy to read or develop
  • Components are built using the standard browser API
  • JavaScript used the modern Module standard.
  • JavaScript was written as TypeScript, and before the Sparkjs Package it was the only package used in the project.

The bad about the self-built Framework:

  • New Packages needed a complex way to import. I landed on esbuild with custom configuration.
  • Translation was handled via URL Params, not that SEO friendly.
  • Blog Posts needed to copy a lot of boilerplate to be viable.
  • Blog Posts were never translated.
  • Google and Bing could not view the Site correctly, only one Link was discovered.
  • Images stored randomly. (Yes thats on me, I did not plan and use a good folder structure).


There are more points to discuss, but I will stop here for now. My biggest complaint about my self build Framework was, that SEO was realy stupid bad. The page was fast but not discoverable by crawlers. This comes from the way the page used custom elements as components. I thought that I did it correctly, but on Bing Webmaster and Google Console the Websites where never indexed. The only page was Index.html and about-me.html. And the only reason for that was that about-me. was directly linked in the index.html page.

<!--[...]-->
<p class="translation" data-snippet="index.about_me.welcome_second">
    You can see this website as a kind of a resume, or References to stuff I do. If you want to know more about me. Just visit the
    <a href="/about_me.html">about me</a> page.
</p>
<!--[...]-->

And for those who are curious why other pages where not indexed, check this part out:

<!--[...]-->
  <body class="body_gradiant">
    <header>
      <custom-header></custom-header>
    </header>
    <div class="row_hero no_print">
      <div class="row_hero_container">
        <div class="hero_header">
          <h1>Full-Stack Developer</h1>
          <p>at your service.</p>
        </div>
        <div id="hero_typewriter">"Your Idea.", "Our Plan.", "My Work.", "Your Website."</div>
      </div>
    </div>
<!--[...]-->

Did you spot the problem? Yes exactly the <custom-header></custom-header> wont be read from the crawlers. Why? Because it needs javascript to show its real content:

<!--[...]-->
<custom-header>
    <nav class="no_print" itemscope="" itemtype="https://schema.org/SiteNavigationElement">
        <div class="hamburger_el_space"></div>
        <a href="http://me.arthurerlich.de/index.html?lang=de-DE" itemprop="url">
            <span itemprop="name" class="" data-snippet="navigation.home">Start</span>
        </a>
        <a href="http://me.arthurerlich.de/blog/index.html?lang=de-DE" itemprop="url">
            <span itemprop="name" class="" data-snippet="navigation.blog">Blog </span>
        </a>
        <a href="http://me.arthurerlich.de/cv.html?lang=de-DE" itemprop="url"><span itemprop="name" class=""
                data-snippet="navigation.cv">Lebenslauf</span></a><a
            href="http://me.arthurerlich.de/about_me.html?lang=de-DE" itemprop="url"><span itemprop="name" class=""
                data-snippet="navigation.about_me">Über mich</span></a>
    </nav>
</custom-header>
<!--[...]-->

Excactly this is the reason why the google crawler did not find the rest of the links. Its a bit bad. Interesting enough is that the bing bot found 3 Sites. So i had to either rebuild other frameworks or use a different approach. But because of the large copy paste of the header and other components blog posts and other pages where a bit hard to produce new blogs.

I created some API to load a lot of image galary. Really cool and a nice way to learn new stuff. It was build on PHP and was interesting. In reality I hosted the Website on the same server as the cdn. Only reason for the cdn to exist was to easily fetch multiple images.

So my goal was to update the framework or replace it. I wanted to replace it. So what framework to use? In my professional work i do a lot of PHP work. Symfony and Wordpress are some frameworks i work alot with.

And the reason why wordpress was ruled out instantly was the vulnerability problems! Oh my, so many problems. Performance is also a bit slow. If you compare it with plain html.

And thats my reason to use plain html. The Speed! But using only plain HTML, I could also stick with my framework. My goal was to use a static side builder. I heard about Hugo, its a good site builder. But i missed the HTML. And I like to work with HTML.

It took some time to find Astro. And astro fits the hole perfectly. Only the translation was different to my framework. Honestly, i brute forced the translation layer to work

export function createTranslator(locale: string | undefined): Translator {
	const lang = localeMap[locale ?? "en"] ?? EN_LANG;
	const dict = translations[lang] ?? translations[EN_LANG];

	const resolve = (key: TranslationKey): string => {
		const keys = key.split(".");
		let current: unknown = dict;
		for (const k of keys) {
			current = (current as Record<string, unknown>)?.[k];
		}
		return (typeof current === "string" ? current : null) ?? key;
	};

	function t(key: TranslationKey): string {
		return resolve(key);
	}

	t.html = (key: TranslationKey, slots?: Record<string, string>): string => {
		let value = resolve(key);
		if (slots)
			value = value.replaceAll(/\{(\w+)\}/g, (_, k) => slots[k] ?? `{${k}}`);
		return resolveComponents(value);
	};

	return t;
}

I wont go into details on this part. I may explain that feature later. My old framework had json snippets. Similar to the snippets used in Shopware. I reused some of the logic. But most of the logic was self written. Before the age of AI.

There is a lot to do now. I have to fix the Navigation for blog post. It is completly missing. Some blogs have formatting wich is not correct. Blogpost where transformed and updated with the help of AI and custom scripts. That worked to make most of the blog post work. Still needs rework and refaktore

Sources: