What does a Modern Static Website look like?
Tags: javascript, webdev, webcomponents, vite
Published: 2022-09-25 23:45:40

In this story, I will take you on the journey of how I created a ***special*** static website that one of my friends described by saying,

> “ The Latest and Greatest ! ” 😎

Kinda exaggerating but I like to call it a ***Modern Static Website*** .

![https://cdn-images-1.medium.com/max/800/1*SVIKc00SaXnlFCVW_myLVg.png](https://cdn-images-1.medium.com/max/800/1*SVIKc00SaXnlFCVW_myLVg.png)

Problem statement:

Imagine you are in this frequent situation where you are hired to code a simple 6 pages static website, For an event organized by your colleagues for example, But because you are kind of a nerd! You want your website to be more interesting because static website development is boring!

So what does this **Modern Static Website** look like?

- DRY: replace repeated HTML code with **reusable** UI commponents just like in modern SPAs.
- use modern modular javascript syntax (ESModules)
- Ability to install npm packages and benefit from the rich ecosystem of javascript packages ( in my case I installed **GSAP:** Green Socket Animation Platform, To add some animations and an HTML minifier package )
- HMR: Hot Module Reloading, For a fast and seamless development experience.
- Build optimizations for a performant production website.
- Some serverless backend services like Newsletter and contact forms.
- use utility first classes for styling (like Tailwind Css).

All without compromising on the **simplicity** that static websites are known for.

### Let’s build it! 🧑‍💻

First things first, make sure you have nodejs and npm installed on your machine. Why? Aren’t we building a static website? Yes, but as mentioned before we want to be able to use npm packages on our website.

npm packages require modern javascript syntax like ESModules for import and exports, therefore we need a build tool to bundle our modern javascript modules into files that the browser can understand.

### Say hi to Vitejs ⚡

There are many javascript build tools out there, But what makes vitejs stand out is its blazing speed; Moreover, It is plain simple, just install it and you have it with zero configuration! this will help us conserve the simplicity of our **Modern Static Website!**

⚠️ — I  will install tailwind with vitejs, But this is just a preference you can install vitejs alone. refer to [vitejs docs](https://vitejs.dev/guide/#scaffolding-your-first-vite-project) if you have any issues with installation.

*Terminal: create a vitejs project*

```
npm create vite@latest my-modern-static-website
cd my-modern-static-website
```

*Terminal: install tailwind css*

```
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
```

🔴 make sure you add every page you want tailwind to work-in in the content array.

~ *tailwind.config.js*

```
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "index.html",
    // "edition.html",
    // "partners.html",
    // "team.html",
    // "about.html",
    // "contact.html",
    // "404.html",
     "./src/**/*.{vue,js,ts,jsx,tsx}",
    //"./components/**/*.{vue,js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
```

I left some of the pages that I had in my project commented so that you have an example of how the pages should be added to the file.

🔴 Make sure you associate every entry page on your website with an entry in the *vite.config.js* file like this :

~ *vite.config.js*

```
import { resolve } from 'path'
import { defineConfig } from 'vite'
```

```
export default defineConfig({
  build: {
    rollupOptions: {
      input: {
        main: resolve(__dirname, 'index.html'),
        // team: resolve(__dirname, 'team.html'),
        // edition: resolve(__dirname, 'edition.html'),
        // partners: resolve(__dirname, 'partners.html'),
        // about: resolve(__dirname, 'about.html'),
        // contact: resolve(__dirname, 'contact.html'),
        // 404: resolve(__dirname, '404.html'),
      }
    }
  }
})
```

~ *index.css*

```
@tailwind base;
@tailwind components;
@tailwind utilities;
```

*Terminal*

```
npm run dev
```

now you are ready to start benefiting from the huge ecosystem of npm packages!

personally, I used [GSAP](https://greensock.com/gsap/) to do some cool animations and **[html-minifier-terser](https://www.npmjs.com/package/html-minifier-terser)** to minify HTML code and make the bundle size smaller.

### Other benefits of Vitejs ✨

vitejs also ships with HMR — Hot Module Reloading — by default so you get a seamless development experience with ease, Also vitejs performs many production build optimizations.

now with vitejs we ensured

- modern js syntax compatibility
- npm packages
- speed and performance

All we left to do is **Not Repeating our selves !** this is so frequent in HTML code.

I am a huge fan of UI components like in modern SPAs, But these frameworks are not the right choice for this project because some of them ( React for example) are not SEO friendly and this is a problem  for static websites, Even though some frameworks like Nextjs solved this problem but they still add so much complexity which is not worth it for a 6 pages static website.

**Fortunately,** there is a native way to implement components using only the native Web APIs and we can use them when needed without any dependencies or installs!!

### Web Components 🧩

Web components API is a set of native web APIs that make possible creating custom HTML elements, A.k.a. **components.**

The first component comes in mind when talking about static websites is the header of the website, It’s so annoying to hard-code the header in every page of the website and then imagine if you want to introduce a  small change to it, You have to repeat the change in every page; Therefore, let’s create a custom component for the header !

to stay organized create a new folder call it “components”, Inside this folder create a new javascript file and call it “wc-header.js”.

Then inside the newly created file define a new class that extends the HTMLElement class in order for our component to inherit the properties of a regular HTML element, Then call the parent constructor inside of the constructor like so…

*~components/wc-header.js*

```
class wcHeader extends HTMLElement {
	constructor(){
		super();
	}
}
```

then set the **innerHTML** property to the code of your HTML header as follows …

*~components/wc-header.js*

```
class wcHeader extends HTMLElement {
	constructor(){
		super();
	}
	this.innerHTML = `<h1> My Header </h1>`;
}
```

Last step, define a custom HTML element using the **define** method inside of the **customElement** class.

*~components/wc-header.js*

```
class wcHeader extends HTMLElement {
constructor(){
		super();
	}
	this.innerHTML = `<h1> My Header </h1>`;
}
customElement.define("wc-header",wcHeader);
```

🔴 Make sure you have a dash “-” in the name you give to your custom element, Like in my example “wc-header”.

🔴 You can’t use tailwind inside of web components at the moment, Ihope it will be possible soon, So only use inline css inside your components at the moment .

Our component is READY !

Include the component inside of your HTML and use it like

```
<html>
<head>
<script type="module" src="/components/wc-header.js"></script>
<title> My first web component </header>
</head>
<body>
	<!-- use your component like this -->
	<wc-header>

	<p> it is working !! </p>
</body>
</html>
```

### The newsletter & contact forms 📬

There are plenty of third party services you can use easly in your website without any backend or serverside code.

In my case i used **[Mailer Lite](https://www.mailerlite.com/)** for the newsletter and **[Smart Forms](https://smartforms.dev/)** for the contact form, they both have good free plans.

### Congratulations! 🎉

You now have all the ingredients to build a **Modern static website** !!

But we still need some backend functionality.

That’s it, Thank you for reading !