Smashing Podcast Episode 27 With Stefan Baumgartner: What Is TypeScript?

We’re talking about TypeScript. What is it, and how can it help us write better JavaScript? I spoke to expert Stefan Baumgartner to find out. Show Notes Stefan’s book TypeScript in 50 Lessons is available now Official site for TypeScript Stefan on Twitter Stefan’s personal website Weekly Update “React Form Validation With Formik And Yup”written…

40+ Best Sketch Templates of 2020

Sketch is a unique app that offers amazing features and functionality for creating app UI designs and mockups. Creating an effective UI for an application requires time, detailed attention, and—most importantly—an idea to get started with! In order to streamline the design process for creating your next app interface, we’ve collected the best Sketch UI templates…

9 Website Design Tips for Different Generations (Yes, It Matters!)

It’s a no-brainer for most designers that you plan a project based on a certain target audience. It might be for people who like soda or buy video games or have an affinity for athletic shoes. But another consideration can often be overlooked – designing for different generational segments. Age can impact how people use…

Top 10 Customer Experience Metrics To Grow Your Business

Data-driven decision-making is more than a buzzword— it’s the key to long-term business success. Using KPIs and performance metrics quantifies the customer experience and provides valuable insights on where to allocate resources and how to make measurable improvements.   If the goal is business growth, customer experience metrics can showcase where the opportunity lies to…

How to Create Your First REST API with Fastify

Fastify is a framework designed for back-end web development. It offers a more lightweight alternative to heavier Node.js API frameworks, such as Hapi and Express. From July 2020, Fastify has released its third version of the framework.This third version comes with improved validation abilities to verify incoming and outgoing requests, as request parameters. Moreover, the third version of the framework consolidates its throughput claims of being the fastest Node.js framework compared with Koa, Resitfy, Hapi, and Express. More information can be found on the benchmarks page.
Fastify has gained a lot of popularity due to its lightweight design. However, a lot of attention goes to its plugin ecosystem. Fastify has adopted the idea that everything is a plugin, whereas with JavaScript, everything is an object. This allows you to quickly encapsulate functionality for your project as a plugin and distribute it so other projects can use your code.
Let’s get started with this tutorial. You’ll learn the following aspects of Fastify:
How to set up your first Fastify API
How to define Fastify API routes
How to add schema validation to requests
How to load and use Fastify plugins
How to define Fastify hooks
Requirements and Installation
To follow this tutorial, you’ll need:
the latest Node.js version
a tool for sending requests, such as cURL or Postman
Next, make sure to create an empty Node.js project. If you don’t have one yet, you can use the following command to set up your project:

npm init -y

Lastly, we want to add this Fastify dependency to our project:

npm i fastify –save

All good? Let’s create our basic API setup in the next step.
Step 1: Basic API Setup
First, let’s create our basic API setup. To get started, we need to create a new file called index.js within our project root:

touch index.js

Next, let’s add the basic server setup. Copy the code below:

const app = require(‘fastify’)({
logger: true
})

app.get(‘/’, function (req, reply) {
reply.send({ hello: ‘world’ })
})

app.listen(3000, (err, address) = > {
if (err) {
app.log.error(err)
process.exit(1)
}
app.log.info(`server listening on ${address}`)
})

There are a couple of things happening here. We first load the Fastify application object and enable logging. Next, we declare a root route that replies with a JSON response. The last part of the code snippet shows that we’re listening on port 3000 for the application to receive requests.
Let’s validate if your basic server setup works. First, we need to start the server by running the index.js file:

node index.js

Thereafter, navigate to http://localhost:3000 in your browser. You should see the following response:

{
“hello”: “world”
}

Success? Let’s go to Step 2 to define different CRUD routes.

Step 2: Define CRUD Routes
An API is useless with only GET routes. Let’s define more routes for handling blogs. Therefore, let’s create the following routes:
GET all blogs at /api/blogs
GET one blog at /api/blogs/:id
POST add blog at /api/blogs
PUT update blog at /api/blogs/:id
DELETE delete blog at /api/blogs/:id
The first thing to do is creating a blog controller.
Step 2.1: Create Blogs Controller
To keep our code clean, let’s define a controller folder in the project root. Here, we create a file called blogs.js.
This file contains some demo data to avoid complicating this tutorial with a database integration. Therefore, we use an array containing blog objects which each contain an ID and title field.

Moreover, we define the different handlers for all the above routes in this file. A handler always accepts a req (request) and reply parameter. The request parameter is useful to access request parameters or request body data.
Add the following code to your /controller/blogs.js file:

let blogs = [
{
id: 1,
title: ‘This is an experiment’
},
{
id: 2,
title: ‘Fastify is pretty cool’
},
{
id: 3,
title: ‘Just another blog, yea!’
}
]

const getAllBlogs = async (req, reply) = > {
return blogs
}

const getBlog = async (req, reply) = > {
const id = Number(req.params.id)
const blog = blogs.find(blog = > blog.id === id)
return blog
}

const addBlog = async (req, reply) = > {
const id = blogs.length + 1
const newBlog = {
id,
title: req.body.title
}

blogs.push(newBlog)
return newBlog
}

const updateBlog = async (req, reply) = > {
const id = Number(req.params.id)
blogs = blogs.map(blog = > {
if (blog.id === id) {
return {
id,
title: req.body.title
}
}
})

return {
id,
title: req.body.title
}
}

const deleteBlog = async (req, reply) = > {
const id = Number(req.params.id)

blogs = blogs.filter(blog = > blog.id !== id)
return { msg: `Blog with ID ${id} is deleted` }
}

module.exports = {
getAllBlogs,
getBlog,
addBlog,
updateBlog,
deleteBlog
}

Note how we can access the request parameter for routes such as /api/blogs/:id via req.params.id. For POST and PUT routes, we can access the body of the request via req.body.
In step 2.2, we’ll connect the route handlers to the route objects.
Step 2.2: Define Blog Routes and Couple Blogs Controller
Again, to keep our code clean, let’s define a routes folder in the project root. Here, we create a file called blogs.js. This file holds the routes object for our blog routes:

mkdir routes
cd routes
touch blogs.js

Luckily, Fastify allows us to define an array containing route objects. Here, we can couple the handlers we’ve defined previously to the different routes. Don’t forget to require the blogs controller. Let’s take a look:

const blogController = require(‘../controller/blogs’);

const routes = [{
method: ‘GET’,
url: ‘/api/blogs’,
handler: blogController.getAllBlogs
},
{
method: ‘GET’,
url: ‘/api/blogs/:id’,
handler: blogController.getBlog
},
{
method: ‘POST’,
url: ‘/api/blogs’,
handler: blogController.addBlog
},
{
method: ‘PUT’,
url: ‘/api/blogs/:id’,
handler: blogController.updateBlog
},
{
method: ‘DELETE’,
url: ‘/api/blogs/:id’,
handler: blogController.deleteBlog
}
]
module.exports = routes

Now we’ve defined all routes. However, Fastify doesn’t know about these routes. The next step shows how you can register routes with your Fastify application object.
Step 2.3: Register Fastify Routes
In this step, we’ll register Fastify routes to the app object. First, we load all the blog routes. Next, we loop over all the routes to register them one by one:

const app = require(‘fastify’)({
logger: true
})

app.get(‘/’, function (req, reply) {
reply.send({ hello: ‘world’ })
})

const blogRoutes = require(‘./routes/blogs’)
blogRoutes.forEach((route, index) = > {
app.route(route)
})

app.listen(3000, (err, address) = > {
if (err) {
app.log.error(err)
process.exit(1)
}
app.log.info(`server listening on ${address}`)
})

Done? It’s time to validate if the blog routes work. Spin up the server using node index.js and visit http://localhost:3000/blogs/1 to get the first blog from the demo data. You should see the following result:

{
“id”: 1,
“title”: “This is an experiment”
}

All good? Let’s learn in Step 3 how to add schema validation to requests and responses.
Step 3: Adding Schema Validation
This step teaches you how to add schema validation to your project. We can make use of the schema key in our routes definition to pass a validation schema to a particular route.
Let’s start with defining a schema for the route /api/blogs/:id to validate the request parameter and response. Requirements?
:id parameter must be of type string
response must contain an object with two properties id (integer) and title (string)
Add the following validation object to your routes/blogs.js file:

const getBlogValidation = {
params: {
id: { type: ‘string’ }
},
response: {
200: {
type: ‘object’,
properties: {
id: { type: ‘integer’ },
title: { type: ‘string’ }
}
}
}
}

To connect the validation object to our route, we have to define the schema key. Look for the /api/blogs/:id route in the routes array and change the object accordingly:


{
method: ‘GET’,
url: ‘/api/blogs/:id’,
schema: getBlogValidation,
handler: blogController.getBlog
},

Let’s do the same for adding a blog POST /api/blogs. Here, we want to verify if the req.body object contains a title parameter. Let’s take a look:

const addBlogValidation = {
body: {
type: ‘object’,
required: [
‘title’
],
properties: {
title: { type: ‘string’ }
}
},
response: {
200: {
type: ‘object’,
properties: {
id: { type: ‘integer’ },
title: { type: ‘string’ }
}
}
}
}

Next, we have to connect the validation object again to the correct route:


{
method: ‘POST’,
url: ‘/api/blogs’,
schema: addBlogValidation,
handler: blogController.addBlog
},

To verify our validation, let’s retrieve the blog with ID 3. Open your browser at http://localhost:3000/api/blogs/3. You should see the following response:

{
“id”: 3,
“title”: “Just another blog, yea!”
}

Now, let’s make a mistake and change the params validation for the id field from sting to object like so:

const getBlogValidation = {
params: {
id: { type: ‘object’ }
},
response: {
200: {
type: ‘object’,
properties: {
id: { type: ‘integer’ },
title: { type: ‘string’ }
}
}
}
}

When requesting the same resource from your API, you’ll receive the following error message.

{
“statusCode”: 400,
“error”: “Bad Request”,
“message”: “params.id should be object”
}

Do you see the error? Good! Let’s revert the change to string to avoid future errors and move to the next step.
Step 4: Load Fastify Plugins
Here, let’s make use of Fastify’s rich plugin ecosystem. You can find plugins that help you with various tasks, such as database integrations or authorization setups. Why would you spend time writing authorization from scratch while you can make use of Fastify plugins? Often, you want to look for packages outside of Fastify’s ecosystem that help you with certain problems or tasks. However, by providing a rich plugin ecosystem, Fastify becomes a one-stop solution that definitely improves the developer experience!
A quick note about plugins: You can create your own plugins to encapsulate functionality. Moreover, you can load those plugins to your Fastify application object. By default, Fastify will first load plugins from the Fastify ecosystem. Afterward, custom plugins are loaded.

Ok, let’s get practical! I would like to use the fastify-env plugin, which helps you with loading environment variables and setting defaults for each variable. Therefore, let’s add this dependency to our project:

npm install –save fastify-env

Next, we can load the dependency after loading the Fastify application object in the index.js file. Your index.js file looks like this:

const app = require(‘fastify’)({
logger: true
})

const fastifyEnv = require(‘fastify-env’)

const options = {
confKey: ‘config’,
schema: {
type: ‘object’,
required: [‘PORT’],
properties: {
PORT: {
type: ‘string’,
default: 1000
}
}
}
}

app
.register(fastifyEnv, options)
.ready((err) = > {
if (err) console.error(err)

console.log(app.config)

})

app.get(‘/’, function (req, reply) {
reply.send({ hello: ‘world’ })
})

const blogRoutes = require(‘./routes/blogs’)
blogRoutes.forEach((route, index) = > {
app.route(route)
})

app.listen(app.config.PORT, (err, address) = > {
if (err) {
app.log.error(err)
process.exit(1)
}
app.log.info(`server listening on ${address}`)
})

Note that we have to define an options object that tells the fastify-env plugin what env variables to look for and which defaults to set. Here, I want to load a PORT variable with a default value of 1000.
By default, the fastify-env plugin will make all environment variables available via the Fastify app object like so: app.config.PORT. Why? The fastify-env plugin attaches the loaded configurations to the confKey, which by default is set to config. However, if you wish, you can change this to another key.
Start the project with node index.js and monitor the output. You should see the PORT variable being printed in your terminal.
Other interesting plugins to use?
fastify-auth: run multiple auth functions in Fastify
fastify-bearer-auth: bearer auth plugin for Fastify
fastify-caching: general server-side cache and etag support
fastify-cors: enables the use of CORS in a Fastify application
Step 5: Define Hooks
Lastly, let’s define some hooks. From the Fastify hooks documentation, we can read the following. “Hooks are registered with the fastify.addHook method and allow you to listen to specific events in the application or request/response lifecycle. You have to register a hook before the event is triggered, otherwise the event is lost.”
Make sure to define hooks before you define any routes:

app.addHook(‘onRoute’, (routeOptions) = > {
console.log(`Registered route: ${routeOptions.url}`)
})

app.get(‘/’, function (req, reply) {
reply.send({ hello: ‘world’ })
})

As you can see, the addHook function first accepts the hook you want to listen for. In our example, we want to listen for new routes being registered with the application. Next, the callback function accepts a routeOptions argument which contains a lot of information, such as the route URL or route method.
Specific details for the onRoute hook can be found in the documentation.
Let’s start the API with node index.js to see which routes have been registered. Your terminal output should look like this:

Registered route: /
Registered route: /api/blogs
Registered route: /api/blogs/:id
Registered route: /api/blogs
Registered route: /api/blogs/:id
Registered route: /api/blogs/:id

Got the same output? Success! At the same time, this was the end of the Fastify tutorial. Let’s wrap up this project with a short conclusion.
Wrapping Up
Fastify is a great, light-weight project that allows you to make use of its rich plugin ecosystem. Instead of creating functionality from scratch, you can make use of existing plugins. In other words, Fastify acts as a one-stop shop for developers, definitely improving the developer experience.
Personally, I like the Fastify hooks functionality as you can listen for various lifecycle events within your application.
To learn more about Fastify, check out the following documentation pages:
You can also check out the repo for this introduction on GitHub.

15+ Best Twitch Stream Overlay Templates in 2020 (Free & Premium)

Twitch is well-known as a video game streaming platform but it’s actually much bigger than that. Now it’s populated by all kinds of content creators and professionals. Most of them are even using Twitch as their main source of income. You’ll notice that all these Twitch streamers have their own unique and personalized streaming setups.…

5 Ways Technology Drives Small Business Growth

Business growth is always at the top of every business manager’s and/or owner’s mind. Without growth, no matter the size or scope of a given business, the chances of failure are always very high. That is because stagnation in today’s dynamic, overly competitive world of business is never an ideal position- someone is always trying…

How to Test Responsive Web Design Cross-Browser Compatibility

HTML is an inherently fluid medium. Text and containers expand horizontally and vertically to use the available space. That fluidity made complex designs more difficult, so by the turn of the millennium, many sites adopted a fixed-width based on popular screen sizes.The process remained viable as screen sizes kept increasing from 800×600 to 1024×768 and beyond. However, the rise of smartphones and the iPhone launch in 2007 reversed that trend. Today, more than half of users access web pages on a smaller mobile device.
Note: Technically, smartphones often have a higher resolution than many monitors, but individual pixels become invisible. An iPhone 11 Max translates its 2688 x 1242 hardware resolution to a more practical 896 × 414 logical resolution. Each logical pixel maps to a grid of 3×3 real pixels, which enables smoother fonts and increased image detail.
The initial workaround was two sites: one for desktop and one for mobile, often with user agent sniffing to redirect as necessary. This rapidly became impractical as the variety of devices grew exponentially.
Finally, the term Responsive Web Design (RWD) was devised by Ethan Marcotte in 2010. The technique allowed the same site to work on any device regardless of screen size or viewport dimensions.
Our thanks go to LambdaTest for sponsoring the update to this older article, which we’ve completely rewritten for 2020. Please support the partners who make SitePoint possible.
How Does RWD Work?
There’s no single RWD approach or technology.
First, you must determine how a site design will react to differently sized displays. This is a challenge, and many of the first RWD sites took an existing desktop layout and removed sections as screen dimensions reduced.
A better technique was mobile first. It started with a linear mobile view, which worked on all devices then rearranged or adapted content as more space and supported browser features became available. More recently, many sites have adopted simpler layouts, where the mobile and desktop experience is mostly similar.
A typical example of RWD in action is the hamburger menu. Those on smaller screens can click an icon to view navigation links, while those with larger screens may see all the options in a horizontal list.
The following sections provide a number of technical implementation options.
HTML viewport Meta Tag
Regardless of any RWD technique, the following tag must be set in your HTML :

The width=device-width setting ensures mobile browsers scale logical CSS pixels to the width of the screen. Without this, the browser will presume it’s rendering a desktop site and scale it accordingly so it can be panned and zoomed.
Media Queries
Media queries were the primary basis of the first RWD sites. They allow CSS to target specific ranges of viewport dimension. For example:

p {
font-size: 1rem;
}

@media (min-width: 900px) and (max-width: 1200px) {

p {
font-size: 1.5rem;
}

}

Media queries are still used, although less explicit options are now available.
Elements
The HTML element uses media query syntax to control which image is displayed from a choice of options. This is typically used for art direction in order to display a suitable image for device viewport. For example:

CSS Viewport Units
The vw and vh CSS units represent 1% of the viewport’s width and height respectively. vmin is 1% of the smallest dimension, and vmax is 1% of the largest dimension.
These permit RWD flexibility, especially when used in conjunction with calc. For example:

p {
font-size: 1rem + 0.5vw;
}

CSS Columns
CSS multi-column layouts provide a way to create multiple text columns as the dimensions of a container increase. For example:

.container {
columns: 12rem auto;
column-gap: 2rem;
}

CSS Flexbox and Grid
CSS Flexbox and CSS Grid provide modern techniques which lay out child elements depending on their content and the space available. The primary difference:
Flexbox is used for one-dimensional layouts. Elements can wrap (or not) to the next line as necessary so columns may not line up.
Grid is for two-dimensional layouts, usually with identifiable rows and columns.
Either can be used to create an intrinsic layout (a term devised by Jen Simmons). In essence, elements are sized according to the viewport dimensions without the need for media queries. For example:

.grid-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
grid-gap: 1rem;
}

JavaScript RWD Options
JavaScript can also be used to determine viewport dimensions and react accordingly. For example:

const
vw = window.innerWidth,
vh = window.innerHeight;

Similarly, the dimensions of an individual element can be examined with offsetWidth and offsetHeight, although the getBoundingClientRect() method can return more information including fractions of a pixel:

const
element = document.getElementById(‘myelement’),
rect = element.getBoundingClientRect(),
ew = rect.width,
eh = rect.height;

Window and element dimensions can change as a device is rotated or the browser window is resized. The matchMedia API can parse CSS media queries and trigger change events:

const mql = window.matchMedia(‘(min-width: 600px)’);

mqTest(mql);

mql.addListener(mqTest);

function mqTest(e) {

if (e.matches) {
console.log(‘viewport is at least 600px width’);
}
else {
console.log(‘viewport is less than 600px width’);
}

}

Browser Support
The RWD technologies above all offer good browser support. The most recent option — CSS Grid — is supported by almost 95% of browsers in use today. However, it’s still necessary to test your site across a range of devices, resolutions, and browsers…
In-browser Testing
Resizing your browser window is a reasonable testing strategy for a few hours, but it rapidly becomes inaccurate and cumbersome. Most browsers offer a Responsive Design Mode which lets you select a device and user agent, rotate it, choose a resolution, alter the pixel density, throttle bandwidth, emulate touch, and take screenshots.
In Firefox, select Responsive Design Mode from the Web Developer menu or press Ctrl | Cmd + Shift + M:

In Chromium-based browsers, open Developer tools from the More tools menu or press Ctrl | Cmd + Shift + I. Then click the Toggle device toolbar icon:

Switch back to the browser tab to view the resized site:

In Safari, enable the Show Develop menu in menu bar option from the Advanced tab of the browser Preferences. Load a page and choose Enter Responsive Design Mode from the Develop menu.
However, be aware that these tools only imitate a device’s screen dimensions and user agent. They cannot accurately emulate the following:

Rendering capabilities
The browser will use its own rendering engine — not that of the emulated device. A CSS feature that works in Firefox would “work” on its emulated iPhone view regardless of actual support. That said, Chrome desktop will show a reasonable approximation to Android Chrome, and macOS Safari will be similar to the iPhone because they’re based on the same rendering engines.

Older devices
Testing the iPhone browser view on the latest version of Safari cannot accurately represent older devices with legacy operating systems and software.

High-density displays
You’re limited to your PC monitor’s physical pixels, so a site may look better or worse on a real device.

Touch
A mouse or trackpad has finer control than a touch-screen device with a small display. It may be impossible to view effects applied on-hover.

Processing speed
Your PC is likely to have a faster network and processing speed than a mobile device.

Mobile OS Emulators
Running an Android or iOS virtual machine on your device allows you to install and run real mobile browsers and use their actual rendering engines.
Android emulators include:
Genymotion: free and commercial cloud options, all Android versions for Windows, macOS, and Linux
Android Studio (and Emulator): free, Windows, macOS, and Linux
Visual Studio Xamarin (and Emulators): commercial, Windows and macOS
Bliss OS: free, Android 9 for Windows, Linux, and Chrome OS
Phoenix OS: free, Android 7.1 or 5.1 for Windows and macOS
Android-x86: free Android ISOs for any virtual machine platform.
Chrome is the obvious browser choice for Android, but you can also install Opera Mini, which is prominent on lower-powered feature phones.
Options for iOS are more limited:
These emulators still have downsides:
The software requires some technical expertise and uses considerable system resources.
Many iOS options are simulators. They adapt another rendering engine and will not always be accurate.
Online Testing Services
This segment was created in partnership with LambdaTest. Thank you for supporting the partners who make SitePoint possible.
Several online services allow you to test responsive pages on mobile browsers over the Web. In essence, you rent time on a real device and can view its screen in your browser. There’s no software to set up or maintain.
As well as live testing, some services include automated testing APIs which allow you to run scripts and check for styling regressions or broken user interfaces.
LambdaTest provides more than 2,000 combinations of device, OS, and browser. Features include:
testing localhost pages running on your development PC
debugging with integrated developer tools
geolocation testing from different locations
automatically generated, full-page screenshots across multiple devices
a built-in issue tracker
LT Browser software (Windows, macOS, Linux) to test and compare devices with auto-reload and scroll sync
Selenium-based automated test APIs
24/7 support
a free plan with unlimited access from $15 per month.
Sign up for a free LambdaTest account …

Alternative services which also provide live and automated mobile testing include:
Real Device Testing
Finally, there’s no substitute for testing on real devices. It’s the best way to assess actual processing speed, touch control, and your site’s responsive web design.
Ideally, you should test as many devices as possible, but your own recent smartphone may not be indicative of average hardware. Try to obtain mid-range devices that are a year or two old, such as a second-hand Moto G7 or iPhone 8.
Devices on the same network can access your PC’s server by entering its IP address in the browser. This can be obtained with ifconfig on macOS and Linux or ipconfig on Windows.
You can also connect a smartphone to your PC with a USB cable. This allows you to remote-control the device and easily access its developer tool panels for debugging. The technique varies across platforms but, to debug Android Chrome on the desktop edition of the browser:
On the Android device, select Developer options from the Settings and enable USB debugging.
Connect the device to your computer using an appropriate USB cable. The first time you attempt this, you may be prompted to confirm actions on one or both devices.
Launch Chrome on your PC and open in a new tab. Ensure Discover USB devices is enabled.
Optionally, set Port forwarding — for example, port 8888 on the remote device can be forwarded to localhost:8888.
Your device should appear in the list. You can now inspect a new or existing tab which opens the device’s developer tools:

To debug Safari for iPhone, do the following:
Connect your phone to your Apple computer.
Open the web page you want to debug in Safari on your iPhone.
Launch Safari on your computer.
In Safari on the computer, go to Develop > [your iPhone] > [website to inspect]. This will open Safari’s developer tools on your computer, allowing you to debug the site on your iPhone.
One Site, Many Views
Responsive Web Design technologies allow you to create a single website which can be viewed by anyone on any device regardless of technical limitations and boundaries. Making it a great user experience is another matter, but the range and capabilities of testing tools continues to improve.