SEO Handbook

Tuan Tran VanTuan Tran Van
48 min read

SEO (Search Engine Optimization) is essential for your online marketing strategy. It’s the process of optimizing your site and content to help you get as much traffic as you can from search engines.

Reaching top positions in the Search Engine Results Pages (SERPs) with your website is one of the fastest ways to drive traffic to your site and boost conversions.

SEO Fundamentals

Amidst the economic devastation of COVID-19, online businesses have become more dependent on SEO than ever. Times like these illustrate the power and importance of Search Engine Optimization (SEO).

What is SEO?

SEO is the practice of increasing the quantity and quality of traffic to a web page through organic search engine results. Organic search results are derived from an internal algorithm of the search engine and are not a result of paid advertising. Below is a list of related terminology:

  • SERP, or Search Engine Results Page, is simply the results page that drives clicks. These pages include a combination of paid search results and organic results.

  • SEM, or Search Engine Marketing, is the practice of marketing a business using the paid advertisements that appear on SERPs.

  • PPC stands for pay-per-click, an internet marketing model in which advertisers pay a fee each time their ads are clicked.

Learning SEO basics and more advanced topics can be a bewildering process. In this post, we will examine simple steps to help create SEO-friendly web pages and tools for maintaining them.

Web Accessibility and Performance

Search Engines will surely continue to raise the bar for acceptable web standards. In 2018, Google announced the beginning of its migration to mobile-first indexing and expanded by announcing mobile-first indexing for the whole web in 2020. Web page performance and accessibility encompass user-centric metrics that can ultimately impact SEO.

Web performance captures the user journey, making various moments of the user experience. Below are important performance metrics:

  • First Contentful Paint (FCP) measures the time from when the page starts loading to when any part of its content is rendered on the screen.

  • Largest Contentful Paint (LCP) measures the time from the page's start loading to the time the largest text block or image element is rendered on the screen.

  • First-input Delay (FID) measures the time between when a user first interacts with your site (e.g., when they click on a link, tab a button, or use a custom, Javascript-powered control) and when the browser is actually able to respond to that interaction.

  • Time To Interactive (TTI) measures the time from when the page starts loading to when it’s visually rendered, its initial scripts (if any) have loaded, and it can reliably respond to user input quickly.

  • Total Blocking Time (TBT): measures the total amount of time between FCP and TTI when the main thread was blocked for long enough to prevent input responsiveness.

  • Cumulative Layout Shift (CLS): measures the cumulative score of all unexpected layout shifts that occur between when the page starts loading and when its lifecycle state changes to hidden.

Web accessibility is another important concept to keep in mind when building a search engine optimized website. Not only are there a variety of humans reading our websites, but also a variety of machines like screen-readers doing the same.

Improving accessibility makes your website more useable to everyone ~ Addy Osami | Accessibility Tips for Web Developers.

SEO Tools

In this post, we have taken a look at ways to improve SEO, but how do we maintain these standards over time? Many tools can help us analyze and monitor SEO.

Foo’s Automated Lighthouse Check monitors the quality of web pages with Lighthouse. It provides detailed SEO, performance, and accessibility reporting. Free and premium plans are available.

Google Search Console is a must-have for any website owner who cares about SEO. It provides insight into which search terms are receiving organic traffic and a granular level of analysis. You can filter by location, device, and more.

Benefits of SEO in Web Development

Every business owner wants to grow his or her brand. Search Engine Optimization (SEO) greatly benefits organizations that provide value and boost visibility to the target audience. The following are some of the benefits of integrating SEO into website development.

  1. SEO boosts high-quality traffic and organic discovery. Organic visibility leads to increased traffic, which is a monumental SEO benefit. Search engine optimization is customer-centric and hyper-targeted. An effective SEO strategy helps deliver web pages to the relevant people through pertinent search queries. Since users are already looking for what a site has to offer, organic visibility propels high-quality traffic without trying to persuade ot entice the visitor.

  2. SEO Boosts Credibility Ranking on Google’s first page showcases credibility to prospective customers. Google ranks websites based on on-page and off-page signals, such as site speed, content, and mobile usability. Although most customers probably don’t consider these signals, users expect Google to deliver valuable and relevant content first. Trust and credibility are developed on search engine authority and a high-quality service or product that builds credibility among web visitors or users.

  3. SEO provides an Impressive ROI ROI, or Return on Investment, which is vital when evaluating digital marketing channels. Although search engine optimization could take some time to get results, a high-quality strategy will ultimately deliver an impressive return on investment. Search engine leads offer a 14.6 percent close rate, almost 12 percent greater than traditional marketing. Nevertheless, there would be no leads if a website ranks at the bottom of pages 2, 3, 4, or not at all. Visibility in search engines correlates directly to improved web traffic and more revenue, making ROI one of the most significant benefits of SEO for organizations.

  4. SEO Targets the Marketing Funnel Driven by SEO, content marketing includes different types of targeting at each marketing funnel step. Although top or middle-of-the-funnel blog posts will not initially convert, this builds brand awareness and loyalty. These traits will lead to conversion.

SEO Techniques

The website optimization process meets the Google algorithm requirements in a way that equals building a website that corresponds to the user’s requirements. Users appreciate the fast-loading website that is error-free and can be browsed seamlessly on mobiles. That said, let’s explore the fundamentals that every web developer should know.

Website Loading Time

Website speed and loading time are the most important after ensuring your website can be indexed. The page speed test of a website with a good search result is vital; thus, it’s an essential factor to consider when it comes to website design. According to Semrush, a slow page response increases the website bounce rate.

Unsurprisingly, these users will skip over the website if it takes a second longer to load. Furthermore, a slow-loading website could also affect its search engine ranking. It would be challenging for an SEO expert to boost its rank with SEO content. Therefore, it’s highly recommended that developers integrate SEO into the development process, work closely with SEO experts, or learn core web vitals SEO principles in Google search console metrics about Website speed and performance.

Redirects

The digital landscape will continue to evolve. Furthermore, everyone is recreating and improving their own sites and domains with advanced features. Another important factor in SEO for web development is Redirects. Redirects smoothly lead users to the correct page during site migration and launch. For web developers, using 301 and 302 redirect codes is paramount. Don’t just rely on the code to be rendered. Rather, use tools to test the redirect codes, no matter how many pages are being redirected to the same destination. Redirects send users from URL to URL. The first URL is where users click, type, or make a request. The second URL is the new destination.

When to use 301 Redirects.

  • If you are changing the page URL

  • Domain Migration from page to page

  • If you want to pass the page authority to the new page.

When to use 302 Redirects

  • If you are making any changes to the current page.

  • If you don’t want to pass the page authority.

  • At some point in the future, the old page will be back.

Sitemaps

When it comes to search engine optimization, better crawlability plays an important role. When a search engine attempts to index a website, it should be able to crawl the whole website. Sitemaps are valuable if there are issues indexing the website. Adding a sitemap ensures that the website is properly indexed. Moreover, ensure that all pages listed in the XML sitemap do not have wasteful redirects, are error-free, and have clean code. From creating content to design to CEO, the sitemap is invaluable. You will constantly refer to it in the stages of development to stay on track. Sitemaps tell Google which files and pages you think are important and provide valuable information regarding these files. Here’s a simple example of the XML sitemap.

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://www.example.com/foo.html</loc>
<lastmod>2022-06-04</lastmod>
</url>
</urlset>

Robots.txt

A robots.txt file is a simple text file on a website that tells search engines which pages they can and cannot visit.

Sitemap: https://acidop.codes/sitemap.xml
User-agent: *
Allow: /
Disallow: /admin

In the above example, we submit our sitemap and also clearly state that we do not want to index our admin directory.

Mobile Responsiveness

Without a doubt, a website that is mobile-responsive provides a better user experience. Furthermore, a responsive design helps them navigate the website easily without zooming in or zooming out of the content. Smartphones are getting smarter, and search engines keep setting higher bars for mobile SEO factors. A mobile-friendly website will always rank better than a desktop-supported website. Thus, web developers must ensure that the website is compatible with a wide array of devices for good search engine optimization. Furthermore, Google uses mobile-first indexing, meaning that the mobile version of the website gets crawled first.

In the above image, you can see that in the Google Search Console, the primary crawler is a smartphone. Simply put, a mobile-responsive design is when a site is responsive, as the content and/or layout responds to the screen size on which it is displayed. Moreover, a responsive website adapts itself to the advice used to see it. Use Google’s mobile-friendly testing tool to get your website report.

Implement Structured Data

For most people involved in SEO, structured data could be knotty. This is where developers could truly shine. Developers already know how to format a page so all the parts will flow well and can be read by humans and search engines alike. When used well, structured data lets Google know where and what’s on the web page. Furthermore, it could also inform Google precisely what questions you are answering. Structured data is a way for the business website to convey its content to search engines. It boosts visibility. Google uses structured data on web pages to generate snippets, which display special enhancements in SEO results. Regardless of whether they appear at the top or bottom on the search results page, rich snippets are way more visible and prominent than the standard results, and therefore, the click-through rates are much better. Take a look at an example of SERP with and without structured data.

In the above example, rating (Review, AgreegateRating) markup has been used.

Google, Bing, Yandex, and Yahoo! worked together to create Schema.org so you could provide search engines the data they require to understand your content and deliver the most relevant results.

You can use any of the 3 methods suggested by Google:

JSON-LD is the format Google recommends and is also the easiest one to implement.

Take a look at an example of how review markup can be implemented.

<html>
 <head>
 <title>Legal Seafood</title>
  <script type="application/ld+json">
  {
   "@context": "https://schema.org/",
   "@type": "Review",
   "itemReviewed": {
    "@type": "Restaurant",
    "image": "https://www.example.com/seafood-restaurant.jpg",
    "name": "Legal Seafood",
    "servesCuisine": "Seafood",
    "priceRange": "$$$",
    "telephone": "1234567",
    "address" :{
     "@type": "PostalAddress",
     "streetAddress": "123 William St",
     "addressLocality": "New York",
     "addressRegion": "NY",
     "postalCode": "10038",
     "addressCountry": "US"
    }
   },
   "reviewRating": {
    "@type": "Rating",
    "ratingValue": "4"
   },
   "name": "A good seafood place.",
   "author": {
    "@type": "Person",
    "name": "Bob Smith"
   },
   "publisher": {
    "@type": "Organization",
    "name": "Washington Times"
   }
  }
  </script>
 </head>
 <body>
 </body>
</html>

This JSON=LD script needs to be embedded in the HTML:

A special script tag: <script type="application/ld+json"> is used for this purpose. we can insert this into the head or the body of the HTML.

The same can be tested using the Rich Results test tool.

User-Friendly URLs

Web developers should remember that URLs should be descriptive, concise, and easy to read to be effective. Both search engines and users like the quality of page addresses, which could easily be advantageous to your website. SEO guide for developers includes much information about bot-friendly writing URLs. You can, specifically, do the following:

  • Use one domain and subdomain. A subdomain could generate mixed results; thus, using a single domain whenever possible is the best solution.

  • Make use of hyphens. Rather than spaces, bots refer hyphens to separate words in URLs.

  • Keywords. Add keywords to URLs where they naturally fit. Do not, however, use too much. Furthermore, refrain from making the URL too long so it won’t look spammy.

  • Get rid of unsafe characters. Some characters, such as carats, tildes, and spaces, could make bots stop in their tracks. Thus, it’s best to avoid them. Here are some user-friendly URL suggestions:

Website Security

To the search engines, website security is an absolute must. Regarding website development, web developers should make sure to have an SSL in place and with no errors. Furthermore, it’s also necessary to have safeguards to ensure that the website doesn't have vulnerabilities.

For every business these days, protecting a website against phishing, cyber-crimes, cyber-attacks, and malfunctions is paramount. Security testing is always needed to defend against data loss and theft caused by digital hackers. In the present scenario, cybersecurity has become a primary shield, and with technological advancement, you need to detect, monitor, upgrade, and patch continuously to avoid risks. From the beginning, website security features should be implemented to keep up with the new threats of continuous technological advancement. Furthermore, the security features should be monitored and maintained as well. Getting hacks hurts the user experience and could cause the site to slow down, lose traffic, lose sensitive client information, and crash. Google Search Console also gives us notifications related to security issues. Google Search Console with website security issues.

Google Search Console without website security issues.

Title Tags and Meta Descriptions

Here is how a title tag looks:

<head>
  <title>AcidOP | Freelancing Developer</title>
</head>

Again, your goal is to tell a lot in a very short space. Technically, you don’t have a limit, but you should keep it to 60 characters.

The title should explain your niche or product related to your website and article.

Here’s how a description tag looks:

<head>
  <meta name="description" content="Excellent Developer from India." />
</head>

One of the most important elements in drawing visitors to a website is a meta description tag:

The meta description should skillfully include the page’s target keywords to persuade readers to click through the page.

Search engines like Google frequently draw user attention by emphasizing terms from the query while displaying the description. It’s critical to match your description closely, but not excessively, to highly valuable search terms.

Below is a title and description tag in action:

Do not exceed 155 characters in descriptions, or Google will then truncate the text.

Here is a list of other meta tags that you can use as well.

Header Tags (H1, H2, H3, etc.)

Header tags help your users navigate the page. The break up your content and break the page into dedicated sections.

Search engines rely on headers to better understand the sections of the page, which helps with SEO.

Instead of writing a very long article with a few paragraphs, divide it into multiple parts, each with its own heading, as I have done in this blog.

The main title of your document should be your <h1>. The H1 Tag represents the document’s overall topic and is displayed at the beginning as the large text.

Your main points should be wrapped in <h2>. H2 tags are second-level headings used to break up content and make it scanable and easy to read.

Subsequent heading tags lead all the way up to H6, which are not that important in the heading hierarchy.

  • All the tags must be in the hierarchy, i.e., H1>H2>H3...H6.

  • There should only be 1 H1 tag in the entire document.

<h1>I built an Markdown editor using Next.js and TailwindCss 🔥</h1>

<h2>Objectives</h2>

<h2>1. Create the landing page</h2>
<h2>2. Add states to store data</h2>
<h2>3. Setup react-markdown and @tailwindcss/typography</h2>
<h2>4. Code Highlighting and Custom Components</h2>
<h3>Optional</h3>
<h2>5. Adding Rehype and Remark Plugins</h2>
<h2>6. Header with Markdown buttons</h2>

Image Optimization for SEO

According to Optinmonster, content that contains images receives up to 94% more views.

Visuals naturally captivate people, and nothing does it more effectively than a pleasing image.

This means that you must use visuals in your content to engage readers and increase your visibility.

Using descriptive alt text

<img src="https://acidop.codes/og.jpg" alt="My website banner" />

Alt Tags (Technically, they are not tags; they are attributes, but you don’t need to worry about that) are important for several key reasons.

  • Enhanced Accessibility: It assists visually impaired individuals in comprehending the image.

  • SEO Boost: It offers search engines valuable details about the image, aiding in its visibility in search rankings.

  • Improved User Experience: It conveys information about the image, even when it fails to load.

Choosing the right image formats:

  • JPEGs are good things like screenshots, blog post images, and content where site speed is essential.

  • PNG is better for quality and resolution, but these files are typically larger, which can result in slower page load time.

  • WebP offers superior compression capabilities compared to others, without comprising much on image quality. It enhances the load time of your web pages and minimizes bandwidth. It supports both the animated features of GIFs and the transparent backgrounds of PNGs.

  • SVG is best when it comes to icons and logos. They can be scaled to any size without losing resolution.

Implementing responsive images (srcset)

Large graphics may slow down your website. We can speed up the process and lower the file size, but the visual quality remains the same on mobile devices as it does on desktop computers.

srcset allows you to define a list of different image resources along with size information so the browser can pick the most appropriate image based on the actual device’s resolution.

<img
  src="image.jpg"
  srcset="small.jpg 300w, medium.jpg 600w, large.jpg 900w"
/>

Canonical Tags (Important)

<head>
  <link
    rel="canonical"
    href="https://acidop.codes/blogs/developer-seo-tips"
  />
</head>

In SEO, a canonical tag is a link attribute that tells search engines which version of a web page is the original. This helps avoid confusion when multiple pages have similar or identical content.

Google is known to penalize sites with duplicate content.

https://acidop.codes,

https://acidop.codes?utm_content=buffer

Even with UTM parameters, both point to the same page, right?

However, Google would consider both URLs to be different pages.

Having a propel canonical tag would help Google understand both are the same

For example, I write blogs on 2 sites: Dev.to (which supports canonical URLs) and my website. My primary source is my website obviously.

First, I post my blog on my website. Then I post the same blog on dev.to with a canonical URL pointing to my own website.

This way, I managed to get a bigger audience while also preventing Google from penalizing me.

Regular SEO Audits and Monitoring

An SEO audit determines how optimized your website is for search engines. It identifies problems that could be harming the website’s rankings and offers ways to fix them.

Free tools for SEO audits:

  1. Aioseo (Best)

  2. seoptimer.com

  3. Seomator

  4. Seobility

  5. Semrush

  6. Ahrefs

Next.js SEO

Next.js is a popular React-based web framework that has gained popularity and a growing community in recent years. It’s a powerful tool for building fast and SEO-friendly web applications with dynamic pages that work great on mobile devices.

Due to the complex nature of isomorphic system design, Next.js SEO can be a tricky topic to get your head around. You are coming from traditional React apps, and you’re relying solely on documentation.

With its built-in support for server-side rendering, static site generation, and now React server components, Next.js provides a robust platform for achieving quality SEO web traffic in your web application. It also helps you deliver exceptional user experiences across multiple pages in Node and React apps while making them SEO-friendly.

How is Next SEO different from other Frameworks?

Next.js SEO sets itself apart by streamlining so many features and free tools into a well-organized package that you can easily digest and apply in your single applications. Nextjs does a great job when it comes to tasks such as search engine optimization, image optimization, and minimizing cumulative layout shift.

Nextjs SEo won’t change much conceptually. If you are looking for good search engine results and organic traffic, the game still revolves around the notion of fast page loads, quick paints, low cumulative layout shifts, and all the rest. Static pages still play a large role as well.

But Next.js gives us some pretty cool and novel features that help facilitate excellent search engine metrics, and it’s more than just React Server Components.

Best Practices for Higher Rankings

In addition to leveraging Next.js features for SEO, there are several other Next.js best practices you should consider to optimize your site’s visibility to search engines. Here are key strategies, including your mention of robots or sitemaps:

  • Robots.txt: This is a text file placed in the root directory of your site that tells search engine crawlers which pages or sections of your site should not be crawled or indexed. For a Next.js site, you can create a robots.txt file and serve it statically. Ensure it’s accessible by placing it in the public folder. This will help control the crawler traffic to your site, prevent the indexing of certain pages, and help manage the crawl budget.

  • XML Sitemaps: A sitemap is crucial as it lists all URLs for a site, allowing search engines to crawl the site more intelligently. In Next.js, you can generate sitemaps dynamically during your build process. Static generation is often preferred for performance reasons. You can use libraries like next-sitemap Automate the generation of sitemaps during your build process.

  • Use Semantic HTML: Semantic HTML5 elements (like <header>, <footer>, <article>, and <section>) help search engines understand the structure of your website and the performance of the content within each section. This can be particularly beneficial for SEO.

  • Optimize Page Speed: Google considers page speed as the ranking factor. Optimize images, leverage efficient CSS and Javascript, use Nextjs’s Image component for optimized image handling, and consider implementing a Content Delivery Network (CDN) to serve your content faster.

  • Meta Tags and Descriptions: Ensure each page has a unique title and description meta tags that accurately describe the page content. These are crucial for SEO as they appear in search engine results.

  • Structured Data: Implement structured data using JSON-LD to help search engines understand the content of your pages and provide rich results. Next.js can handle inline scripts where you can place your JSON-LD structured data.

  • Accessibility (A11y): Making your website accessible is not only a good practice for usability, It also impacts SEO. Ensuring your website is accessible to all users, including those with disabilities, can positively influence your rankings.

  • Mobile-Friendliness: With the increasing use of mobile devices, having a mobile-friendly website is crucial. Next.js’s responsive design capabilities can help ensure that your website looks good on all devices, which is important for both user experience and SEO.

  • Content Quality: Regularly update your website with high-quality, relevant content that addresses your audience’s needs. This is vital for SEO and helps retain visitors.

Implementing these practices within your Next.js application can significantly enhance your SEO performance and ensure your site is well-optimized for search engines.

Effective Meta Tag Integration in Next13

Next.js 13 has completely overhauled the process of integrating meta tags, bringing about significant changes.

💡
Explore the procedure for configuring metadata in Next Js 12 or earlier.

In the most recent iteration of Next.js, there are two approaches to configuring meta tags. You can utilize either the generateMetadata method or incorporate a static metadata object within the layout.tsx or page.tsx files.

💡
Refer to the metadata fields to access the comprehensive list of supported options with Next JS 13 and above.

The Static Metadata Object

// layout.tsx or page.tsx

import { Metadata } from 'next'

// either Static metadata
export const metadata: Metadata = {
  title: 'Create Next App',
  description: 'Generated by create next app',
  icons: {
    icon: "https://nextjs.org/favicon.ico"
  }
}


// <head> output
<title>Create Next App</title>
<meta name="description" content="Generated by create next app"/>
<link rel="icon" href="https://nextjs.org/favicon.ico"/>

The generateMetadataFunction

Utilizing the generateMetadata functionality allows for the execution of API calls. Additionally, access to parameters such as params, searchParams, and parent provides the means to generate dynamic metadata for dynamic routes.

The generateMetadata function is expected to return a Metadata object encompassing one or more metadata fields.

Example:

// layout.tsx or page.tsx
import { Metadata, ResolvingMetadata } from 'next'

type Props = {
  params: { id: string }
  searchParams: { [key: string]: string | string[] | undefined }
}

export async function generateMetadata(
  { params, searchParams }: Props,
  parent: ResolvingMetadata
): Promise<Metadata> {

  // read route params
  const id = params.id

  // fetch data
  const product = await fetch(`https://.../${id}`).then((res) => res.json())

  // optionally access and extend (rather than replace) parent metadata
  const previousImages = (await parent).openGraph?.images || []

  // returning metadata object
  return {
    title: product.title, // Create Next App
    description: product.description //Generated by create next app
    icons: {
      icon: "https://nextjs.org/favicon.ico"
    },
  }
}

export default function Page({ params, searchParams }: Props) {}

Following will be the <head> Output

<title>Create Next App</title>
<meta name="description" content="Generated by create next app"/>
<link rel="icon" href="https://nextjs.org/favicon.ico"/>
💡
The metadata object and generateMetadata function exports are only supported in Server Components. You cannot export both the metadata object and generateMetadata function from the same route segment.

Next.js will automatically include some crucial meta tags by default.

<!-- default metatags added by Next JS framework -->
<meta charSet="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>

So far, we have progressed. Now, let us examine all metadata fields and their various options.

viewport MetaData Object

However, viewport options can be superseded by exporting a viewport object from either the layout.tsx or page.tsx files.

// layout.tsx or page.tsx
import type { Viewport } from 'next'

// static viewport object
export const viewport: Viewport = {
    width: 'device-width',
    initialScale: 1,
    maximumScale: 5,
    minimumScale: 1,
    themeColor: [
      { media: '(prefers-color-scheme: light)', color: 'cyan' },
      { media: '(prefers-color-scheme: dark)', color: 'black' },
    ],
    colorScheme: 'dark',
};

//<head> ouput
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=5"/>
<meta name="theme-color" media="(prefers-color-scheme: light)" content="cyan" />
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="black" />
<meta name="color-scheme" content="dark" />

The viewport object can also be dynamically generated using the asynchronous function generateViewport. This operates similarly to the generateMetadata function.

Good to know: If the viewport doesn’t depend on runtime information, it should be defined using the static viewport object rather than generateMetadata.

Template Object

A template object can be used to define default or fallback values. This can be only defined in layout.tsx.

import { Metadata } from 'next'

export const metadata: Metadata = {
  title: {
    template: '...',
    default: '...',
    absolute: '...',
  },
}

1. title.default can be used to provide a fallback title to child route segments that don't define a title.

2. title.templatecan be used to add a prefix or a suffix to titles defined in child route segments.

// app/layout.tsx
import { Metadata } from 'next'

export const metadata: Metadata = {
  title: {
    template: '%s | Acme',
    default: 'Acme', // a default is required when creating a template
  },
}


// app/page.tsx
import { Metadata } from 'next'

export const metadata: Metadata = {
  title: 'About',
}

// Output: <title>About | Acme</title>

3. title.absolutecan be used to provide a title that ignores title.template set in parent segments.

// layout.tsx
import { Metadata } from 'next'

export const metadata: Metadata = {
  title: {
    template: '%s | Acme',
  },
}

// app/page.tsx
import { Metadata } from 'next'

export const metadata: Metadata = {
  title: {
    absolute: 'About',
  },
}

// Output: <title>About</title>

Basic Fields

Let’s check all basic fields which is required for SEO.

export const metadata = {
  generator: 'Next.js',
  applicationName: 'Next.js',
  referrer: 'origin-when-cross-origin',
  keywords: ['Next.js', 'React', 'JavaScript'],
  authors: [{ name: 'Seb' }, { name: 'Josh', url: 'https://nextjs.org' }],
  creator: 'Jiachi Liu',
  publisher: 'Sebastian Markbåge'
}

// Head output
<meta name="application-name" content="Next.js" />
<meta name="author" content="Seb" />
<link rel="author" href="https://nextjs.org" />
<meta name="author" content="Josh" />
<meta name="generator" content="Next.js" />
<meta name="keywords" content="Next.js,React,JavaScript" />
<meta name="referrer" content="origin-when-cross-origin" />
<meta name="color-scheme" content="dark" />
<meta name="creator" content="Jiachi Liu" />
<meta name="publisher" content="Sebastian Markbåge" />

FormateDetection Field

The behaviour of these automatic links for phone numbers, email addresses, and physical addresses can be controlled through the utilisation of formatDetection.

Please refer to the example below, which illustrates the disabling of the automatic link behaviour for phone numbers, email addresses, and telephone contacts.

export const metadata = {
  formatDetection: {
    email: false,
    address: false,
    telephone: false,
  },
}

// Head output
<meta name="format-detection" content="telephone=no, address=no, email=no" />

metadataBase Field

The metadataBase option provides a convenient way to establish a base URL prefix for metadata fields that demand a fully qualified URL.

export const metadata = {
  metadataBase: new URL('https://acme.com'),
  alternates: {
    canonical: '/',
    languages: {
      'en-US': '/en-US',
      'de-DE': '/de-DE',
    },
  },
  openGraph: {
    images: '/og-image.png',
  },
}


// <head> out will be
<link rel="canonical" href="https://acme.com" />
<link rel="alternate" hreflang="en-US" href="https://acme.com/en-US" />
<link rel="alternate" hreflang="de-DE" href="https://acme.com/de-DE" />
<meta property="og:image" content="https://acme.com/og-image.png" />

In the preceding example, you’ll observe that the metadataBase includes the base URL. Nevertheless, in other instances, such as canonical and openGraph, the base URL is not explicitly defined. Despite this, the output reflects the presence of the base URL.

openGraph Field

The openGraph field is employed for incorporating og:* related meta tags. Let us now review all the available options under this category.

// layout.tsx or page.tsx
export const metadata = {
  openGraph: {
    title: 'Next.js',
    description: 'The React Framework for the Web',
    url: 'https://nextjs.org',
    siteName: 'Next.js',
    images: [
      {
        url: 'https://nextjs.org/og.png',
        width: 800,
        height: 600,
      },
      {
        url: 'https://nextjs.org/og-alt.png',
        width: 1800,
        height: 1600,
        alt: 'My custom alt',
      },
    ],
    locale: 'en_US',
    type: 'article', // this can be 'website' as well
    publishedTime: '2023-01-01T00:00:00.000Z',
    authors: ['Seb', 'Josh'],
  },
}

// Head output
<meta property="og:title" content="Next.js" />
<meta property="og:description" content="The React Framework for the Web" />
<meta property="og:url" content="https://nextjs.org/" />
<meta property="og:site_name" content="Next.js" />
<meta property="og:locale" content="en_US" />
<meta property="og:image:url" content="https://nextjs.org/og.png" />
<meta property="og:image:width" content="800" />
<meta property="og:image:height" content="600" />
<meta property="og:image:url" content="https://nextjs.org/og-alt.png" />
<meta property="og:image:width" content="1800" />
<meta property="og:image:height" content="1600" />
<meta property="og:image:alt" content="My custom alt" />
// <meta property="og:type" content="website" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2023-01-01T00:00:00.000Z" />
<meta property="article:author" content="Seb" />
<meta property="article:author" content="Josh" />

robotsField

import type { Metadata } from 'next'

export const metadata: Metadata = {
  robots: {
    index: false,
    follow: true,
    nocache: true,
    googleBot: {
      index: true,
      follow: false,
      noimageindex: true,
      'max-video-preview': -1,
      'max-image-preview': 'large',
      'max-snippet': -1,
    },
  },
}

// Head ouput
<meta name="robots" content="noindex, follow, nocache" />
<meta
  name="googlebot"
  content="index, nofollow, noimageindex, max-video-preview:-1, max-image-preview:large, max-snippet:-1"
/>

icons Field

Next.js recommends using the file-based Metadata API for icons where possible. Rather than having to sync the config export with actual files, the file-based API will automatically generate the correct metadata for you.

export const metadata = {
  icons: {
    icon: '/icon.png',
    shortcut: '/shortcut-icon.png',
    apple: '/apple-icon.png',
    other: {
      rel: 'apple-touch-icon-precomposed',
      url: '/apple-touch-icon-precomposed.png',
    },
  },
}

// Head Output
<link rel="shortcut icon" href="/shortcut-icon.png" />
<link rel="icon" href="/icon.png" />
<link rel="apple-touch-icon" href="/apple-icon.png" />
<link
  rel="apple-touch-icon-precomposed"
  href="/apple-touch-icon-precomposed.png"
/>

manifest Field

A web application manifest, defined in the Web Application Manifest specification, is a JSON text file that provides information about a web application.

export const metadata = {
  manifest: 'https://nextjs.org/manifest.json',
}

// Head Output
<link rel="manifest" href="https://nextjs.org/manifest.json" />

twitter Field

The Twitter metadata specification is utilized by Twitter to present rich text, imagery, and video content when links are shared on the platform.

Learn more about the Twitter Card markup reference.

// layout.tsx or page.tsx
export const metadata = {
  twitter: {
    card: 'app',
    title: 'Next.js',
    description: 'The React Framework for the Web',
    siteId: '1467726470533754880',
    creator: '@nextjs',
    creatorId: '1467726470533754880',
    images: {
      url: 'https://nextjs.org/og.png',
      alt: 'Next.js Logo',
    },
    app: {
      name: 'twitter_app',
      id: {
        iphone: 'twitter_app://iphone',
        ipad: 'twitter_app://ipad',
        googleplay: 'twitter_app://googleplay',
      },
      url: {
        iphone: 'https://iphone_url',
        ipad: 'https://ipad_url',
      },
    },
  },
}


// Head Output
<meta name="twitter:site:id" content="1467726470533754880" />
<meta name="twitter:creator" content="@nextjs" />
<meta name="twitter:creator:id" content="1467726470533754880" />
<meta name="twitter:title" content="Next.js" />
<meta name="twitter:description" content="The React Framework for the Web" />
<meta name="twitter:card" content="app" />
<meta name="twitter:image" content="https://nextjs.org/og.png" />
<meta name="twitter:image:alt" content="Next.js Logo" />
<meta name="twitter:app:name:iphone" content="twitter_app" />
<meta name="twitter:app:id:iphone" content="twitter_app://iphone" />
<meta name="twitter:app:id:ipad" content="twitter_app://ipad" />
<meta name="twitter:app:id:googleplay" content="twitter_app://googleplay" />
<meta name="twitter:app:url:iphone" content="https://iphone_url" />
<meta name="twitter:app:url:ipad" content="https://ipad_url" />
<meta name="twitter:app:name:ipad" content="twitter_app" />
<meta name="twitter:app:name:googleplay" content="twitter_app" />

verification Field

verification field is used to add different search engine verification code to verify site.

// layout.tsx or page.tsx
export const metadata = {
  verification: {
    google: 'google',
    yandex: 'yandex',
    yahoo: 'yahoo',
    other: {
      me: ['my-email', 'my-link'],
    },
  },
}

// Head Output
<meta name="google-site-verification" content="google" />
<meta name="y_key" content="yahoo" />
<meta name="yandex-verification" content="yandex" />
<meta name="me" content="my-email" />
<meta name="me" content="my-link" />

alternates Field

alternates field is used to create meta tags for canonical, languages, media and define type of page.

// layout.tsx or page.tsx
export const metadata = {
  alternates: {
    canonical: 'https://nextjs.org',
    languages: {
      'en-US': 'https://nextjs.org/en-US',
      'de-DE': 'https://nextjs.org/de-DE',
    },
    media: {
      'only screen and (max-width: 600px)': 'https://nextjs.org/mobile',
    },
    types: {
      'application/rss+xml': 'https://nextjs.org/rss',
    },
  },
}

// Head Output
<link rel="canonical" href="https://nextjs.org" />
<link rel="alternate" hreflang="en-US" href="https://nextjs.org/en-US" />
<link rel="alternate" hreflang="de-DE" href="https://nextjs.org/de-DE" />
<link
  rel="alternate"
  media="only screen and (max-width: 600px)"
  href="https://nextjs.org/mobile"
/>
<link
  rel="alternate"
  type="application/rss+xml"
  href="https://nextjs.org/rss"
/>

other Field

All metadata options should be covered using the built-in support. However, there may be custom metadata tags specific to your site or brand-new metadata tags just released. You can use the other option to render any custom metadata tag.

// layout.tsx or page.tsx
export const metadata = {
  other: {
    custom: 'meta',
  },
}

// Head Output
<meta name="custom" content="meta" />

To generate multiple same-key meta tags, you can use an array value.

// layout.tsx or page.tsx
export const metadata = {
  other: {
    custom: ['meta1', 'meta2'],
  },
}

// Head Output
<meta name="custom" content="meta1" /> <meta name="custom" content="meta2" />

There are so many other options available like appleWebApp, appLinks, archives, assets, bookmarks, category. Refer to the Metadata Fields to access all lists of supported options with Next JS 13 and above.

There are few unsupported Metadata. Refer to the Unsupported MetaData to know more about them.

Accessibility

As a front-end developer, it is your responsibility to ensure that the websites you create are accessible to all users, including those with disabilities. In this guide, we will explore what web accessibility is, why it is important, and how you can create web-accessible websites.

What is Web Accessibility?

Before we dive into what web accessibility is, we should first understand what the word Accessibility entails:

From my knowledge, Accessibility means the ability of everyone regardless of their condition to have access to something (e.g. internet, transport, system).

Wikipedia says, “Accessibility refers to the design of products, devices, services, or environments for people who experience disabilities.“

So we could eventually say that Web Accessibility is a way to make everyone including the disabled to have access to the website and internet as a whole.

To put it differently, we could also say:

Web Accessibility means that people with disabilities can use the Web.

At the end of the day, we can conclude that people with disabilities can perceive, understand, navigate, and interact with the Web and that they can contribute to the Web. Web accessibility also benefits those with temporary or conditional disabilities which in some cases may be aging, slow internet connection, or broken arm.

What is Disability and Types?

It’s important to build sites that are inclusive and accessible to everyone. There are at least six key areas of disability you can optimize for: visual, hearing, mobility, cognition, speed, and neural. Many tools and resources can help here, even if you are totally new to web accessibility.

Over one billion people live with some form of disability.

To be accessible, sites need to work across multiple devices with varying screen sizes and different kinds of input, such as screen readers. Moreover, sites should be usable by the broadest of users, including those with disabilities.

Here are a few disabilities your users may have:

Visual issues range from an inability to distinguish colors to no vision at all:

  • Ensures text content meets a minimum contrast ratio threshold.

  • Avoid communicating information using solely color and ensure that all text is resizable.

  • Ensures all user interface components can be used with assistive technologies such as screen readers, magnifiers, and braille displays. This entails ensuring that UI components are marked up such that accessibility APIs can programmatically determine the role, state, value, and title of any element.

💡
Tip: The element inspection feature in the browser displays a tooltip of CSS properties that includes a quick check for the color contrast ratio.

Some people live with low vision, they often find themself zooming in on sites, their DevTools, and the Terminal. While supporting Zoom is almost never at the top of developers' to-do lists, it can make a world of difference for people like them.

Hearing issues mean a user may have issues hearing sound emitted from a page.

Mobility issues can include the inability to operate a mouse, a keyboard, or a touch screen.

  • Make the content of your UI components functionally accessible from a keyboard for any actions one would otherwise use the mouse for

  • Ensure pages are correctly marked up for assistive technologies — including screen readers, voice control software, and physical switch controls — which tend to use the same APIs.

Cognitive issues mean a user may require assistive technologies to help them with reading text, so it’s important to ensure text alternatives exist.

  • Be mindful when using animations. Avoid video and animation that repeat or flash, which can cause issues for some users.
    The prefers-reduced-motion CSS media query lets you limit animations and auto-playing videos for users who prefer reduced motion:

      /*
      If the user expresses a preference for reduced motion, don't use animations on buttons.
      */
      @media (prefers-reduced-motion: reduce) {
        button {
          animation: none;
        }
      }
    
  • Avoid interactions that are timing-based.

This may seem like a lot of bases to cover, but we will work through the process of assessing and improving the accessibility of your UI components.

For extra visual support, the GOV.UK accessibility team has created a series of accessibility do and don'ts digital posters, which you can use to share the best practices with your team.

Why Web Accessibility is important?

The Web and the Internet as a whole are increasingly important resources in many aspects of our lives, including education, employment, government, commerce, health care, creation, and more. Therefore, it is important that the Web be accessible to everyone to provide equal access and equal opportunity to people with disabilities. An accessible Web can help people with disabilities participate more actively in society.

Also, an accessible web is often one of the easiest ways to do business with many people with disabilities, for instance, people who can not read print material, people who have difficulty going to physical stores or malls, and others. Furthermore, what you do for accessibility overlaps with other best practices such as mobile web design, usability, and search engine optimization (SEO).

An accessible website provides many people with disabilities with access to information and interaction. The accessibility barriers to print, audio, and visual media can be much more easily overcome through Web technologies.

I suggest reading “Social Factors in Developing a Web Accessibility Business Case for Your Organization” which shows how the web impacts the lives of people with disabilities and Web accessibility as an aspect of cooperate social responsibility.

Another important consideration for organizations is that Web accessibility is required by laws and policies in some cases. WAI Web Accessibility Policy Resources links to resources for addressing legal and policy factors within organizations, including a list of relevant laws and policies around the world.

Measure UI component’s accessibility

When editing your page’s UI component for accessibility, ask yourself:

  • Can you use your UI component with the keyboard only?
    Does the component manage to focus and avoid focus traps? Can it respond to the appropriate keyboard events?

  • Can you use your UI component with the screen reader?

    Have you provided text alternatives for any information present visually? Have you added semantic information using ARIA?

  • Can your UI component work without sound?

    Turn off your speakers and go through your use cases.

  • Can your UI component work without color?

    Ensure your UI component can be used by someone who can't see colors. A helpful tool for simulating color blindness is a Chrome extension called Colorblindly (Try all four forms of color blindness simulation available). You may also be interested in the Daltonize extension, which is similarly useful.

  • Can your UI component work with high-contrast mode enabled?

    All modern operating systems support a high contrast mode. High Contrast is a Chrome extension that can help here.

Standardized controls (such as <button> and <select>) have accessibility built into the browser. They are focusable using the Tab key; they respond to keyboard events (like the Enter, Space, and arrow keys); and they have semantic roles, states, and properties used by accessibility tools. Their default styling should also meet the accessibility requirements listed.

Custom UI components (with the exception of components that extend standard elements like <button>) don’t have any built-in capabilities, including accessibility, so you need to provide it. A good place to start when implementing accessibility is to compare your component to an analogous standard element (or a combination of several standard elements, depending on how complex your component is).

Most browser developer tools support inspecting the accessibility tree of a page. In Chrome DevTools, this is available in the Accessibility tab in the Element panels.

Firefox also has an Accessibility panel.

Safari exposes accessibility information in the Elements panel’s Node tab.

The following is a list of questions you can ask yourself when attempting to make your UI component more accessible.

How to Make the Web Accessible

Making the web accessible depends on the developers building for the web. Making your website accessible to people with disabilities, will end up making it accessible to everyone.

Use tabindex

You can add keyboard focus for elements and UI components with the tabindex attribute. Keyboard-only and assistive technology users need to be able to place keyboard focus on elements to interact with them.

Built-in interactive elements (like <Button/>) are implicitly focusable, so they don’t need a tabindex, attribute unless you need to change their position in the tab order.

There are 3 types of tabindex values:

  • tabindex="0" is the most common and places elements in the natural tab order (defined by the DOM order)

  • A tabindex value equal to -1 causes the element to be programmatically focusable, but not in the tab order.

  • A tabindex value greater than 0 places the element in the manual tab order. All elements in the page with the positive tabindex value are visited in numerical order, before elements in the natural tab order.

Warning: As a general rule, avoid positive tabindexes. Disrupting the normal focus order may confuse and frustrate your users. It’s therefore likely to cause the failure of Success Criterion 2.4.3.

Find some use cases for tabindex in this article Using tabindex.

Ensure that focus is always visible, whether by using the default focus ring style or by applying a discernible custom focus style. Remember not to trap keyboard users - they should be able to move focus away from an element using only the keyboard.

Use autofocus

The HTML autofocus attribute lets an author specify that a particular element should automatically take focus when the page is loaded. autofocus is already supported on all web form controls, including buttons. To autofocus elements in your own custom UI components, call the focus() method, supported on all HTML elements that can be focused (for example, document.querySelector('myButton').focus()).

Add keyboard interaction

Once your UI component is focusable, provide a good keyboard interaction story when a component is focused by handling appropriate keyboard events. For example, allow the user to use arrow keys to select menu options and Space or Enter to activate buttons. The ARIA design pattern guide provides some guidance here.

Finally, ensure that your keyboard shortcuts are discoverable. A common practice is to have a keyboard shortcut legend (on-screen text) to inform the user that shortcuts exist. For example, "Press ? for keyboard shortcuts.". Alternatively, a hint such as a tooltip can be used to inform a user about the shortcut.

The performance of managing shortcuts can not be overstated. An important example is a navigation drawer. If you add a UI component to a page, you need to direct focus to the element inside it; otherwise, the user may have to tab the entire page to get there. This can be a frustrating experience, so be sure to test focus for all keyboard navigable components on your page.

💡
Tip: You can use the Puppeteer to automate running keyboard accessibility tests for toggling UI states. WalkMe Engineering has a great guide on this I recommend reading.

// Example for expanding and collapsing a category with the Space key
const category = await page.$(`.category`);

// verify tabIndex, role and focus
expect(await page.evaluate(elem => elem.getAttribute(`role`), category)).toEqual(`button`);
expect(await page.evaluate(elem => elem.getAttribute(`tabindex`), category)).toEqual(`0`);
expect(await page.evaluate(elem => window.document.activeElement === elem, category)).toEqual(true);

// verify aria-expanded = false
expect(await page.evaluate(elem => elem.getAttribute(`aria-expanded`), category)).toEqual(`false`);

// toggle category by pressing Space
await page.keyboard.press('Space');

// verify aria-expanded = true
expect(await page.evaluate(elem => elem.getAttribute(`aria-expanded`), category)).toEqual(`true`);

Mind the HTML semantic

The Browser derives the DOM Tree to create the Accessibility Tree. This is possible because the DOM Tree has some semantic meaning implicit in HTML. This means that by correctly using HTML semantics, we will have a more accessible site.

Let’s see some important things that have into consideration:

Embrace the element’s nature:

You’ve likely seen a pseudo-button or pseudo-link before. These are elements that try to replicate the functionality of a button or anchor, on other elements. A div with an onclick, for example. This is almost never a good idea. The effort required to make these accessible far out-weighs whatever reason you have for implementing them. Let’s take a quick look at the features built into the <button> element.

  • Focusable: A button can be focused by tabbing

  • Keyboard interactions: Pressing enter or space while focused will activate the button

  • Screen readers announce the element as a button

  • Additional attributes such as: autofocus, disabled, type, and many others.

💡
Why are devs drawn to this anti-pattern? The most common reason I’ve seen is that it’s an easy way to remove all browser styles from the button. Today, there is an easier solution to that problem: Simply add the unset style to your button’s css: button { all: unset }

We should not abuse the div element. Instead, we can use elements like nav, footer, article, section, address, aside elements. They will provide some crucial implicit content to the user’s device.

Non-text contents

For those elements that don’t result in text content, it is hard for the browser to reason about.

For input elements, there is a simple semantic solution: use the label element. We have two ways to use it:

  • 1. Explicit (recommended): by using the label element with the for attribute

  • 2. Implicit: by wrapping the input in a label element

<!-- Wrapping element in Label -->
<label>
  <input type="checkbox">Terms and Conditions
</label>

<!-- Using the 'for' attribute  -->
<input id="terms" type="checkbox">
<label for="terms">Terms and Conditions</label>

There are a couple of things to have in mind. The input label should be visible. Otherwise, screen readers won’t voice it. Interactive elements such as links are discouraged from any label. They might lead to accidental clicks or simply fail to be voiced properly.


<!-- ❌ Avoid -->
<input type="checkbox" id="terms" name="terms" />
<label for="terms">I accept the <a href="...">Terms and Conditions</a></label>

<!-- ✅ Recommended -->
<input type="checkbox" id="terms" name="terms" />
<label for="terms">I accept the Terms and Conditions.</label>
<span><a href="...">Available here</a></span>

Correct usage of Headings

There are six levels of section headings in HTML <h1> to <h6>. They are relevant to both users and search engines. A proper structure will help better orientate the users and rank you site properly.

This is a list of things to have in mind:

  • There should be only one h1 in your site at all times. It is meant to be the headline of your page. It should contain a relevant description of the content.

  • Avoid using those elements to resize text. In that scenario font-size should be used.

  • Avoid skipping heading levels. Start from h1 all the way down to h6.

Give links the proper name

  • The link must be recognizable. They should be either underlined or bold when resizing within a block of text (don’t just rely on color to denote it’s a link).

  • Ensure the link text makes sense on its own or give it a custom label (see below). Avoid “click here“ in the link text. Other ambiguous links, such as “more“ or “continue“ can be confusing.

  • Any links that open in a new tab or window should give screen reader users advance warning by setting the aria-label attribute on the anchor link(see below).

  • Links that point to the PDF document should open in a new tab.

  • Here’s an example of a link that has a custom label and opens in a new window.

<a href=”#” target=”_blank” aria-label=”Download the 2022 report, opens in a new tab”>Download</a>

Rules of HTML display

  • If a piece of HTML content is set to display:none, this content will also be ignored by assistive technologies.

  • However, keep in mind that content that is set to opacity:0 or visibility: hidden will be reachable by assistive technologies.

Telephone numbers and email addresses should always be hyperlinked

Some screen readers do not enable these as clickable links as default, so this needs to be accounted for.

Audio and Video 101

Play controls (play, pause, volume, etc.) should always be available for screen readers and keyboards to interact it.

In addition, you should always provide captions for video and live audio and aim to make text transcripts available for all audio content.

Include alt text for images

We have seen earlier how input where challenging for screen screenreaders. The same is true for images. The screen reader needs an alternate way to understand the content of the image.

That is where the alt comes to play. It is a native HTML attribute that provides alternative information for the user when he can’t view the element. That might be because he is a screen reader or because the image failed to load. Even if crawlers can now “see“ the image, having an accurate description will help the SEO.

Some useful guidelines:

  • the text should describe the image if it contains information

  • if the image is a link, it should describe where it is going.

  • alt="" might be used in cosmetic decoration images that are not relevant to the user.

  • Purely decorative images also need the HTML role attribute set:

      role="presentation"
    
  • If the image is a headshot of a person and their name is already being displayed underneath or next to the photo, the alt should also be empty in this case. This will prevent assistive technologies from reading out the person’s name twice. For example, this would be the markup for the headshot with the person’s name under it.

      <img src=’/images/walter-white.jpg’ alt=”” role=”presentation”/> <h3>Walter White 👨🏻‍🔬 </h3>
    

Use ARIA attributes

The Accessible Rich Internet Application is a set of attributes that are designed to boost the accessibility of your page. When using the correct HTML semantics you get those for free. They should therefore only be used when the native HTML semantics require additional input.

Let’s see an obvious example:

// ❌ bad usage
<div role="checkbox”>...</div>
// ✅ recommended, `role=checkbox` is implicit
<input type=”checkbox” name="terms">

Let’s see a more complex example:


<!-- Manually building progress -->
<div
  id="task-completed"
  role="progressbar"
  aria-valuenow="55"
  aria-valuemin="0"
  aria-valuemax="100"
>
</div>

<!-- ✅ using dedicated element (preferred) -->
<progress id="task-completed" value="55" max="100">55 %</progress>

Let’s see another example. If we want to present some advisory information we can use the role="status". The screen reader will properly communicate the message to the user.

// ✅ Using status for success messages
<p role="status">Your changes were saved.</p>

How can we make sure that we are enforcing ARIA accessibility in your codebase? By using those tags to make queries and assertions in our e2e, component, and integration tests. The whole team would be more ARIA aware and we would have some semantic selectors.

Color Contrast

When building a site, it is important to maintain a good color contrast between the background and the foreground content. This will ensure that your content stays legible.

There are some ratios established by the WCAG. The success is measured by where your site lands.

  • Minimum Contrast (AA)

  • Enhanced Contrast (AAA)

  • Non-text Contrast (AA)

There are some tools like WebAim that can help achieve the desired output of success.

Always test your page by using your keyboard

  • You should be able to navigate through your page with the Tab key. Typically, the expected flow is left to right, top to bottom.

  • If the keyboard focus disappears and jumps out of order, this needs to be fixed and usually means something will not work as expected on the screen reader as well.

  • All clickable elements should fire when pressing Enter.

  • Links that contain a dropdown menu should open when pressing ENTER or SPACEBAR.

  • Links within a submenu/drop-down should be reachable via TAB or using the UP and DOWN ARROWS.

  • Checkboxes and radio buttons should be selectable with the SPACEBAR.

Account for the page zoom

  • You should able to zoom the browser view up to 200% without loss of content and functionality.

  • WCAG 2.1 requires content to be zoomable up to 400% without the need for vertically scrolling (except when necessary).

Include a visually hidden “Skip To Main Content“ link before the global navigation

  • This allows assistive technologies to bypass the global navigation and the site header and jump to the main content.

  • Typically, the link remains hidden, but it should become visible when it receives keyboard focus.

  • When clicked, this link should drop the user to an element on the page that holds the main content.

A word on icons

  • Most icons can be set to be ignored by the screen readers since they are purely decorative.

  • If you are using font icons and it acts as a link, there must be an associated text that describes the link.

  • Avoid using the <i> tag for displaying icons. Some screen readers will understand this to mean italics.

Be wary of hover-only content

  • Any content that can only be viewed by mouse hover will likely be ignored by assistive technologies or get cut off if a user has their screen magnified. The best practice is to use clicks to show or hide vital content.

  • If that is not possible, make sure the content that is displayed on hover should also be viewable on keyboard focus or when pressing ENTER depending on the behavior of the component.

Removing focus outline

It’s not uncommon to see an app where the focus outline has been removed. This is problematic as people with mobility problems will often use an app with keyboard interactions, and rely on the outline. While I agree, it doesn’t always look pretty, there are better solutions than removing it.

Better focus styles with box-shadow

If you want more control over the look of the focus outline, you can override the styles to use box-shadow. There is a caveat here though. When a Windows high-contrast theme is turned on the box-shadow wont be visible to the user. We can get the best of both worlds though by setting a box-shadow, and outline-color: transparent

Better UX with focus-visible

If you’re like me, you really don’t like when you click a button and it shows the focus styles. This can be prevented by using :focus-visible. This allows the focus styles to appear only when the element has been tabbed to.

Pay close attention to form controls

  • Ensure form controls have descriptive labels and introductions regardless if the label is visible on the page or not.

  • Relying on the input placeholder’s text to act as the label is bad practice.

  • Keep form error messages close to the corresponding user input. Always provide text so the screen reader can read the errors.

Leverage screen reader only content when applicable

When the standard HTML content is too complex for a screen reader to understand, such as for charts, graphs, infographics, etc., your best option is to create a screen reader only content. This involves:

  • Creating a separate version of this content using simple text that typical users will not see on the page but will be available for assistive technologies.

  • In other words, you will have two versions of the same content: one for the browser and one for the screen reader. The screen version should be placed right before and after the browser content.

  • Many frontend frameworks such as Bootstrap offer a special CSS class that you can apply to your screen reader only content. (class=”sr-only”)

  • The standard browser content that visually appear on the page needs to be hidden from the screen reader so it doesn't read duplicate information. This can be done by applying the area-hidden attribute to this element and setting this to true (aria-hidden=”true”)

Rules for models and all dialog boxes

  • Keyboard focus should be trapped inside the modal window when it is opened and visible on the screen. Meaning, that only the items inside the modal should be focusable. Other page elements should be inaccessible by a keyboard and screen reader.

  • The ESC button should always allow the user to close the modal.

  • There should always be an obvious way for the user to exit the modal via a button.

  • The wrapping <div> element for the modal should utilize the following attributes:

<div tabindex=”-1" role=”dialog” aria-label=”Contact Us Dialog”>
  • tabindex: indicates if an element can receive user focus. It should be set to –1 when the modal is hidden and then switched to 0 with JavaScript when the modal is present on the screen. Many UI frameworks handle this behavior behind the scenes.

  • role=”dialog”: tells screen readers and other tools that this element should behave like a dialog.

  • aria-label: defines an accessible label for interactive elements to be read out by screen readers. You can also use aria-labelled by: which accepts the id of an HTML element that holds the text you want to use as the label.

Rules for carousels and sliders

  • There should always be next and previous controls.

  • There should always be a clear way for the user to stop or pause the carousel/slider. This can be done by adding both a stop/pause button and a play button.

  • When the carousel/slider moves from one slide to the next, a screen reader should read out what slide it is currently on. For example “Slide 2 of 4“.

  • If the carousel or slider is displaying text on any of the slides, this text needs to be read out by the screen reader as the slider moves from slide to slide. This can only be done with JavaScript and some custom HTML aria-attributes. Follow this example to see how you can implement this.

  • As always, ensure your carousel can be operated with a keyboard.

Accessibility tools and testing

There are over 100 tools available to evaluate the accessibility of your site and its components. Some tools are automated while others require manual testing.

Here are a few for your consideration:

  • Axe provides automated accessibility testing for your framework or browser of choice. Axe Puppeteer can be used for writing automated accessibility tests.

  • A Lighthouse Accessibility audit provides helpful insights for discovering common accessibility issues. The accessibility score is a weighted average of all accessibility audits based on Axe user impact assessments. For monitoring accessibility with continuous integration, see Lighthouse CI.

  • Tenon.io is useful for testing common accessibility problems. Tenon has strong integration support across build tools, browsers (through extensions), and even text editors.

  • There are many library- and framework-specific tools for highlighting accessibility issues with components. For example, use eslint-plugin-jsx-a11y to highlight accessibility issues for React components in your editor.

    If you use Angular, codelyzer provides in-editor accessibility audits too:

Work with assistive technologies

  • You can examine the way that assistive technologies see web content by using Accessibility Inspector (Mac) or Windows Automation API Testing Tools and AccProbe (Windows). You can also see the full accessibility tree that Chrome creates by navigating to about://accessibility.

  • The best way to test for screen reader support on a Mac is by using the VoiceOver utility. Use ⌘F5 to enable or disable it, Ctrl+Option ←→ to move through the page, and Ctrl+Shift+Option + ↑↓ to move up and down the accessibility tree. For more detailed instructions, see the full list of VoiceOver commands and the list of VoiceOver Web commands.

  • On Windows, NVDA is a free, open-source screen reader. However, it has a steep learning curve for sighted users.

  • ChromeOS has a built-in screenreader.

We have a long way to go to improve accessibility on the web. Per the Web Almanac:

  • 4 out of every 5 sites have text that blends into the background, making them unreadable.

  • 49.91% of pages still fail to provide alt attributes for some of their images.

  • Only 24% of pages that use buttons or links include labels.

  • Only 22.33% of pages provide labels for all their form inputs.

References

https://blog.openreplay.com/seo-basics-for-web-developers/?ref=dailydev

https://dev.to/acidop/12-easy-seo-tips-every-developer-should-know-52k3?context=digest

https://dev.to/thesohailjafri/the-must-have-seo-checklist-for-developers-192i?ref=dailydev

https://www.freecodecamp.org/news/tips-to-boost-your-seo/

https://www.freecodecamp.org/news/how-to-make-a-website-seo-friendly/

https://www.freecodecamp.org/news/nextjs-seo/

https://medium.com/@sassenthusiast/next-js-seo-best-practices-for-higher-rankings-f315c5c2db32

https://blog.stackademic.com/boosting-seo-in-next-js-essential-steps-for-effective-meta-tag-integration-b42690f1bc02

https://medium.com/better-programming/5-web-accessibility-tips-e2ba0d3726e5

https://web.dev/articles/a11y-tips-for-web-dev#improve_keyboard_focus

https://uxplanet.org/30-must-know-best-practices-for-web-accessibility-df1b3258ebdc

https://medium.com/fbdevclagos/why-web-accessibility-is-important-and-how-you-can-accomplish-it-4f59fda7859c

0
Subscribe to my newsletter

Read articles from Tuan Tran Van directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Tuan Tran Van
Tuan Tran Van

I am a developer creating open-source projects and writing about web development, side projects, and productivity.