• Stars
    star
    101
  • Rank 338,166 (Top 7 %)
  • Language
  • Created about 8 years ago
  • Updated almost 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A list of all things to consider when making a website or webapp of quality.

Guidelines to create a strong website

Here you'll find out all the things I could think of and find out, to create a "good" website.

From security, to performance, social sharing, analytics etc. I'm trying to not forget anything. This is not about which framework to use, but about everything that makes a "good" website in general: secured, performant, social compliant, SEO compliant, offline ready, and more.

This list is growing over time.

You know more ?

Don't hesitate to PR! Let's try to be concise: other resources on the web go further in details for each topic, let's keep them one-liner here with a sample code when necessary.

Be strong

Summary

Care about security ?

  • Use HTTPS (add a letsencrypt certificate, renew every 3 months automatically)
  • Add all security headers
    • get A+ on https://securityheaders.io/
    • Content-Security-Policy: define which hosts are allowed for the browser to download/send from/to (scripts, styles, images, iframes, forms..). Content-Security-Policy: script-src 'self' https://apis.google.com; img-src 'self'. All details here https://www.html5rocks.com/en/tutorials/security/content-security-policy/. A very interesting piece to read: https://hackernoon.com/im-harvesting-credit-card-numbers-and-passwords-from-your-site-here-s-how-9a8cb347c5b5 (look for "Content Security Policy") about CSP tricks and escapes.
    • Content-Security-Policy-Report-Only: when migrating an existing website to CSP, use this first just to get reports on CSP violations (the browser will still acts normal)
    • X-Webkit-CSP (old Chrome)
    • X-Content-Security-Policy: IE10, FF<24)
    • Public-Key-Pins: ensure the webclient has the right public keys, to avoid MITM attacks public-key-pins-report-only:max-age=500; pin-sha256="WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18="; report-uri="http://example.com/hpkp/"
    • Public-Key-Pins-Report-Only: Same as CSP-RO. At first, add this one to see if you get any error. Facebook is using this one for instance.
    • Strict-Transport-Security: specify to the browser to use only HTTPS for a period of time. The browser will automatically use https if it got the header before. Strict-Transport-Security: max-age=63072000; includeSubDomains; preload (2 years), and add it to the preload list of Chrome https://hstspreload.appspot.com and figure inside Chromium's source: https://cs.chromium.org/chromium/src/net/http/transport_security_state_static.json
    • X-Content-Type-Options: do not rely on files MIME types. (a .txt containing some .js, and there are even some exploits that insert JS into MIME-types!) X-Content-Type-Options: nosniff
    • X-Frame-Options: avoid your website to be embedded into an iframe, to just allow for same domain. X-Frame-Options: deny. For a finer control, CSP exist.
    • X-XSS-Protection: enable by default, the browser does not execute a js if it finds the same in the querystring. As CSP, a report url option exists: X-XSS-Protection: 1; report=http://www.company.com/report
    • X-Download-Options: IE8
    • X-Permitted-Cross-Domain-Policies: Restrict Adobe Flash Player's and Reader's access to data. X-Permitted-Cross-Domain-Policies: none
    • Access-Control-Allow-Origin: Known as CORS. Control how a HTTP request is handled (accepted or rejected) if it's coming from another domain. Generally, an API adds the host(s) serving the UI in this header (only if on different domain ofc). Never use Access-Control-Allow-Origin: * except if you are reckless or don't care. Lots of details: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
    • Timing-Allow-Origin: prevent browsers to access timing information through PerformanceResourceTiming (window.performance) for privacy reasons: Timing-Allow-Origin: (no value)
    • Observe CORB impact
    • Add CRI (Subresource Integrity) to your resources https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity
<script src="framework.js"
        integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
        crossorigin="anonymous"></script>

Care about social ?

<meta property="fb:admins" content="USER_ID" />
<meta property="fb:app_id" content="123456789456489" />
  • Twitter Card
<meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="{{ PAGE_NAME }}"/>
<meta name="twitter:description" content="{{ PAGE_DESCRIPTION }}"/>
<meta name="twitter:site" content="{{ TWITTER_WEBSITE_ACCOUNT }}"/>
<meta name="twitter:image" content="{{ PAGE_IMAGE_URL }}" />
<meta name="twitter:creator" content="{{ TWITTER_CREATOR_ACCOUNT }}"/>
<meta name="twitter:domain" content="mon.site.com"/>

Care about SEO ?

  • Use HTTPS
  • Isomorphic/Universal Javascript (prerendering page)
  • Add share & like buttons
  • Take care of the name of your images and alt
  • Add a sitemap.xml
  • Define the crawlers politic. Define the file robots.txt, or you can add a meta:
<meta name="robots" content="index,follow" />
<link type="text/plain" rel="author" href="humans.txt" />
<link rel="alternate" hreflang="es" href="http://es.example.com/" />
  • If your website publishes news:
    • you can use <meta name="news_keywords" content="football, world cup" /> to help Google News to reference you https://support.google.com/news/publisher/answer/68297?hl=en
    • you can use <meta name="syndication-source" content="http://example.com/my_news" /> if you are the original creator of the news, to indicate you are the original source.
    • it exists also a meta original-source to reference the sources you reference in your article

Care about communication ?

<meta property="og:locale" content="{{ LOCALE }}" />
<meta property="og:type" content="article" /> <!-- product... -->
<meta property="og:title" content="{{ PAGE_NAME }}" />
<meta property="og:description" content="{{ PAGE_DESCRIPTION }}" />
<meta property="og:image" content="{{ PAGE_IMAGE_URL }}" />
<meta property="og:url" content="{{ PAGE_CANONICAL_URL }}" />
<meta property="og:site_name" content="{{ APPLICATION_NAME }}" />	
<meta property="og:updated_time" content="2015-05-12T22:24:50+00:00" />
<meta property="article:publisher" content="{{ PUBLISHER }}" />
<meta property="article:author" content="{{ AUTHOR }}" />
<meta property="article:section" content="Technology" />
<meta property="article:published_time" content="2015-01-06T23:07:41+00:00" />
<meta property="article:modified_time" content="2015-05-12T22:24:50+00:00" />
  • Bing
<meta name="geo.placename" content="United States" />
<meta name="geo.position" content="x;x" />
<meta name="geo.region" content="usa" />
<meta name="ICBM" content="x,x" />
  • Define a canonical URL for every page (to avoid to reference twice the same page, for instance the mobile version and the desktop's)
<link rel="canonical" href="article.html">
  • Define it's UTF8
<meta charset="utf-8">
  • Define the content type
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
  • Language
<html lang="en">
<meta http-equiv="Content-Language" content="en">
<meta name="language" content="{{ LANG }}" /><!-- Old -->
  • Provide some info the browsers/crawlers can use to describe your app (if web app)
<meta name="application-name" content="{{ APPLICATION_NAME }}">
<meta name="description" content="{{ PAGE_DESCRIPTION }}">
<meta name="keywords" content="{{ PAGE_KEYWORD }}" />
<link rel="pingback" href="http://www.example.com/xmlrpc.php" />
  • You can put some RSS
<link rel="alternate" type="application/rss+xml" href="http://www.example.com/rss.xml" />
  • Prev/Next pages if you are in a listing
<link rel="prev" title="..." href=".../page/1" />
<link rel="next" title="..." href=".../page/3" />
  • Define the shortlink of the pages
<link rel="shortlink" type="text/html" href="http://example.com/Ad1ca9">
  • Define the sitemap of the website
<link rel="sitemap" type="application/xml" title="Sitemap" href="{{ SITEMAP_URL }}" />
<!-- The classic one; ico or png -->
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico">

<!-- Used by http://fluidapp.com/ (website to native app on Mac) -->
<link rel="fluid-icon" href="fluidicon.png" title="...">

<!-- Apple formats https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/ConfiguringWebApplications/ConfiguringWebApplications.html -->
<link rel="apple-touch-icon" sizes="57x57" href="/apple-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/apple-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="/apple-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png">

<!-- For Safari pinned tabs -->
<link rel="mask-icon" href="logo.svg" color="orange">

<!-- Recommanded is 192x192 only -->
<link rel="icon" type="image/png" sizes="192x192"  href="/icon-192x192.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">

<!-- Not sure if still used. App should used it if og:image is unspecified, to display an image when sharing -->
<link rel="image_src" href="{{ PAGE_IMAGE_URL }}">

<!-- Windows -->
<meta name="msapplication-TileColor" content="#ffffff">
<meta name="msapplication-TileImage" content="/ms-icon-144x144.png">
<meta name="theme-color" content="#ffffff">
<link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://www.example.com/xmlrpc.php?rsd" />
  • WindowsLiveWriter
<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="http://www.example.com/wlwmanifest.xml" />
<meta name="msapplication-task" content="name=Example: home;action-uri=http://www.example.com/home;icon-uri=http://www.example.com/favicon.ico">
  • OpenSearch
<link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="...">
<script type="application/ld+json">{"@context":"http:\/\/schema.org","@type":"WebSite","url":"https:\/\/...","name":"...","alternateName":"..."}</script>
<link rel="profile" href="http://gmpg.org/xfn/11" />
<meta name="DC.Format" content="text/html">
<meta name="DC.Language" content="en">
<meta name="DC.Type" content="Text">
<meta name="DC.Title" content="My revolution">
  • Keep URLs short and meaningful
  • Handle page errors (404, etc.) with some links inside, instead of dumping the classic raw default page

Care about Apple ?

<link rel="apple-touch-startup-image" href="/startup.png">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="format-detection" content="telephone=no">

Care about accessibility (a11y) ?

Care about privacy ?

Care about style ?

<meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes, minimal-ui">
  • Avoid FOUC (Flash Of Unstyled Content) and FOIC (Flash Of Invisible Content) https://css-tricks.com/fout-foit-foft/
  • Make it responsive using media queries and other css techniques
  • Talk to a UI and UX designer
  • Avoid to use custom scrollbars plugins. People tends to not like them. There are often used to cancel the style of the ugly scrollbars in Windows unfortunately.
  • Fix the size of elements in the page (images, videos..) to avoid shifting layouts
  • Ensure the color contrast you are using is fine: http://leaverou.github.io/contrast-ratio/

Care about legacy ?

  • Add X-UA-Compatible
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  • If you uses specific features, you can use @supports if css only, or https://modernizr.com/ to detect if a feature is available and can fallback.
  • Add shims
<!--[if lt IE 9]>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>
<![endif]-->
<script type="module" src="main.mjs"></script>
<script nomodule type="javascript" src="fallback.js"></script>

Care about performance ?

  • Test with https://web.dev/measure
  • Use HTTP/2
  • Define a performance budget (overall, js, images, time to interactive, first paint..) and improve it over time (you can't deploy something out of the budget)
  • DNS Prefetch to resolve DNS asap (for future pages)
<link rel="dns-prefetch" href="//fonts.googleapis.com">
<link rel="dns-prefetch" href="//themes.googleusercontent.com">
  • DNS+Handshake+TLS Preconnect. Better. DNS+TCP handshake + optional TLS negotiation. Use for the current page.
<link rel="preconnect" href="//fonts.googleapis.com">  
  • Resource preload (high priority) Download a resource right now (into cache) if we know we'll need it. It supports media queries (for instance, if you want to preload an image that is available in 3 formats, according to the screen max-width)
<link rel="preload" href="image.png" as="image" media="(min-width: 1024px)">
  • Module preload (mjs)
<link rel="modulepreload" href="lib.mjs">
  • Resource Prefetch (low priority). Download a resource (into the cache) when the browser will have time, if we know it's going to be used later.
<link rel="prefetch" href="image.png">
  • Add https://instant.page/ to preload pages when the user hovers a link
  • Subresource (deprecated, not supported anymore): Download directly (high priority, whereas prefetch is low priority) a resource that will be discovered later in the page (such as <script> at the end) Use preload.
<link rel="subresource" href="app.js">
  • Prerender. Fetch the whole content of another page (css, process js etc.). Useful when you know that the user will click on it for sure. It will take only a instant (everything will be already loaded!)
<link rel="prerender" href="http://example.com/about">
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Open+Sans:300">
  • Better, don't use <link rel="stylesheet" ..>, it's a blocking resource download. Try to inline into <style>.
  • For classic js third party libraries, use a cdn (unpkg, cdnjs, jsdelivr, maxcdn..)
  • Use a generic CDN for your resources like Cloudflare
  • If you don't want an external CDN, install a "HTTP Web Accelerator" like Varnish to cache static resources server side and serve them faster
  • Use rel="noopener" for external links: <a href="http://example.com" target="_blank" rel="noopener">
  • Check your performances with https://testmysite.io/
  • Check your performances and best practices with Lighthouse: https://github.com/GoogleChrome/lighthouse GitHub stars (test if you app can be considered as "progressive")
  • Analyze what changes in the DOM with Chrome extensions such as DOMListener and http://google.github.io/tracing-framework/ if you want the best!
  • Evaluate your bloat score http://www.webbloatscore.com/
  • Async image processing to get better responsiveness <img decoding=async src="..."> (proposal)
  • Load lazily your resources
// js modules here (or dynamic imports, à la webpack)
const module = await import('more.mjs')
module.something()

Care about mobile ?

<link rel="manifest" href="/manifest.json">
{
	"name": "example.com",
	"short_name": "EXX",
	"start_url": "/",
	"display": "standalone",
	"background_color": "#fff",
	"theme_color": "#0379C4",
	"description": "The official website and documentation for ...",
	"icons": [ { } ]
}

Care about offline ?

Care about analytics ?

  • Google Webmaster
<meta name="google-site-verification" content="xyz">
<script>
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
ga('create', 'UA-XXXXX-Y', 'auto');
ga('send', 'pageview');
</script>
<script async src='https://www.google-analytics.com/analytics.js'></script>  

Care about bugs ?

Care about misc ?

<meta name="google" value="notranslate">  

More tips

https://developers.google.com/speed/docs/insights/rules https://www.awesomeweb.com/blog/make-website-awesome

More Repositories

1

every-single-day-i-tldr

A daily digest of the articles or videos I've found interesting, that I want to share with you.
307
star
2

akka-streams-summary

Trying to put together some notes I took about Akka-streams and reactive-streams
Scala
40
star
3

checklists

All checklists
26
star
4

react-stack-step-by-step

A tentative to explain a full technical stack using Reactjs, step by step, in-depth. I've never finished. _o_
25
star
5

acorn-jsx-walk

JSX support for Acorn Walk
JavaScript
21
star
6

react-line

Provide a React component to draw a line
JavaScript
17
star
7

react-motion-fun

Just having fun with react-motion
14
star
8

curated-system-tools

A list of tools and commands to know what's going on in the system
14
star
9

kafka-streams-consumer-offsets-to-json

A Kafka Streams process to convert __consumer_offsets to a JSON-readable topic
Scala
13
star
10

seo-boilerplate

Recap of all what can be found in <head> for a good SEO
HTML
13
star
11

parquet-custom-reader-writer

Simple implementation of a custom parquet reader/writer
Scala
11
star
12

fisheye

Fisheye algorithm
JavaScript
10
star
13

how-i-stay-updated

All the things I subscribed to or that I often check and read to stay up to date.
9
star
14

ultra-slim-play-scala

Play Framework application reduced to a strict minimum
Scala
8
star
15

javascript-en-francais

Il est temps de coder en français !
JavaScript
7
star
16

react-voxel

JavaScript
7
star
17

druid-overview

An in-depth presentation of the timeseries database Druid; ways to ingest data, how to extend it, the tools it provides, and most of its features.
5
star
18

number-converter-alphabet

Convert a number to any base/any custom alphabet
JavaScript
4
star
19

text-ellipsis

Cut off a string if too long
JavaScript
4
star
20

couchbase-bucket-listener

Listen to a Couchbase Bucket in real-time
Scala
3
star
21

twitter-dealabs-hot

Bot that powers @hotdealabs
JavaScript
3
star
22

kafka-better-cli

A better kafka command line
Rust
3
star
23

kafka-streams-kotlin

Sample Kafka Streams in Kotlin
Kotlin
3
star
24

react-ascii-loader

A simple ASCII loader
JavaScript
3
star
25

functional-sagas

Enjoying Sagas in a functional way
Scala
2
star
26

scala-api-boilerplate

My boilerplate to start working on APIs quickly
Scala
2
star
27

avro-parquet-reader-writer

Scala
2
star
28

algo-kmeans

Simple implementation of the k-means clustering algorithm
JavaScript
2
star
29

chtree

Walks through a directory and prints out a treeview of its content
JavaScript
2
star
30

react-polyline

Provide a React component to draw a polyline.
JavaScript
2
star
31

kotlin-gradle-karate-tests

Boilerplate using kotlin + gradle + karate to test
Kotlin
2
star
32

one-liner

Transform a string to a one line string by converting and merging line breaks/carriages, tabs, spaces
JavaScript
2
star
33

real-time-apps-example

1
star
34

monads-training-ground

Quiet please. Practising here.
Scala
1
star
35

whitespace-parser

An implementation of a Whitespace parser relying only on the State monad
Scala
1
star
36

download-dynamic

Download the content from a url containing dynamic parts
JavaScript
1
star
37

download-collection

Download the content from a list of urls automatically
JavaScript
1
star
38

jmxtrans-docker

Send JMX stats to a backend such as Graphite using JMXTrans in a container
1
star