SEO Helpers

Rhapsody provides a set of tools to help you optimise your application for search engines and social media sharing.

Dynamic Meta Tags

You can provide a unique title and meta description for any page by passing a third argument to the view() helper in your controller. The framework will automatically use this data to generate <title>, <meta name="description">, and Open Graph tags.

// In a controller
public function viewUser(Request $request, string $user_id)
{
    $user = $this->userModel->findById($user_id);

    $meta = [
        'title' => $user['name'] . ' - Profile | Rhapsody',
        'description' => 'View the profile for ' . $user['name'] . '.'
    ];

    return $this->view('users/user.twig', ['user' => $user], $meta);
}

Canonical URLs

The main layout automatically generates a <link rel="canonical"> tag for every page. This tells search engines the preferred URL for your content, preventing duplicate content issues. The generation is handled by the Request::getCanonicalUrl() method, which you can customise by passing allowed query parameters.

Make sure the APP_URL variable is set correctly in your .env file.

Structured Data with Schema.org

The Rhapsody\Core\SEO\SchemaOrg class allows you to add JSON‑LD structured data to your pages. This helps search engines understand your content and can improve your appearance in rich results.

Basic Usage

In your controller, create an instance of SchemaOrg, add schemas with the add() method, and then render them.

use Rhapsody\Core\SEO\SchemaOrg;

$schema = new SchemaOrg();
$schema->add('Article', [
    'headline'      => 'My Great Article',
    'author'        => ['@type' => 'Person', 'name' => 'John Doe'],
    'datePublished' => '2025-01-01',
    'image'         => 'https://example.com/image.jpg',
]);

// Pass the rendered markup to the view
$args['schema_markup'] = $schema->render();

If you are extending BaseController, the $this->schema property is already available, and the view() method will automatically inject the rendered schemas into the template as schema_markup.

// Inside a controller that extends BaseController
$this->schema->add('Product', [
    'name'        => 'Awesome Widget',
    'description' => 'The best widget ever.',
    'sku'         => 'ABC123',
    'offers'      => [
        '@type'         => 'Offer',
        'price'         => '19.99',
        'priceCurrency' => 'USD',
    ],
]);

return $this->view('product.twig', ['product' => $product]);

Creating URL Slugs with Sluggify

The Rhapsody\Core\SEO\Sluggify class provides a static method transform() that converts any string into a clean, SEO‑friendly URL slug. It handles accents, special characters, ampersands, and more.

Example

use Rhapsody\Core\SEO\Sluggify;

$title = "1 & 2 Samuel: King David's Reign!";
$slug = Sluggify::transform($title);
// Result: '1-2-samuel-king-davids-reign'

The transformation steps are:

  • Replace & with and
  • Replace non‑letter/digit characters with a single dash
  • Transliterate accents to ASCII
  • Remove any remaining unwanted characters
  • Trim and collapse multiple dashes
  • Convert to lowercase

If the result would be empty, it returns 'n-a' (not available).

Use this helper when generating slugs (or full href links) for blog posts, categories, or any dynamic content:

$post = new Post();
$post->title = $request->post('title');
$post->slug = Sluggify::transform($post->title);
$post->save();

Sitemap

The framework can automatically generate a sitemap.xml file for you. Simply navigate to /sitemap.xml. This file lists all your public pages, making it easy for search engines like Google to discover and index your entire site. You can customize which pages are included by editing app/Controllers/SitemapController.php.

robots.txt

A basic robots.txt file is included in the project root. You can edit this file to provide instructions to search engine crawlers, such as which pages or directories to disallow.