How to easily add a favicon to a Next.js app

Adding a favicon to a website enhances usability and branding. It helps identify the website in browser tabs and bookmarks, improving user recognition and trust.

Let’s learn how to quickly add a favicon image to a Next.js app

In this article

Add favicon automatically in Next.js 13 App Router

To add a favicon in Next.js 13 App Router, add a favicon.ico file to the app/ directory. Next.js will automatically detect favicon.ico and display it on the page.

Here we’ve added the favicon.ico to our VS Code Next.js project.

favicon.ico is the app directory in Visual Studio Code.

And this is all we need to do – here’s layout.tsx:

src/app/layout.tsx
import { Metadata } from 'next'; import './globals.css'; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <html lang="en"> <body>{children}</body> </html> ); }

And we’ll instantly see the image next to the page title in the browser tab:

The favicon shows up next to the page title in the browser-tab

Apart from favicon and .ico, Next.js also auto-discovers the following file name and extension combinations in the app/ directory

  • icon with .ico, .jpg, .jpeg, .png, or.svg extension.
  • app-icon with .jpg, .jpeg, .png extension.

You can rename PNGs to .ico files and they will still work.

Add favicon automatically in Next.js Pages Router

To add a favicon automatically in the Next.js pages directory, place a favicon.ico file in your public/ directory, and your browser will automatically detect the file for the site icon.

favicon.ico is the public directory in Visual Studio Code.

If your image file isn’t a .ico, you’ll need to either rename it to favicon.ico, or manually specify the filename.

Set Next.js favicon statically in Next.js 13 App Router

To add a favicon to a Next.js 13 app, you can also export a Metadata object with an icons property in your layout.tsx file:

src/app/layout.tsx
import { Metadata } from 'next'; import './globals.css'; export const metadata: Metadata = { icons: { icon: '/icon.png', }, }; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <html lang="en"> <body>{children}</body> </html> ); }

The image file should be in your public directory.

Set Next.js favicon with HTML in Pages Router

To add a site icon in the Next.js pages or app directory, use the HTML <link> tag in your _document.tsx or _document.js file, just like in vanilla HTML:

pages/_document.tsx
import { Html, Head, Main, NextScript } from 'next/document'; export default function Document() { return ( <Html lang="en"> <Head> <link rel="icon" href="/favicon.png" /> </Head> <body> <Main /> <NextScript /> </body> </Html> ); }

The favicon should be in your public directory.

Add favicon with HTML in Next.js 13 App Router

You can also use the HTML <link> tag to add a favicon in a project using the Next.js app directory, in your layout.tsx file:

src/app/layout.tsx
import './globals.css'; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <html lang="en"> <head> <link rel="icon" href="/app-icon.jpg" /> </head> <body>{children}</body> </html> ); }

The favicon should be in your public directory.

How to add or toggle a class on the body element in JavaScript

Adding a class to the <body> tag can be useful for applying global styles or targeting specific elements within the body for styling or functionality.

This article will teach us how to easily add or toggle a class on the HTML body element using JavaScript.

In this article

To add a class to the HTML body element in JavaScript on page load, call the classList.add() method on it, i.e., document.body.classList.add(element).

HTML
<!DOCTYPE html> <html> <head> <title>Coding Beauty Tutorial</title> </head> <body class="dev coding"> <div>This is a div element.</div> </body> </html>
JavaScript
document.body.classList.add('class-3');

The body property is the HTMLElement object that represents the body tag in the markup.

The classList property is a DOMTokenList object that represents the list of classes an element has.

The add() method of the classList property takes a list of classes and adds them to an element.

JavaScript
<!DOCTYPE html> <html> <head> <title>Coding Beauty Tutorial</title> </head> <body class="dev coding beauty"> <div>This is a div element.</div> </body> </html>

You can pass multiple arguments to add() to add more than one class to the body. For example, we can add both beauty and magic to the body in single statement.

JavaScript
document.body.classList.add('beauty', 'magic');

To produce this HTML markup:

JavaScript
<!DOCTYPE html> <html> <head> <title>Coding Beauty Tutorial</title> </head> <body class="dev coding beauty magic"> <div>This is a div element.</div> </body> </html>

If you add class that already exists on the HTML body, add() ignores the class instead of throwing an exception.

Add class to body tag in <head> tag

To add a class to the body element in the <head> tag using JavaScript, use the DOMContentLoaded event and the document.body.classList.add() method.

For example:

JavaScript
<!DOCTYPE html> <html> <head> <title>Coding Beauty Tutorial</title> <script> document.addEventListener('DOMContentLoaded', () => { document.body.classList.add('beauty', 'magic'); }); </script> </head> <body class="dev coding"> <div>This is a div element.</div> <script src="index"></script> </body> </html>

The DOMContentLoaded event runs when the HTML is completely parse and the DOM has loaded.

The <script> loads and the JavaScript runs before the browser renders the HTML, so without DOMContentLoaded, document.body will be null in the <script>, causing the “Cannot read property ‘classList’ of undefined” JavaScript error.

The "Cannot read property 'classList' of undefined" error happening in JavaScript.

Add class to body tag on click

If you’d like to add a class to the body tag when the user clicks an element, set a click listener on element and call document.body.classList.add() in this listener.

For example:

HTML
<!DOCTYPE html> <html> <head> <title>Coding Beauty Tutorial</title> </head> <body class="dev coding"> <div>So you can code</div> <button class="amazify">Be amazing</button> </body> </html>
JavaScript
const button = document.getElementById('amazify'); button.addEventListener('click', () => { document.body.classList.add('amazify'); });

Toggle class on body element

Toggling a class on the body element in JavaScript simplifies code implementation by handling the addition and removal of the class in a single line of code.

And this single line of code is a call to the body’s classList.toggle() method:

JavaScript
document.body.classList.toggle('incredible');

As you would expect, the class is removed from the body when it’s already there and added when it isn’t.

Next.js: How to set page title and meta description

Setting the page title and meta description helps improve search engine visibility, increase click-through rates, and provide concise summaries of webpage content.

In this article, we’re going to learn how we easily set the page title and meta description in a Next.js project.

In this article

Set static page title and meta description in Next.js App Router

To set page title and meta description statically in Next.js 13’s app directory, create a Metadata object in a page.tsx file and export it:

src/app/page.tsx
import React from 'react'; import { Metadata } from 'next'; export const metadata: Metadata = { title: 'Coding Beauty', description: 'codingbeautydev.com: Coding - the art, the science, and the passion.', }; export default function Page() { return ( <main> <h1>Welcome to Coding Beauty</h1> </main> ); }

The tab will have this title, and the page will have a meta tag containing this description:

A Next.js page with a title and meta description.

We can also do this in a layout.tsx to make every page using this layout have this title and meta description by default – if the page doesn’t have its own.

src/app/layout.tsx
import { Metadata } from 'next'; import '@/styles/globals.css'; export const metadata: Metadata = { title: 'Coding Beauty', description: 'The official Coding Beauty home page.', icons: { icon: '/favicon.png', }, }; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <html lang="en"> <body>{children}</body> </html> ); }

Set title and meta description dynamically in Next.js App Router

You can use the generateMetadata() function to set the page title and meta description using dynamic information we don’t know beforehand, like data from an API.

TypeScript
export function generateMetadata({ params }: Props): Promise<Metadata> { // fetch data with `params` // return a `Metadata` object return { title: post.name, description: post.description, } }

Let’s look at a full example, where we fetch API data for a post in our hypothetical social media app, and we use generateMetadata() to set the page title and meta description for the page based on what we get from the endpoint URL.

src/pages/posts/[id]/page.tsx
import { Metadata } from 'next'; type Props = { params: { id: string }; }; export async function generateMetadata({ params, }: Props): Promise<Metadata> { const id = params.id; const url = `https://api.mysocialapp.com/posts/${id}`; const post = await fetch(url).then((res) => res.json()); return { title: post.title, description: post.description, }; } export default async function Page({ params }: Props) { const { id } = params; const url = `https://api.mysocialapp.com/posts/${id}`; // fetch again! // But don't worry, Next.js caches the `fetch()` calls const post = await fetch(url).then((res) => res.json()); return ( <> <h1>{post.title}</h1> <div>{post.content}</div> </> ); }

We fetch data from the same endpoint twice, one for the title and meta description, and another to display the title and other information to the actual users on the page.

Next.js caches the results of the fetch in generateMetadata() for use in Page to prevent multiple requests and avoid performance hits.

If you export a Metadata object and also have generateMetadata() function, Next.js will use generateMetadata()‘s return value.

Set page title and meta description in Next.js Pages Router (<= 12)

To set the page title and meta description in the Next.js pages directory, create a Head component, and place meta and title tags in it, like you would in vanilla HTML:

pages/index.tsx
import Head from 'next/head'; export default function Home() { return ( <> <Head> <title>Coding Beauty</title> <meta name="description" content="A brand all about coding passion and success" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="icon" href="/favicon.png" /> </Head> <main> <h1>Welcome to Coding Beauty</h1> </main> </> ); }

We can also set the page title and meta description in your _app.tsx or _app.jsx file to make each page without a title or description use this as a default.

pages/_app.tsx
import '@/styles/globals.css'; import type { AppProps } from 'next/app'; import Head from 'next/head'; export default function App({ Component, pageProps }: AppProps) { return ( <> <Head> <title>Coding Beauty</title> <meta name="description" content="A page on the Coding Beauty website" /> </Head> <Component {...pageProps} /> </> ); }

Set page title and meta description dynamically in Next.js Pages Router (<= 12)

You can also set the page title and meta description in the pages directory based on some data not known ahead of time.

For instance, to set the meta information based on API data, you’ll fetch the data in getServerSideProps and display it in the title and meta tags that are in the Head tag.

pages/[id].tsx
import { GetServerSideProps } from 'next'; import Head from 'next/head'; export const getServerSideProps: GetServerSideProps = async (context) => { const { params } = context; const { id } = params!; const result = await fetch(`api.mystore.com/books/${id}`); const { title, description, details } = await result.json(); return { props: { title, description, details, }, }; }; export default function Home(props: any) { const { title, description, details } = props; return ( <> <Head> {/* 👇 set page title and meta description dynamically */} <title>{title}</title> <meta name="description" content={description} /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="icon" href="/favicon.png" /> </Head> <main> <h1>{title}</h1> <p>{details}</p> </main> </> ); }

Best laptops (for programming)

Dell XPS 15 9000

View laptop

  • Screen size: 15.6”
  • Color: Black
  • Hard disk size: 512 GB
  • CPU model: Core i7
  • RAM: 16 GB
  • Resolution: 1920 x 1200
  • OS: Windows 11 Pro
  • Special features: InfinityEdge, Anti-glare screen
  • Graphics card: Arc A370M Graphics

How to create a type from type or object keys or values in TypeScript

In this article

Create type from object keys in TypeScript

To create a type from an object’s keys in TypeScript, use the keyof typeof object. For example:

TypeScript
const brand = { name: 'Coding Beauty', domain: 'codingbeautydev.com', color: 'blue', }; // 👇 type Keys = 'name' | 'domain' | 'color'; type BrandKeys = keyof typeof brand;

With this, you’ll have a type that only accepts strings matching the key name, and your code editor’s intellisense should indicate:

The new type only accepts values matching the object's keys.
The new type only accepts values matching the object’s keys.

Create type from another type’s keys in TypeScript

We use typeof because brand is an instance object, not a type. If it was a type, we would omit typeof:

TypeScript
type Brand = { name: string; domain: string; color: string; }; // 👇 type Keys = 'name' | 'domain' | 'color'; type BrandKeys = keyof Brand;

As before, you’ll have a type that only contains strings matching the key name, and your code editor should detect this:

The new type only accepts values matching the first type's keys.
The new type only accepts values matching the first type’s keys.

Create type from object values in TypeScript

We can use typeof and type indexing to easily create a type from an object’s values in TypeScript:

TypeScript
const site = { url: 'codingbeautydev.com', color: 'blue', topic: 'coding', } as const; // 👈 const assertion // 👇 type Values = 'codingbeautydev.com' | 'color' | 'coding' type Values = (typeof site)[keyof typeof site];

We this, we’ll have a type that only accepts strings matching the values of the object:

The new type only accepts values matching the object's values.
The new type only accepts values matching the object’s values.

Otherwise, there’ll be a TypeScript error

You can only values matching the object's values to the new type.

Create generic type from object values in TypeScript

The as const is called a const assertion in TypeScript. It tells the compiler to infer the most specific type possible from an expression. Without it, the inferred value type will be a primitive, like string or number or union of these primitives – string | number for example.

TypeScript
const site = { url: 'codingbeautydev.com', color: 'blue', topic: 'coding', }; // 👇 type Values = 'string' type Values = (typeof site)[keyof typeof site]; // 👇 No error - `Values` takes any string const testObj: Values = 'random string';

Values is no different from the string type here, and VS Code confirms it:

The Values type is a string.
The Values type is a string.

If there are multiple primitive types, the resulting generic type will be a union of all those primitives:

TypeScript
const site = { url: 'codingbeautydev.com', age: 1000, // 👈 also `number` type now topic: 'coding', }; // 👇 type Values = 'string' | number type Values = (typeof site)[keyof typeof site]; // 👇 No error const testObj: Values = 34124;
The Values type is a string | number type.
The Values type is a string | number type.

Create generic type from another type’s values in TypeScript

You can also create generic types from another type’s values in TypeScript, like this:

TypeScript
type Site = { url: 'codingbeautydev.com'; age: number; topic: string; }; // 👇 type Site = 'string' | 'number' type Values = Site[keyof Site];
The Values type comes from the Site type's values.
The Values type comes from the Site type’s values.

How to allow all domains for images in Next.js

To allow Next.js to display images from all domains, modify your next.config.js file to add an object with protocol and hostname properties to the remotePatterns array property.

next.config.js
/** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, // other properties... remotePatterns: [ { protocol: 'https', hostname: '**', }, ], }; module.exports = nextConfig;

Why would I need to allow all domains for Next.js images?

Because you want to avoid this error:

The "hostname is not configured under images in your next.config.js" error occuring in a Next.js application.
Using a non-matching domain results in this error.

Which happens when you have next.config.js with a limited number of specified domains, for example:

Only images from upload.wikimedia.org are allowed in this Next.js app.
Only images from upload.wikimedia.org are allowed in this Next.js app.

But you try to display images from a domain not in the image.domains list:

src/app/blog/page.tsx
import React from 'react'; import { Metadata } from 'next'; import Image from 'next/image'; export const metadata: Metadata = { title: 'Coding Beauty', description: 'Tutorials by Coding Beauty', }; export default function Page() { return ( <main> <Image src="https://codingbeautydev.com/wp-content/uploads/2023/08/vscode-tips-tricks.png" alt="Coding Beauty article featured image" width={100} height={100} ></Image> 10 essential VS Code tips & tricks for greater productivity </main> ); }

remotePatterns vs images.domains property in next.config.js

In this case, you can follow the steps earlier in this article:

next.config.js
/** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, // other properties... remotePatterns: [ { protocol: 'https', hostname: '**', }, ], }; module.exports = nextConfig;

Or you can modify your next.config.js to include codingbeautydev.com:

Images can now also be displayed from codingbeautydev.com in this Next.js app.
Images can now also be displayed from codingbeautydev.com in this Next.js app.

Of course, if you don’t have any domains property, you just create one with the new domain as its single element.

While the image.domains is simple and straightforward, the remotePatterns property gives us more flexibility with its support for wildcard pattern matching, and protocol, port, and pathname restriction.

These advanced restrictions remotePatterns provide greater security when you don’t own all the content in the domain, which is why the Next.js team recommends it.

Why do we need to be explicit with domains for Next.js images?

So whether you use remotePatterns or images.domains, you still need to be explicit about the domains that a next/image component can display.

By doing so, you can prevent the potential security risks of loading images from random, unverified URLs that could contain malicious code.

How to fix the “This project is configured to use Yarn” error on pnpm install

The “This project is configured to use Yarn” error happens in pnpm install when you have a field in your package.json file that specifies Yarn as the package manager.

The package.json field may have come about when you ran a yarn set version ... command, for example, yarn set version stable to set up Yarn Berry, or yarn set version berry to migrate from Yarn v1 to Yarn Berry.

Fix “This project is configured to use Yarn” error

To fix the this pnpm install usage error, simply remove the "packageManager" field from package.json:

Once you do that, pnpm install will run properly.

7 amazing new JavaScript features in ES14 (ES2023)

The world’s most popular programming language just got a new update.

Ever since 2015, a new JavaScript version has come out every year with tons of powerful features to make life much easier, and 2023 has been no different. Let’s look at what ES14 has to offer.

1. Array toSorted() method

Sweet syntactic sugar.

ES14 comes with a new toSorted() method that makes it easier to sort an array and return a copy without mutation.

So instead of doing this:

JavaScript
const nums = [5, 2, 6, 3, 1, 7, 4]; const clone = [...nums]; const sorted = clone.sort(); console.log(sorted); // [1, 2, 3, 4, 5, 6, 7]

We now get to do this:

JavaScript
const nums = [5, 2, 6, 3, 1, 7, 4]; const sorted = nums.toSorted(); console.log(sorted); // [1, 2, 3, 4, 5, 6, 7] console.log(nums); // [5, 2, 6, 3, 1, 7, 4]

And just like sort(), toSorted() takes a callback function that lets you decide how the sort should happen – ascending or descending, alphabetical or numeric.

JavaScript
const nums = [5, 2, 6, 3, 1, 7, 4]; const sorted = nums.toSorted((a, b) => b - a); console.log(sorted); // [7, 6, 5, 4, 3, 2, 1]

2. Hashbang grammar

What’s a hashbang?

Basically, it’s a sequence of characters in a file that tells the Linux Shell what interpreter or engine it should use to run the file. For example:

codingbeauty.sh
#!/bin/bash echo "How are you all doing today?"

With this hashbang, we can now easily run codingbeauty.sh directly in the shell, after using the chmod command to make the script executable.

Hashbangs also let us hide all the juicy implementation details in our scripts and indicate specific interpreter versions to execute the script files.

So with ES14, we can now do this effortlessly in JavaScript files, like this:

codingbeauty.js
#!/usr/bin/env node console.log("I'm doing great, how are you?");

3. Array toSpliced() method

Those immutability purists out there will no doubt be pleased with all these new Array methods.

toSorted() is to sort() as toSpliced() is to splice():

JavaScript
const colors = ['red', 'green', 'blue', 'yellow', 'pink']; const spliced = colors.toSpliced(1, 2, 'gray', 'white'); console.log(spliced); // [ 'red', 'gray', 'white', 'yellow', 'pink' ] // Original not modified console.log(colors); // ['red', 'green', 'blue', 'yellow', 'pink'];

Here toSpliced() removes 2 of the array elements, starting from index 1, and inserts 'gray' and 'white' in their place.

4. Symbols as WeakMap keys

WeakMaps; not very popular, are they?

Well, they’re a lot like Maps, except their keys can only contain non-primitive objects – no strings or numbers allowed here. These keys are stored as weak references, meaning the JavaScript engine can carry out garbage collection on the objects when it needs to if there is no other reference to the objects in memory apart from the keys.

One powerful use of WeakMaps is custom caching: by using objects as keys, you can associate cached values with specific objects. When the objects are garbage collected, the corresponding WeakMap entries are automatically removed, clearing the cache immediately.

JavaScript
const map = new Map(); const weakMap = new WeakMap(); const obj1 = { name: 'React' }; const obj2 = { name: 'Angular' }; map.set(obj1, 'Value for obj1 at Coding Beauty'); weakMap.set(obj2, 'Value for obj2 at Coding Beauty'); console.log(map.get(obj1)); // Output: Value for obj1 console.log(weakMap.get(obj2)); // Output: Value for obj2 obj1 = null; obj2 = null; console.log(map.get(obj1)); // Output: Value for obj1 console.log(weakMap.get(obj2)); // Output: undefined (obj2 has been garbage collected)

So ES14 makes it possible to define JavaScript Symbols as keys. This can make the role a key-value pair plays in a WeakMap clearer.

JavaScript
let mySymbol = Symbol('mySymbol'); let myWeakMap = new WeakMap(); let obj = { name: 'Coding Beauty' }; myWeakMap.set(mySymbol, obj); console.log(myWeakMap.get(mySymbol)); // Output: object

And what are they meant for?

5. Array toReversed() method

Another new Array method to promote immutability and functional programming.

The name’s self-explanatory: give me the reversed version of my array.

Before – with reverse().

JavaScript
const arr = [5, 4, 3, 2, 1] const reversed = arr.reverse(); console.log(reversed); // [1, 2, 3, 4, 5] // Original modified console.log(arr); // [1, 2, 3, 4, 5]

Now:

JavaScript
const arr = [5, 4, 3, 2, 1] const reversed = arr.toReversed(); console.log(reversed); // [5, 4, 3, 2, 1] // Original NOT modified console.log(arr); // [1, 2, 3, 4, 5]

6. Array find from last

Sure we can already use the Array find() method to find an element in an array that passes a specified test condition. And findIndex() will give us the index of such an element.

But find() and findIndex() both start searching from the first element of the array. What if it’ll be better for us to search from the last element instead?

Here we’re trying to get the item in the array with the value prop equal to y. With find() and findIndex():

JavaScript
const letters = [ { value: 'v' }, { value: 'w' }, { value: 'x' }, { value: 'y' }, { value: 'z' }, ]; const found = letters.find((item) => item.value === 'y'); const foundIndex = letters.findIndex((item) => item.value === 'y'); console.log(found); // { value: 'y' } console.log(foundIndex); // 3

This works, but as the target object is closer to the tail of the array, we could make this program run faster if we use the new ES2022 findLast() and findLastIndex() methods to search the array from the end.

JavaScript
const letters = [ { value: 'v' }, { value: 'w' }, { value: 'x' }, { value: 'y' }, { value: 'z' }, ]; const found = letters.findLast((item) => item.value === 'y'); const foundIndex = letters.findLastIndex((item) => item.value === 'y'); console.log(found); // { value: 'y' } console.log(foundIndex); // 3

Another use case might require that we specifically search the array from the end to get the correct item. For example, if we want to find the last even number in a list of numbers, find() and findIndex() would produce a totally wrong result.

JavaScript
const nums = [7, 14, 3, 8, 10, 9]; // gives 14, instead of 10 const lastEven = nums.find((value) => value % 2 === 0); // gives 1, instead of 4 const lastEvenIndex = nums.findIndex((value) => value % 2 === 0); console.log(lastEven); // 14 console.log(lastEvenIndex); // 1

Yes, we could call the reverse() method on the array to reverse the order of the elements before calling find() and findIndex().

But this approach would cause unnecessary mutation of the array, as reverse() reverses the elements of an array in place. The only way to avoid this mutation would be to make a new copy of the entire array, which could cause performance problems for large arrays.

And this beside the fact that findIndex() would still not work on the reversed array, as reversing the elements would also mean changing the indexes they had in the original array. To get the original index, we would need to perform an additional calculation, which means writing more code.

JavaScript
const nums = [7, 14, 3, 8, 10, 9]; // Copying the entire array with the spread syntax before // calling reverse() const reversed = [...nums].reverse(); // correctly gives 10 const lastEven = reversed.find((value) => value % 2 === 0); // gives 1, instead of 4 const reversedIndex = reversed.findIndex((value) => value % 2 === 0); // Need to re-calculate to get original index const lastEvenIndex = reversed.length - 1 - reversedIndex; console.log(lastEven); // 10 console.log(reversedIndex); // 1 console.log(lastEvenIndex); // 4

It’s in cases like where the findLast() and findLastIndex() methods come in handy.

JavaScript
const nums = [7, 14, 3, 8, 10, 9]; const lastEven = nums.findLast((num) => num % 2 === 0); const lastEvenIndex = nums.findLastIndex((num) => num % 2 === 0); console.log(lastEven); // 10 console.log(lastEvenIndex); // 4

This code is shorter and more readable. Most importantly, it produces the correct result.

7. Array with() method

Unlike the others, with() has no complementary mutating method. But once you see it in action, you’ll know that it’s the immutable approach to changing a single element.

In so many languages, you typically modify a single array element like this:

JavaScript
const arr = [5, 4, 7, 2, 1] // Mutates array to change element arr[2] = 3; console.log(arr); // [5, 4, 3, 2, 1]

But see what we can do now, in ES2023 JavaScript:

JavaScript
const arr = [5, 4, 7, 2, 1]; const replaced = arr.with(2, 3); console.log(replaced); // [5, 4, 3, 2, 1] // Original not modified console.log(arr); // [5, 4, 7, 2, 1]

Final thoughts

This year was all about easier functional programming and immutability.

Indeed, the reliability and consistency that immutability brings cannot be overstated. With the rise of declarative frameworks like React and Vue as well as Redux and other libraries, we’ve seen immutable JavaScript array methods explode in popularity; it’s only natural that we see more and more of them come baked into the language as it matures.

They stole the show in 2023, just like JavaScript took over a huge chunk of the language ecosystem a while back, with many millions of developers keeping that fire burning today. Let’s see what the future holds.

How to easily get the intersection of two sets in JavaScript

To get the intersection of two Sets in JavaScript, combine the filter() and has() array methods:

JavaScript
const set1 = new Set([1, 2, 3, 4, 5]); const set2 = new Set([4, 5, 6, 7, 8]); const intersection = new Set([...set1].filter(x => set2.has(x))); console.log(intersection); // Set {4, 5}

The Array filter() method tests each element in an array against a condition specified by a callback function and creates a new array filled with elements that pass the test. It doesn’t modify the original array.

JavaScript
const arr = [1, 2, 3, 4]; const filtered = arr.filter((num) => num > 2); console.log(filtered); // [ 3, 4 ]

The spread syntax (...) converts the Set to an array:

JavaScript
const set1 = new Set([1, 2, 3, 4, 5]); const arrayFromSet = [...set1]; console.log(arrayFromSet); // [1, 2, 3, 4, 5]

We can also do this with the Array from() method, which converts Sets and other iterables into arrays:

JavaScript
const set1 = new Set([1, 2, 3, 4, 5]); const arrayFromSet = Array.from(set1); console.log(arrayFromSet); // [1, 2, 3, 4, 5]

And the Set has() method tells us whether or not the Set contains a particular element.

JavaScript
const set = new Set(['coding', 'beauty', 'dev']); const hasElegance = set.has('elegance'); const hasBeauty = set.has('beauty'); console.log(hasElegance); // false console.log(hasBeauty); // true

Get intersection of two sets with Array forEach() method

Alternatively, we can use the Array forEach() method to get the intersection of two Sets in JavaScript.

JavaScript
const set1 = new Set([1, 2, 3, 4, 5]); const set2 = new Set([4, 5, 6, 7, 8]); const intersection = new Set(); set1.forEach(value => { if (set2.has(value)) { intersection.add(value); } }); console.log(intersection); // Set {4, 5}

The Set forEach loops through an array and calls a specified function on each element.

JavaScript
const fruits = new Set(['apple', 'orange', 'banana']); fruits.forEach((fruit) => { console.log(fruit.toUpperCase()); }); // Output 👇 // APPLE // ORANGE // BANANA

The Set add() method adds a new element to a Set:

JavaScript
const set = new Set([1, 2, 3]); console.log(set); // Set(3) { 1, 2, 3 } set.add(10); console.log(set); // Set(4) { 1, 2, 3, 10 }

Get intersection of two Sets with for..of loop

Anywhere you see the forEach(), you can use the for..of loop in its place:

JavaScript
const set1 = new Set([1, 2, 3, 4, 5]); const set2 = new Set([4, 5, 6, 7, 8]); const intersection = new Set(); for (const value of set1) { if (set2.has(value)) { intersection.add(value); } } console.log(intersection); // Set {4, 5}

Get intersection of two Sets with reduce() method

You can also use the reduce() method to get the intersection of two Set objects in JavaScript:

JavaScript
const set1 = new Set([1, 2, 3, 4, 5]); const set2 = new Set([4, 5, 6, 7, 8]); const intersection = [...set1].reduce((acc, value) => { if (set2.has(value)) { acc.add(value); } return acc; }, new Set()); console.log(intersection); // Set {4, 5}

The reduce() method calls a function on each element of an array to accumulate a resulting value:

JavaScript
const nums = [1, 2, 3, 4, 5]; const sum = nums.reduce((acc, num) => acc + num, 0); const product = nums.reduce((acc, num) => acc * num, 1); console.log(sum); // 15 console.log(product); // 120

How to quickly toggle (enable/disable) autosave in VS Code

To enable or disable autosave in VS Code, use the File > Auto Save option from the menu bar.

The `File > Auto Save` option in Visual Studio Code enables/disables autosave.

After this, the “dirty” indicator will no longer show up when you modify a saved file.

Before:

Visual Studio Code without autosave.
No autosave.

After:

Visual Studio Code with autosave.
Autosave enabled – the unsaved indicator no longer shows.

Why do we need autosave?

So we can stop mindlessly pressing Ctrl + S.

So we can save time, increase productivity, and be much more certain that we’re working with the latest changes.

Autosave is not perfect though; it’s up to you to weigh the pros and cons – which we comprehensively cover here.

What’s not to like about autosave?

Some of the cons we talk about in that autosave article:

  1. It wastes resources because it saves even when you’re not ready to view the results of your changes.
  2. It makes it harder to recover from unexpected errors, for example, making a buggy file change and accidentally closing the file.
  3. There’s no auto-formatting with auto-save.

Enable/disable autosave in VS Code Settings

Alternatively, we can disable autosave in Visual Studio Code using the Files: Auto Save setting in the Settings page.

You can easily navigate to this page with the gear icon at the top-left of the code editor:

You can open Settings with the bottom-left gear icon.

Once you get there, you can use the search bar to find the setting.

Using the `Files: Auto Save` option in VS Code Settings.

As you can see, Files: Auto Save can be one of four possible values, namely:

  1. off – self-explanatory: disable autosave.
  2. afterDelay: – the new value enables autosave with the File > Auto Save setting. autosaves the file sometime after your changes.
  3. onFocusDelay – autosaves the dirty file when you switch windows or tabs.
  4. onWindowChange – as the name implies, autosaves the unsaved file when you switch windows in the operating system.

So there are more customization options in the Settings page than in the menu bar.

Change autosave delay in VS Code

When Files: Auto Save is set to afterDelay, you can modify the autosave delay in Visual Studio Code with the Files: Auto Save Delay setting.

Modifying the autosave delay in VS Code.

You may be better off increasing the autosave delay instead of disabling autosave entirely, so VS Code still saves your work automatically, while minimizing the impact on system resources.

Enable/disable autosave in VS Code with Command Palette

To turn autosave on or off in Visual Studio Code, you can also use the File: Toggle Auto Save command, accessible from the Command Palette:

Toggling auto save in VS Code with the Command Palette.