I've been building Mylo (a more intelligent workout assistant) but contrary to popular advice, I started building the app and completely ignored making a landing page. I should have taken that advice 😔
There are all the usual reasons like letting you build hype and gather email addresses, but the biggest impact I've noticed is how 'real' it makes the project. It's no longer an idea in your head but a landmark that others can see giving them the chance to understand you.
Determined to make a landing page, I decided to learn Nuxt, let me share what I learned to help you make your own page and get amazing scores in Lighthouse.
Setup
Setting up your nuxt project is pretty straightforward, as per nuxt's getting started guide, run this command:
$ npx create-nuxt-app <project-name>
When you go through the setup cli make sure to select 'static' as the target, it's a brand new option in Nuxt that will let you generate a fully static version of your site. This will make it load much faster, and you can benefit from free hosting on most CDNs, like Netlify.
Add the generate command to your package.json:
{
// ...
"scripts": {
// ...
"generate": "nuxt build && nuxt export",
}
// ...
}
$ cd <project-name>
$ npm run dev
After that you're pretty much dealing with standard Vue. I won't go into all the details of Nuxt because you won't need most of them for a simple landing page like this one, but here is a brief primer of what you do need:
Directory structure
Unlike Vue, which essentially dumps you in the desert with nothing but a src
folder, Nuxt leaves you by the oasis 🌴
You're given a few folders to help you get started, here are the ones you will definitely need:
- assets - static assets that you want Nuxt to bundle/transform for you (images, SVG, CSS)
- components - your usual components like buttons, modals, forms, etc.
- layouts - these are also components but they handle full page elements like a header, footer, sidebar, etc.
- pages - each file/folder here will get mapped to a URL of your site
- index.vue -> yoursite.com/
- about.vue -> yoursite.com/about
- blog/welcome.vue -> yoursite.com/blog/welcome
Generally a landing page is rather light in interactivity so you might find yourself writing very little JS, and might not use the other Nuxt features like asyncData
.
If you want to check out the code behind Mylo's homepage, I've open-sourced it here: Github - MyloWebsite
Improving Lighthouse
Making the site itself is only the first step though, we need to make sure performance is great, a slow site doesn't make for a great first impression of your product or service.
So first, go ahead and run a Lighthouse audit to get an idea of where things stand.
These scores aren't all that great, the performance one is downright horrible. But here's where a few changes get me 😎
Performance
The biggest issue I was running into were caused by SVGs.
When it comes to icons I generally prefer to use SVGs over images, they often result in smaller file sizes, can be modified with CSS, and can be resized without any loss of quality.
Now there are many ways to embed them into your site depending on what you need. I needed to be able to modify their color with CSS so I inlined them.
<template functional>
<svg
xmlns="http://www.w3.org/2000/svg"
:width="props.size"
:height="props.size"
viewBox="0 0 16 16"
:aria-labelledby="props.labelledby"
role="presentation"
>
<title lang="en">logo icon</title>
...
</svg>
</template>
This works great for simpler SVGs like the logo. But when I inlined a more complex one (multiple times) it made the DOM huge, filling it with giant SVG tags that the browser had to parse through, giving me that performance score of 13.
The solution then was to embed them in an <img />
tag. This way you avoid adding thousands of DOM elements while still benefiting from caching, but you lose the ability to color them with CSS...
<img :src="require('~/assets/images/sports_icons.svg')" />
Or do you?
Turns out there are a couple of ways to change the color of an SVG even if embedded this way. They involve using combinations of CSS filters to get the color you want.
You can find more information on how to do that in this post:
CSS Tricks - Change SVG fill on hover
But these filters aren't very intuitive to combine into the color you want, luckily I found this codepen which can convert a HEX value into the matching set of CSS filters:
Generate filters for a hex
<img
:src="require('~/assets/images/sports_icons.svg')"
class="fill-green"
/>
.fill-green {
filter: invert(91%) sepia(10%) saturate(1436%) hue-rotate(90deg) brightness(94%) contrast(93%);
}
Accessibility - color contrast
Another issue I had was poor color contrast.
In most design tools you start off by creating a nice color palette which you then tweak to get proper contrast.
What if you could do things the other way around? That's what Leonardo Color does. You set your base color(s) and from there generate additional colors that achieve the contrast ratios you need to pass the WCAG's criteria.
And here is another tool you can use to check contrast between colors: WebAIM Contrast Checker
Conclusion
Making a landing page really is a good first step, it seemed like such a daunting task to me but ended up being much easier to create than my actual project.
Turns out I was just scared of how concrete it would make Mylo feel, because now the whole world can see and criticize it, but in the end, what better way is there to improve?
Let me know what you thought of this post and if you check out Mylo I'd love to hear your feedback!😁
P.S. Here's one more tip
Making the landing page is cool and all but you're likely going to need a way to contact those who sign up, and it looks more professional to have an email address on at a custom domain.
contact@<your-project>.com
Some hosting services offer emails but I use Netlify which doesn't offer this and getting such an address is usually a paid service but I found this guide to set you up for free!
Top comments (1)
As a #builder myself, I incredibly love your article. Currently building those landing pages. Thinking about the aid of AI for the aesthetics