SEO Tools

RockFrontend comes with tools that help you build SEO optimized websites in no time.

sitemap.xml

RockFrontend introduces a streamlined way to generate sitemap.xml files for your website, enhancing your SEO capabilities with minimal effort. The sitemap() method simplifies the creation and maintenance of sitemaps, ensuring your site's pages are easily discoverable by search engines.

Quick Start

To generate a sitemap, simply call the sitemap() method in your /site/ready.php file:

rockfrontend()->sitemap();

This will do the following:

  • It will create the file /sitemap.xml on demand when it is requested
  • It will automatically delete this file on Pages::saved and on Modules::refresh
  • It will create the following markup for every viewable page in your tree (including hidden ones!):
<url>
<loc>https://example.com/foo/bar/</loc>
<lastmod>2024-03-18</lastmod>
</url>

Customisation

If you want, you can totally customise the markup of every page's entry by providing a callback to the sitemap() method. This is the default callback that is used by RockFrontend if no callback is provided:

rockfrontend()->sitemap(function (Page $page) {
  $modified = date("Y-m-d", $page->modified);
  return "<url>\n"
    . "<loc>{$page->httpUrl()}</loc>\n"
    . "<lastmod>$modified</lastmod>\n"
    . "</url>";
});

Debugging

You can use TracyDebugger to efficiently debug your sitemap while developing:

// in /site/ready.php
bd(rockfrontend()->sitemapMarkup());

Excluding pages from the sitemap

By default, all hidden pages will be included in the sitemap generated by RockFrontend. However, there might be instances where you want to exclude specific pages or even an entire branch of your page tree from appearing in the sitemap. This can be easily achieved by customizing the callback function provided to the sitemap() method:

rockfrontend()->sitemap(function (Page $page) {
  if($page->name === 'foo') {
    // this will exclude the whole /foo branch from the sitemap
    return false;
  }

  if($page->name === 'bar') {
    // this will skip page /bar
    // but it will still process /bar/one, /bar/two, etc
    return;
  }

  // all other pages
  // returning the page object results in the default markup:
  // <url><loc>...</loc><lastmod>...</lastmod></url>
  return $page;
});

If you are a module developer and want to make sure that your data pages do not appear in RockFrontend's sitemap you can set the noSitemap property of your page and RockFrontend will automatically exclude it.

Example of RockCommerce RootPage:

class RootPage extends Page
{
  public $noSitemap = true;
}

Adding pages to the sitemap

Sometimes you have endpoints that are not represented by pages in the pagetree (these docs are an example as they are rendered from markdown files rather than from ProcessWire pages).

rockfrontend()->sitemap(function ($page) {
  if ($page->template == 'module') {
    $modified = date("Y-m-d", $page->modified);
    $page->sitemapAppendMarkup =
      "<url>\n"
      . "<loc>{$page->httpUrl()}docs/</loc>\n"
      . "<lastmod>{$modified}</lastmod>\n"
      . "</url>\n";
  }
  return $page;
});
RockFrontend - SEO Tools

How does it work?

RockFrontend adds an url hook to /sitemap.xml that creates the sitemap on demand. The great thing is that if the sitemap has been already created the url hook will not trigger and your server will render the static file instead! RockFrontend will simply delete that file whenever a page is saved or modules are refreshed.

That means that on large sites the first request of /sitemap.xml after a page save could potentially take some time. The method is built in a way that it is as efficiently as possible, meaning that if you return false for a page in the tree the whole branch will neither be processed nor loaded into memory. Though all other pages will be processed and loaded into memory, so on very large websites you'd have to take care of that issue yourself.

Just check the logs for RockFrontend - there you will see something like this and you'll get an idea if you have to do something or its fast enough for your use case:

Sitemap showing 958 pages generated in 272 ms

SEO Markup Tags

The Concept of RockFrontend's SEO tools differ from many other solutions where you add many fields to every template and then have the user fill all these fields.

This might be the best solution in terms of search engine rankings but it is not the best solution in terms of efficiency in my opinion. In all websites that I develop I usually have the content for those SEO fields already available in one field or another.

So what RockFrontend's SEO Tools do is to make it super simple to grab the available content and turn it into state of the art SEO markup!

Note: In the future we might also add custom inputfields for the user to overwrite values generated by RockFrontend. What do you think? Let me know in the forum!

Usage

While you can customise every aspect of the output the main goal is that usage is still very simple. You can even use it without any customizations:

usage with default settings

<head>
<?php echo $rockfrontend->seo(); ?>
</head>

Just inspect the generated HTML markup and then further adjust settings to your needs. RockFrontend will take care of the tedious parts!

For example you can simply return a PageImage object in the og:image callback and RockFrontend will take care of creating the correct image size and return the correct url necessary for SEO tags including the host scheme.

Or you can just throw the content of a TinyMCE field into the description() function and RockFrontend will take care of removing all html tags and truncating the text to the desired length.

An example used for the page that you are currently viewing could look something like this:

/site/templates/_main.php

<head>
  ...
  <?php
  echo $rockfrontend->seo()

    ->title("RockFrontend - " . $page->title)

    ->description(function (Page $page) {
      if($page->template == 'docs') return $page->getDocs();
      return $page->body;
    })

    ->setValue('og:image', function (Page $page) {
      if($page->coverpic) return $page->coverpic;
      if($page->heroimage) return $page->heroimage;
      return $this->wire->pages->get(1)->defaultpic;
    });
  ?>
</head>

output

  <title>RockFrontend - SEO Tools</title>
  <meta property="og:title" content="RockFrontend - SEO Tools">
  <meta name="description" content="SEO Tools; RockFrontend comes with...">
  <meta property="og:description" content="SEO Tools; RockFrontend comes with...">
  <link rel='icon' type='image/png' sizes='32x32' href=/site/assets/files/1/favicon.32x32.png>
  <link rel='icon' type='image/png' sizes='16x16' href=/site/assets/files/1/favicon.16x16.png>
  <link rel='icon' type='image/png' sizes='48x48' href=/site/assets/files/1/favicon.48x48.png>
  <link rel='icon' type='image/png' sizes='192x192' href=/site/assets/files/1/favicon.192x192.png>
  <link rel='apple-touch-icon' type='image/png' sizes='167x167' href=/site/assets/files/1/favicon.167x167.png>
  <link rel='apple-touch-icon' type='image/png' sizes='180x180' href=/site/assets/files/1/favicon.180x180.png>
  <link rel="manifest" href="/website.webmanifest">

Most values can either be set as string (for simple situations like the title in the example above) or as a callback that receives the current $page as first argument (like in the description in the example above).

Default Configuration

If you don't want to use the default configuration, all tags are fully configurable. The default configuration can be inspected by dumping the RockFrontend Seo object:

bd($rockfrontend->seo());
Default SEO Configuration
Default SEO Configuration

The recommendations are mostly inspired from https://moz.com/learn/seo.

You can manipulate tags via setMarkup() and setValue():

setMarkup()

Let's say we wanted to add a new foo tag to our SEO tools:

$rockfrontend->seo()
  ->setMarkup("foo", "<meta property='foo' content='{value:20}'>");

setValue()

Now we can set a new value for the foo tag based on the page's title:

string

$rockfrontend->seo()
  ->setValue($page->title);

Note that as we defined {value:20} in the tag's markup the page title will be truncated to 20 characters!

Page Title

The page title can either be set as a string or as a callback:

string

$rockfrontend->seo()->title($page->title);

callback

$rockfrontend->seo()
  ->title(function ($page) {
    if ($page->headline) return "{$page->title} - {$page->headline}";
    return $page->title;
  });

This will not only set the <title> tag but also the og:title tag:

output

<title>RockFrontend - SEO Tools</title>
<meta property="og:title" content="RockFrontend - SEO Tools">

Page Description

The same concept applies to the page description tag:

string

$rockfrontend->seo()->description($page->body);

callback

$rockfrontend->seo()
  ->description(function ($page) {
    if ($page->template == 'car') return $page->cardescription;
    return $page->body;
  });

output

<meta name="description" content="Your Page Description">
<meta property="og:description" content="Your Page Description">

Favicon and OG Image

Good buy favicon generators, hello RockFrontend! 😎

RockFrontend can create a favicon and an og:image field for you if you have the RockMigrations module installed:

RockFrontend SEO Fields
RockFrontend SEO Fields

These fields will be added to the home template and if populated those files will be used in your SEO markup! The favicon must be PNG so that ProcessWire can create all the necessary icon size variations for you. SVG is not supported here. If you want to use an svg favicon simply add that tag manually to your markup.

An example output could look like this:

<link rel='icon' type='image/png' sizes='32x32' href=/site/assets/files/1/favicon.32x32.png>
<link rel='icon' type='image/png' sizes='16x16' href=/site/assets/files/1/favicon.16x16.png>
<link rel='icon' type='image/png' sizes='48x48' href=/site/assets/files/1/favicon.48x48.png>
<link rel='icon' type='image/png' sizes='192x192' href=/site/assets/files/1/favicon.192x192.png>
<link rel='apple-touch-icon' type='image/png' sizes='167x167' href=/site/assets/files/1/favicon.167x167.png>
<link rel='apple-touch-icon' type='image/png' sizes='180x180' href=/site/assets/files/1/favicon.180x180.png>

<meta property="og:image" content="https://www.example.com/site/assets/files/1/pexels-arnaud-vigne-13321059.1200x630.jpg">
<meta property="og:image:type" content="image/jpeg">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:image:alt" content="RockFrontend - SEO Tools">

All these tags are generated automatically! Note that the favicon urls are relative /site/assets/... whereas the og:image path is absolute https://www....

But you don't need to know all that. RockFrontend does it for you! 🚀

Website Manifest File

You can create your website's manifest file from the RockFrontend module config. RockFrontend will then add that manifest file to your site's <head> section which will make the website appear in your selected color theme:

Manifest File Preview
Manifest File Preview
Manifest File Settings
Manifest File Settings