SEO Top Codes

SEO Meta Tags HTML Template

Copy this template to the head of your pages and change the values. Each tag has a short comment which tells its job.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">

  <!-- Makes the page responsive on mobile -->
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <!-- Title: unique, about 50 to 60 characters -->
  <title>SEO Title Tag: How to Write a Good Title</title>

  <!-- Description: unique, about 120 to 155 characters -->
  <meta name="description" content="Learn how to write an SEO title tag with the right length and keyword, with simple examples.">

  <!-- Preferred URL of this page -->
  <link rel="canonical" href="https://example.com/seo-title-tag/">

  <!-- Indexing rules (this is the default, so you may skip it) -->
  <meta name="robots" content="index, follow">

  <!-- Language versions (only for multilingual sites) -->
  <link rel="alternate" hreflang="en" href="https://example.com/seo-title-tag/">
  <link rel="alternate" hreflang="x-default" href="https://example.com/seo-title-tag/">

  <!-- Open Graph: how the page looks when shared on social media -->
  <meta property="og:type" content="article">
  <meta property="og:title" content="SEO Title Tag: How to Write a Good Title">
  <meta property="og:description" content="Learn how to write an SEO title tag with the right length and keyword.">
  <meta property="og:url" content="https://example.com/seo-title-tag/">
  <meta property="og:image" content="https://example.com/images/title-tag-share.jpg">
  <meta name="twitter:card" content="summary_large_image">
</head>
<body>
  <h1>SEO Title Tag</h1>
</body>
</html>

How it works

  • The viewport tag is needed for a mobile friendly page.
  • The title and description are the main text of the search result. See Title Tag and Meta Description.
  • The canonical link tells the preferred URL. See Canonical URLs.
  • The Open Graph tags control the title, text and picture when a link is shared on social platforms. They do not change the Google ranking.
  • Use the noindex value in the robots tag only for pages which must stay out of search, like thank you pages.
Note: The meta keywords tag is not in the template, because Google ignores it.

Robots.txt Template for WordPress

This robots.txt keeps crawlers out of the admin area and the internal search pages, but allows the one admin file that many themes and plugins need on the front end.

User-agent: *
Disallow: /wp-admin/
Allow: /wp-admin/admin-ajax.php
Disallow: /?s=
Disallow: /search/

Sitemap: https://example.com/wp-sitemap.xml

Here is the test of some paths for Googlebot:

Test result of the rules above

Googlebot /wp-admin/options.php Blocked
Googlebot /wp-admin/admin-ajax.php Allowed
Googlebot /?s=seo Blocked
Googlebot /search/seo/ Blocked
Googlebot /wp-content/uploads/2026/05/photo.jpg Allowed
Googlebot /blog/seo-guide/ Allowed

How it works

  • Disallow: /wp-admin/ blocks the admin folder, and the longer Allow rule makes an exception for admin-ajax.php.
  • /?s= and /search/ are the internal search result pages. They give no value in Google and waste crawling.
  • The images in /wp-content/uploads/ stay open, so Google can use them in image search.
  • Change the sitemap address to your own. If you use Yoast SEO or Rank Math, it is usually /sitemap_index.xml.
Note: Do not block /wp-content/ or /wp-includes/. Google needs the CSS and JavaScript from there to render your pages. See Robots.txt.

.htaccess Rules for HTTPS and www Redirect

Search engines see http://example.com, https://example.com, http://www.example.com and https://www.example.com as four addresses. These rules send all of them to one version: https://www.example.com. Change the domain to yours.

RewriteEngine On

# 1. Redirect http to https
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]

# 2. Redirect non-www to www (https)
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]

Check the redirects

curl -I http://example.com/seo-title-tag/
curl -I https://example.com/seo-title-tag/

Both results should show 301 and a Location line with https://www.example.com/seo-title-tag/. If you see a chain of many redirects, simplify the rules.

How it works

  • RewriteCond %{HTTPS} off runs the rule only when the request is not secure.
  • [L,R=301] means last rule and a permanent redirect.
  • !^www\. matches a host name which does not start with www.
  • Both rules send the visitor to the final address directly, so there is no redirect chain.
  • The code works on Apache with mod_rewrite. This server file was not run here, so test it on your own server first, and keep a backup of your old .htaccess.
Note: If your site is behind a proxy or a CDN, the https check may need %{HTTP:X-Forwarded-Proto}, and many hosts offer a setting for the https redirect. See Redirection.

Python Script to Generate sitemap.xml

This small script reads a list of URLs and writes an XML sitemap. It uses only the standard library of Python.

from datetime import date
from xml.sax.saxutils import escape

def build_sitemap(urls, lastmod):
    lines = ['<?xml version="1.0" encoding="UTF-8"?>',
             '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">']
    for url in urls:
        lines.append("  <url>")
        lines.append("    <loc>" + escape(url) + "</loc>")
        lines.append("    <lastmod>" + lastmod + "</lastmod>")
        lines.append("  </url>")
    lines.append("</urlset>")
    return "\n".join(lines)

with open("urls.txt") as f:
    urls = [line.strip() for line in f if line.strip()]

xml = build_sitemap(urls, date(2026, 9, 1).isoformat())

with open("sitemap.xml", "w", encoding="utf-8") as f:
    f.write(xml + "\n")

print(len(urls), "URLs written to sitemap.xml")
Output

$ python3 make_sitemap.py
4 URLs written to sitemap.xml
$ cat sitemap.xml
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://example.com/</loc>
<lastmod>2026-09-01</lastmod>
</url>
<url>
<loc>https://example.com/seo-introduction/</loc>
<lastmod>2026-09-01</lastmod>
</url>
<url>
<loc>https://example.com/seo-title-tag/</loc>
<lastmod>2026-09-01</lastmod>
</url>
<url>
<loc>https://example.com/seo-robots-txt/</loc>
<lastmod>2026-09-01</lastmod>
</url>
</urlset>
$ xmllint –noout sitemap.xml && echo "sitemap.xml is valid XML"
sitemap.xml is valid XML

How it works

  • The script reads one URL per line from urls.txt.
  • escape() changes the special characters like & in URLs, so the XML stays valid.
  • It writes a loc and a lastmod for each page. Use the real date of the last change for each page, not always today.
  • xmllint is a tool to check that the XML is well formed.
Note: A sitemap file can have at most 50,000 URLs and 50 MB. For more URLs, make many files and a sitemap index. See XML Sitemap.

Python Script to Check Title and Meta Description Length

This script checks the basic on-page tags of HTML files: the title length, the meta description length and the number of H1 headings. It uses only the standard library, so you can run it on any computer with Python.

import sys
from html.parser import HTMLParser

class SeoParser(HTMLParser):
    def __init__(self):
        super().__init__()
        self.in_title = False
        self.title = ""
        self.description = ""
        self.h1_count = 0

    def handle_starttag(self, tag, attrs):
        attrs = dict(attrs)
        if tag == "title":
            self.in_title = True
        elif tag == "meta" and attrs.get("name") == "description":
            self.description = attrs.get("content", "")
        elif tag == "h1":
            self.h1_count += 1

    def handle_endtag(self, tag):
        if tag == "title":
            self.in_title = False

    def handle_data(self, data):
        if self.in_title:
            self.title += data

def check(path):
    parser = SeoParser()
    with open(path, encoding="utf-8") as f:
        parser.feed(f.read())

    print(path)
    print("  Title (%d chars): %s" % (len(parser.title), parser.title))
    print("  Description (%d chars)" % len(parser.description))
    print("  H1 tags: %d" % parser.h1_count)

    if not 30 <= len(parser.title) <= 60:
        print("  WARNING: title should be about 30 to 60 characters")
    if not 70 <= len(parser.description) <= 155:
        print("  WARNING: description should be about 70 to 155 characters")
    if parser.h1_count != 1:
        print("  WARNING: page should have exactly one H1")

for path in sys.argv[1:]:
    check(path)
Output

$ python3 check_seo.py page1.html page2.html
page1.html
Title (40 chars): SEO Title Tag: How to Write a Good Title
Description (92 chars)
H1 tags: 1
page2.html
Title (4 chars): Home
Description (0 chars)
H1 tags: 2
WARNING: title should be about 30 to 60 characters
WARNING: description should be about 70 to 155 characters
WARNING: page should have exactly one H1

How it works

  • HTMLParser reads the HTML and calls a method for each start tag, end tag and text.
  • The class remembers the title text, the content of the description meta tag and counts the H1 tags.
  • The warnings use the common length guidelines. They are a guide, not a strict rule of Google.
  • The first page passes all checks. The second page has a short title, no description and two H1 tags, so the script shows three warnings.
Note: You can extend it to read many files in a folder, or to check canonical tags and image alt text. See Title Tag and Meta Description.

JSON-LD Article Schema Template

Add this JSON-LD in the head or body of an article page, and replace the example values with the real data of your page. Everything in the markup must match what is visible on the page.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Article",
  "mainEntityOfPage": {
    "@type": "WebPage",
    "@id": "https://example.com/seo-title-tag/"
  },
  "headline": "SEO Title Tag: How to Write a Good Title",
  "description": "Learn how to write an SEO title tag with the right length and keyword.",
  "image": [
    "https://example.com/images/title-tag-1x1.jpg",
    "https://example.com/images/title-tag-16x9.jpg"
  ],
  "datePublished": "2026-05-10T08:00:00+05:30",
  "dateModified": "2026-09-01T10:30:00+05:30",
  "author": {
    "@type": "Person",
    "name": "Robin Sharma",
    "url": "https://example.com/authors/robin-sharma/"
  },
  "publisher": {
    "@type": "Organization",
    "name": "Example Site",
    "logo": {
      "@type": "ImageObject",
      "url": "https://example.com/images/logo.png"
    }
  }
}
</script>

How it works

  • The JSON was parsed with a tool, so it has no syntax errors. Always check after you edit it, because one missing comma breaks the full block.
  • datePublished and dateModified use the ISO 8601 format with a time zone.
  • Use more than one image shape if you have them, and update dateModified only when the content really changes.
  • Test the final page with the Rich Results Test or the Schema Markup Validator.
Note: In WordPress, plugins like Yoast SEO and Rank Math add this markup for you. If you use a plugin, do not add a second copy by hand. See Structured Data.